diff options
Diffstat (limited to 'numpy/numarray')
26 files changed, 6844 insertions, 0 deletions
diff --git a/numpy/numarray/__init__.py b/numpy/numarray/__init__.py new file mode 100644 index 000000000..b0819d127 --- /dev/null +++ b/numpy/numarray/__init__.py @@ -0,0 +1,26 @@ +from util import * +from numerictypes import * +from functions import * +from ufuncs import * +from compat import * +from session import * + +import util +import numerictypes +import functions +import ufuncs +import compat +import session + +__all__ = ['session', 'numerictypes'] +__all__ += util.__all__ +__all__ += numerictypes.__all__ +__all__ += functions.__all__ +__all__ += ufuncs.__all__ +__all__ += compat.__all__ +__all__ += session.__all__ + +del util +del functions +del ufuncs +del compat diff --git a/numpy/numarray/_capi.c b/numpy/numarray/_capi.c new file mode 100644 index 000000000..0ba1be221 --- /dev/null +++ b/numpy/numarray/_capi.c @@ -0,0 +1,3337 @@ +#include <Python.h> + +#define _libnumarray_MODULE +#include "numpy/libnumarray.h" +#include <float.h> + +#if defined(__GLIBC__) || defined(__APPLE__) || defined(__MINGW32__) +#include <fenv.h> +#elif defined(__CYGWIN__) +#include "numpy/fenv/fenv.h" +#include "numpy/fenv/fenv.c" +#endif + +static PyObject *pCfuncClass; +static PyTypeObject CfuncType; +static PyObject *pHandleErrorFunc; + +static int +deferred_libnumarray_init(void) +{ + static int initialized=0; + + if (initialized) return 0; + + pCfuncClass = (PyObject *) &CfuncType; + Py_INCREF(pCfuncClass); + + pHandleErrorFunc = + NA_initModuleGlobal("numpy.numarray.util", "handleError"); + + if (!pHandleErrorFunc) goto _fail; + + + /* _exit: */ + initialized = 1; + return 0; + + _fail: + initialized = 0; + return -1; +} + + + +/**********************************************************************/ +/* Buffer Utility Functions */ +/**********************************************************************/ + +static PyObject * +getBuffer( PyObject *obj) +{ + if (!obj) return PyErr_Format(PyExc_RuntimeError, + "NULL object passed to getBuffer()"); + if (obj->ob_type->tp_as_buffer == NULL) { + return PyObject_CallMethod(obj, "__buffer__", NULL); + } else { + Py_INCREF(obj); /* Since CallMethod returns a new object when it + succeeds, We'll need to DECREF later to free it. + INCREF ordinary buffers here so we don't have to + remember where the buffer came from at DECREF time. + */ + return obj; + } +} + +/* Either it defines the buffer API, or it is an instance which returns +a buffer when obj.__buffer__() is called */ +static int +isBuffer (PyObject *obj) +{ + PyObject *buf = getBuffer(obj); + int ans = 0; + if (buf) { + ans = buf->ob_type->tp_as_buffer != NULL; + Py_DECREF(buf); + } else { + PyErr_Clear(); + } + return ans; +} + +/**********************************************************************/ + +static int +getWriteBufferDataPtr(PyObject *buffobj, void **buff) +{ + int rval = -1; + PyObject *buff2; + if ((buff2 = getBuffer(buffobj))) + { + if (buff2->ob_type->tp_as_buffer->bf_getwritebuffer) + rval = buff2->ob_type->tp_as_buffer->bf_getwritebuffer(buff2, + 0, buff); + Py_DECREF(buff2); + } + return rval; +} + +/**********************************************************************/ + +static int +isBufferWriteable (PyObject *buffobj) +{ + void *ptr; + int rval = -1; + rval = getWriteBufferDataPtr(buffobj, &ptr); + if (rval == -1) + PyErr_Clear(); /* Since we're just "testing", it's not really an error */ + return rval != -1; +} + +/**********************************************************************/ + +static int +getReadBufferDataPtr(PyObject *buffobj, void **buff) +{ + int rval = -1; + PyObject *buff2; + if ((buff2 = getBuffer(buffobj))) { + if (buff2->ob_type->tp_as_buffer->bf_getreadbuffer) + rval = buff2->ob_type->tp_as_buffer->bf_getreadbuffer(buff2, + 0, buff); + Py_DECREF(buff2); + } + return rval; +} + +/**********************************************************************/ + +static int +getBufferSize(PyObject *buffobj) +{ + Py_ssize_t size=0; + PyObject *buff2; + if ((buff2 = getBuffer(buffobj))) + { + (void) buff2->ob_type->tp_as_buffer->bf_getsegcount(buff2, &size); + Py_DECREF(buff2); + } + else + size = -1; + return size; +} + + +static double numarray_zero = 0.0; + +static double raiseDivByZero(void) +{ + return 1.0/numarray_zero; +} + +static double raiseNegDivByZero(void) +{ + return -1.0/numarray_zero; +} + +static double num_log(double x) +{ + if (x == 0.0) + return raiseNegDivByZero(); + else + return log(x); +} + +static double num_log10(double x) +{ + if (x == 0.0) + return raiseNegDivByZero(); + else + return log10(x); +} + +static double num_pow(double x, double y) +{ + int z = (int) y; + if ((x < 0.0) && (y != z)) + return raiseDivByZero(); + else + return pow(x, y); +} + +/* Inverse hyperbolic trig functions from Numeric */ +static double num_acosh(double x) +{ + return log(x + sqrt((x-1.0)*(x+1.0))); +} + +static double num_asinh(double xx) +{ + double x; + int sign; + if (xx < 0.0) { + sign = -1; + x = -xx; + } + else { + sign = 1; + x = xx; + } + return sign*log(x + sqrt(x*x+1.0)); +} + +static double num_atanh(double x) +{ + return 0.5*log((1.0+x)/(1.0-x)); +} + +/* NUM_CROUND (in numcomplex.h) also calls num_round */ +static double num_round(double x) +{ + return (x >= 0) ? floor(x+0.5) : ceil(x-0.5); +} + + +/* The following routine is used in the event of a detected integer * +** divide by zero so that a floating divide by zero is generated. * +** This is done since numarray uses the floating point exception * +** sticky bits to detect errors. The last bit is an attempt to * +** prevent optimization of the divide by zero away, the input value * +** should always be 0 * +*/ + +static int int_dividebyzero_error(long value, long unused) { + double dummy; + dummy = 1./numarray_zero; + if (dummy) /* to prevent optimizer from eliminating expression */ + return 0; + else + return 1; +} + +/* Likewise for Integer overflows */ +#if defined(__GLIBC__) || defined(__APPLE__) || defined(__CYGWIN__) || defined(__MINGW32__) +static int int_overflow_error(Float64 value) { /* For x86_64 */ + feraiseexcept(FE_OVERFLOW); + return (int) value; +} +#else +static int int_overflow_error(Float64 value) { + double dummy; + dummy = pow(1.e10, fabs(value/2)); + if (dummy) /* to prevent optimizer from eliminating expression */ + return (int) value; + else + return 1; +} +#endif + +static int umult64_overflow(UInt64 a, UInt64 b) +{ + UInt64 ah, al, bh, bl, w, x, y, z; + + ah = (a >> 32); + al = (a & 0xFFFFFFFFL); + bh = (b >> 32); + bl = (b & 0xFFFFFFFFL); + + /* 128-bit product: z*2**64 + (x+y)*2**32 + w */ + w = al*bl; + x = bh*al; + y = ah*bl; + z = ah*bh; + + /* *c = ((x + y)<<32) + w; */ + return z || (x>>32) || (y>>32) || + (((x & 0xFFFFFFFFL) + (y & 0xFFFFFFFFL) + (w >> 32)) >> 32); +} + +static int smult64_overflow(Int64 a0, Int64 b0) +{ + UInt64 a, b; + UInt64 ah, al, bh, bl, w, x, y, z; + + /* Convert to non-negative quantities */ + if (a0 < 0) { a = -a0; } else { a = a0; } + if (b0 < 0) { b = -b0; } else { b = b0; } + + ah = (a >> 32); + al = (a & 0xFFFFFFFFL); + bh = (b >> 32); + bl = (b & 0xFFFFFFFFL); + + w = al*bl; + x = bh*al; + y = ah*bl; + z = ah*bh; + + /* + UInt64 c = ((x + y)<<32) + w; + if ((a0 < 0) ^ (b0 < 0)) + *c = -c; + else + *c = c + */ + + return z || (x>>31) || (y>>31) || + (((x & 0xFFFFFFFFL) + (y & 0xFFFFFFFFL) + (w >> 32)) >> 31); +} + + +static void +NA_Done(void) +{ + return; +} + +static PyArrayObject * +NA_NewAll(int ndim, maybelong *shape, NumarrayType type, + void *buffer, maybelong byteoffset, maybelong bytestride, + int byteorder, int aligned, int writeable) +{ + PyArrayObject *result = NA_NewAllFromBuffer( + ndim, shape, type, Py_None, byteoffset, bytestride, + byteorder, aligned, writeable); + + if (result) { + if (!NA_NumArrayCheck((PyObject *) result)) { + PyErr_Format( PyExc_TypeError, + "NA_NewAll: non-NumArray result"); + result = NULL; + } else { + if (buffer) { + memcpy(result->data, buffer, NA_NBYTES(result)); + } else { + memset(result->data, 0, NA_NBYTES(result)); + } + } + } + return result; +} + +static PyArrayObject * +NA_NewAllStrides(int ndim, maybelong *shape, maybelong *strides, + NumarrayType type, void *buffer, maybelong byteoffset, + int byteorder, int aligned, int writeable) +{ + int i; + PyArrayObject *result = NA_NewAll(ndim, shape, type, buffer, + byteoffset, 0, + byteorder, aligned, writeable); + for(i=0; i<ndim; i++) + result->strides[i] = strides[i]; + return result; +} + + +static PyArrayObject * +NA_New(void *buffer, NumarrayType type, int ndim, ...) +{ + int i; + maybelong shape[MAXDIM]; + va_list ap; + va_start(ap, ndim); + for(i=0; i<ndim; i++) + shape[i] = va_arg(ap, int); + va_end(ap); + return NA_NewAll(ndim, shape, type, buffer, 0, 0, + NA_ByteOrder(), 1, 1); +} + +static PyArrayObject * +NA_Empty(int ndim, maybelong *shape, NumarrayType type) +{ + return NA_NewAll(ndim, shape, type, NULL, 0, 0, + NA_ByteOrder(), 1, 1); +} + + +/* Create a new numarray which is initially a C_array, or which +references a C_array: aligned, !byteswapped, contiguous, ... +Call with buffer==NULL to allocate storage. +*/ +static PyArrayObject * +NA_vNewArray(void *buffer, NumarrayType type, int ndim, maybelong *shape) +{ + return (PyArrayObject *) NA_NewAll(ndim, shape, type, buffer, 0, 0, + NA_ByteOrder(), 1, 1); +} + +static PyArrayObject * +NA_NewArray(void *buffer, NumarrayType type, int ndim, ...) +{ + int i; + maybelong shape[MAXDIM]; + va_list ap; + va_start(ap, ndim); + for(i=0; i<ndim; i++) + shape[i] = va_arg(ap, int); /* literals will still be ints */ + va_end(ap); + return NA_vNewArray(buffer, type, ndim, shape); +} + + +static PyObject* +NA_ReturnOutput(PyObject *out, PyArrayObject *shadow) +{ + if ((out == Py_None) || (out == NULL)) { + /* default behavior: return shadow array as the result */ + return (PyObject *) shadow; + } else { + PyObject *rval; + /* specified output behavior: return None */ + /* del(shadow) --> out.copyFrom(shadow) */ + Py_DECREF(shadow); + Py_INCREF(Py_None); + rval = Py_None; + return rval; + } +} + +static long NA_getBufferPtrAndSize(PyObject *buffobj, int readonly, void **ptr) +{ + long rval; + if (readonly) + rval = getReadBufferDataPtr(buffobj, ptr); + else + rval = getWriteBufferDataPtr(buffobj, ptr); + return rval; +} + + +static int NA_checkIo(char *name, + int wantIn, int wantOut, int gotIn, int gotOut) +{ + if (wantIn != gotIn) { + PyErr_Format(_Error, + "%s: wrong # of input buffers. Expected %d. Got %d.", + name, wantIn, gotIn); + return -1; + } + if (wantOut != gotOut) { + PyErr_Format(_Error, + "%s: wrong # of output buffers. Expected %d. Got %d.", + name, wantOut, gotOut); + return -1; + } + return 0; +} + +static int NA_checkOneCBuffer(char *name, long niter, + void *buffer, long bsize, size_t typesize) +{ + Int64 lniter = niter, ltypesize = typesize; + + if (lniter*ltypesize > bsize) { + PyErr_Format(_Error, + "%s: access out of buffer. niter=%d typesize=%d bsize=%d", + name, (int) niter, (int) typesize, (int) bsize); + return -1; + } + if ((typesize <= sizeof(Float64)) && (((long) buffer) % typesize)) { + PyErr_Format(_Error, + "%s: buffer not aligned on %d byte boundary.", + name, (int) typesize); + return -1; + } + return 0; +} + + +static int NA_checkNCBuffers(char *name, int N, long niter, + void **buffers, long *bsizes, + Int8 *typesizes, Int8 *iters) +{ + int i; + for (i=0; i<N; i++) + if (NA_checkOneCBuffer(name, iters[i] ? iters[i] : niter, + buffers[i], bsizes[i], typesizes[i])) + return -1; + return 0; +} + +static int NA_checkOneStriding(char *name, long dim, maybelong *shape, + long offset, maybelong *stride, long buffersize, long itemsize, + int align) +{ + int i; + long omin=offset, omax=offset; + long alignsize = (itemsize <= sizeof(Float64) ? itemsize : sizeof(Float64)); + + if (align && (offset % alignsize)) { + PyErr_Format(_Error, + "%s: buffer not aligned on %d byte boundary.", + name, (int) alignsize); + return -1; + } + for(i=0; i<dim; i++) { + long strideN = stride[i] * (shape[i]-1); + long tmax = omax + strideN; + long tmin = omin + strideN; + if (shape[i]-1 >= 0) { /* Skip dimension == 0. */ + omax = MAX(omax, tmax); + omin = MIN(omin, tmin); + if (align && (ABS(stride[i]) % alignsize)) { + PyErr_Format(_Error, + "%s: stride %d not aligned on %d byte boundary.", + name, (int) stride[i], (int) alignsize); + return -1; + } + if (omax + itemsize > buffersize) { + PyErr_Format(_Error, + "%s: access beyond buffer. offset=%d buffersize=%d", + name, (int) (omax+itemsize-1), (int) buffersize); + return -1; + } + if (omin < 0) { + PyErr_Format(_Error, + "%s: access before buffer. offset=%d buffersize=%d", + name, (int) omin, (int) buffersize); + return -1; + } + } + } + return 0; +} + +/* Function to call standard C Ufuncs +** +** The C Ufuncs expect contiguous 1-d data numarray, input and output numarray +** iterate with standard increments of one data element over all numarray. +** (There are some exceptions like arrayrangexxx which use one or more of +** the data numarray as parameter or other sources of information and do not +** iterate over every buffer). +** +** Arguments: +** +** Number of iterations (simple integer value). +** Number of input numarray. +** Number of output numarray. +** Tuple of tuples, one tuple per input/output array. Each of these +** tuples consists of a buffer object and a byte offset to start. +** +** Returns None +*/ + + +static PyObject * +NA_callCUFuncCore(PyObject *self, + long niter, long ninargs, long noutargs, + PyObject **BufferObj, long *offset) +{ + CfuncObject *me = (CfuncObject *) self; + char *buffers[MAXARGS]; + long bsizes[MAXARGS]; + long i, pnargs = ninargs + noutargs; + UFUNC ufuncptr; + + if (pnargs > MAXARGS) + return PyErr_Format(PyExc_RuntimeError, "NA_callCUFuncCore: too many parameters"); + + if (!PyObject_IsInstance(self, (PyObject *) &CfuncType) + || me->descr.type != CFUNC_UFUNC) + return PyErr_Format(PyExc_TypeError, + "NA_callCUFuncCore: problem with cfunc."); + + for (i=0; i<pnargs; i++) { + int readonly = (i < ninargs); + if (offset[i] < 0) + return PyErr_Format(_Error, + "%s: invalid negative offset:%d for buffer[%d]", + me->descr.name, (int) offset[i], (int) i); + if ((bsizes[i] = NA_getBufferPtrAndSize(BufferObj[i], readonly, + (void *) &buffers[i])) < 0) + return PyErr_Format(_Error, + "%s: Problem with %s buffer[%d].", + me->descr.name, + readonly ? "read" : "write", (int) i); + buffers[i] += offset[i]; + bsizes[i] -= offset[i]; /* "shorten" buffer size by offset. */ + } + + ufuncptr = (UFUNC) me->descr.fptr; + + /* If it's not a self-checking ufunc, check arg count match, + buffer size, and alignment for all buffers */ + if (!me->descr.chkself && + (NA_checkIo(me->descr.name, + me->descr.wantIn, me->descr.wantOut, ninargs, noutargs) || + NA_checkNCBuffers(me->descr.name, pnargs, + niter, (void **) buffers, bsizes, + me->descr.sizes, me->descr.iters))) + return NULL; + + /* Since the parameters are valid, call the C Ufunc */ + if (!(*ufuncptr)(niter, ninargs, noutargs, (void **)buffers, bsizes)) { + Py_INCREF(Py_None); + return Py_None; + } else { + return NULL; + } +} + +static PyObject * +callCUFunc(PyObject *self, PyObject *args) { + PyObject *DataArgs, *ArgTuple; + long pnargs, ninargs, noutargs, niter, i; + CfuncObject *me = (CfuncObject *) self; + PyObject *BufferObj[MAXARGS]; + long offset[MAXARGS]; + + if (!PyArg_ParseTuple(args, "lllO", + &niter, &ninargs, &noutargs, &DataArgs)) + return PyErr_Format(_Error, + "%s: Problem with argument list", me->descr.name); + + /* check consistency of stated inputs/outputs and supplied buffers */ + pnargs = PyObject_Length(DataArgs); + if ((pnargs != (ninargs+noutargs)) || (pnargs > MAXARGS)) + return PyErr_Format(_Error, + "%s: wrong buffer count for function", me->descr.name); + + /* Unpack buffers and offsets, get data pointers */ + for (i=0; i<pnargs; i++) { + ArgTuple = PySequence_GetItem(DataArgs, i); + Py_DECREF(ArgTuple); + if (!PyArg_ParseTuple(ArgTuple, "Ol", &BufferObj[i], &offset[i])) + return PyErr_Format(_Error, + "%s: Problem with buffer/offset tuple", me->descr.name); + } + return NA_callCUFuncCore(self, niter, ninargs, noutargs, BufferObj, offset); +} + +static PyObject * +callStrideConvCFunc(PyObject *self, PyObject *args) { + PyObject *inbuffObj, *outbuffObj, *shapeObj; + PyObject *inbstridesObj, *outbstridesObj; + CfuncObject *me = (CfuncObject *) self; + int nshape, ninbstrides, noutbstrides; + maybelong shape[MAXDIM], inbstrides[MAXDIM], + outbstrides[MAXDIM], *outbstrides1 = outbstrides; + long inboffset, outboffset, nbytes=0; + + if (!PyArg_ParseTuple(args, "OOlOOlO|l", + &shapeObj, &inbuffObj, &inboffset, &inbstridesObj, + &outbuffObj, &outboffset, &outbstridesObj, + &nbytes)) { + return PyErr_Format(_Error, + "%s: Problem with argument list", + me->descr.name); + } + + nshape = NA_maybeLongsFromIntTuple(MAXDIM, shape, shapeObj); + if (nshape < 0) return NULL; + + ninbstrides = NA_maybeLongsFromIntTuple(MAXDIM, inbstrides, inbstridesObj); + if (ninbstrides < 0) return NULL; + + noutbstrides= NA_maybeLongsFromIntTuple(MAXDIM, outbstrides, outbstridesObj); + if (noutbstrides < 0) return NULL; + + if (nshape && (nshape != ninbstrides)) { + return PyErr_Format(_Error, + "%s: Missmatch between input iteration and strides tuples", + me->descr.name); + } + + if (nshape && (nshape != noutbstrides)) { + if (noutbstrides < 1 || + outbstrides[ noutbstrides - 1 ])/* allow 0 for reductions. */ + return PyErr_Format(_Error, + "%s: Missmatch between output " + "iteration and strides tuples", + me->descr.name); + } + + return NA_callStrideConvCFuncCore( + self, nshape, shape, + inbuffObj, inboffset, ninbstrides, inbstrides, + outbuffObj, outboffset, noutbstrides, outbstrides1, nbytes); +} + +static int +_NA_callStridingHelper(PyObject *aux, long dim, + long nnumarray, PyArrayObject *numarray[], char *data[], + CFUNC_STRIDED_FUNC f) +{ + int i, j, status=0; + dim -= 1; + for(i=0; i<numarray[0]->dimensions[dim]; i++) { + for (j=0; j<nnumarray; j++) + data[j] += numarray[j]->strides[dim]*i; + if (dim == 0) + status |= f(aux, nnumarray, numarray, data); + else + status |= _NA_callStridingHelper( + aux, dim, nnumarray, numarray, data, f); + for (j=0; j<nnumarray; j++) + data[j] -= numarray[j]->strides[dim]*i; + } + return status; +} + + +static PyObject * +callStridingCFunc(PyObject *self, PyObject *args) { + CfuncObject *me = (CfuncObject *) self; + PyObject *aux; + PyArrayObject *numarray[MAXARRAYS]; + char *data[MAXARRAYS]; + CFUNC_STRIDED_FUNC f; + int i; + + int nnumarray = PySequence_Length(args)-1; + if ((nnumarray < 1) || (nnumarray > MAXARRAYS)) + return PyErr_Format(_Error, "%s, too many or too few numarray.", + me->descr.name); + + aux = PySequence_GetItem(args, 0); + if (!aux) + return NULL; + + for(i=0; i<nnumarray; i++) { + PyObject *otemp = PySequence_GetItem(args, i+1); + if (!otemp) + return PyErr_Format(_Error, "%s couldn't get array[%d]", + me->descr.name, i); + if (!NA_NDArrayCheck(otemp)) + return PyErr_Format(PyExc_TypeError, + "%s arg[%d] is not an array.", + me->descr.name, i); + numarray[i] = (PyArrayObject *) otemp; + data[i] = numarray[i]->data; + Py_DECREF(otemp); + if (!NA_updateDataPtr(numarray[i])) + return NULL; + } + + /* Cast function pointer and perform stride operation */ + f = (CFUNC_STRIDED_FUNC) me->descr.fptr; + + if (_NA_callStridingHelper(aux, numarray[0]->nd, + nnumarray, numarray, data, f)) { + return NULL; + } else { + Py_INCREF(Py_None); + return Py_None; + } +} + +/* Convert a standard C numeric value to a Python numeric value. +** +** Handles both nonaligned and/or byteswapped C data. +** +** Input arguments are: +** +** Buffer object that contains the C numeric value. +** Offset (in bytes) into the buffer that the data is located at. +** The size of the C numeric data item in bytes. +** Flag indicating if the C data is byteswapped from the processor's +** natural representation. +** +** Returns a Python numeric value. +*/ + +static PyObject * +NumTypeAsPyValue(PyObject *self, PyObject *args) { + PyObject *bufferObj; + long offset, itemsize, byteswap, i, buffersize; + Py_complex temp; /* to hold copies of largest possible type */ + void *buffer; + char *tempptr; + CFUNCasPyValue funcptr; + CfuncObject *me = (CfuncObject *) self; + + if (!PyArg_ParseTuple(args, "Olll", + &bufferObj, &offset, &itemsize, &byteswap)) + return PyErr_Format(_Error, + "NumTypeAsPyValue: Problem with argument list"); + + if ((buffersize = NA_getBufferPtrAndSize(bufferObj, 1, &buffer)) < 0) + return PyErr_Format(_Error, + "NumTypeAsPyValue: Problem with array buffer"); + + if (offset < 0) + return PyErr_Format(_Error, + "NumTypeAsPyValue: invalid negative offset: %d", (int) offset); + + /* Guarantee valid buffer pointer */ + if (offset+itemsize > buffersize) + return PyErr_Format(_Error, + "NumTypeAsPyValue: buffer too small for offset and itemsize."); + + /* Do byteswapping. Guarantee double alignment by using temp. */ + tempptr = (char *) &temp; + if (!byteswap) { + for (i=0; i<itemsize; i++) + *(tempptr++) = *(((char *) buffer)+offset+i); + } else { + tempptr += itemsize-1; + for (i=0; i<itemsize; i++) + *(tempptr--) = *(((char *) buffer)+offset+i); + } + + funcptr = (CFUNCasPyValue) me->descr.fptr; + + /* Call function to build PyObject. Bad parameters to this function + may render call meaningless, but "temp" guarantees that its safe. */ + return (*funcptr)((void *)(&temp)); +} + +/* Convert a Python numeric value to a standard C numeric value. +** +** Handles both nonaligned and/or byteswapped C data. +** +** Input arguments are: +** +** The Python numeric value to be converted. +** Buffer object to contain the C numeric value. +** Offset (in bytes) into the buffer that the data is to be copied to. +** The size of the C numeric data item in bytes. +** Flag indicating if the C data is byteswapped from the processor's +** natural representation. +** +** Returns None +*/ + +static PyObject * +NumTypeFromPyValue(PyObject *self, PyObject *args) { + PyObject *bufferObj, *valueObj; + long offset, itemsize, byteswap, i, buffersize; + Py_complex temp; /* to hold copies of largest possible type */ + void *buffer; + char *tempptr; + CFUNCfromPyValue funcptr; + CfuncObject *me = (CfuncObject *) self; + + if (!PyArg_ParseTuple(args, "OOlll", + &valueObj, &bufferObj, &offset, &itemsize, &byteswap)) + return PyErr_Format(_Error, + "%s: Problem with argument list", me->descr.name); + + if ((buffersize = NA_getBufferPtrAndSize(bufferObj, 0, &buffer)) < 0) + return PyErr_Format(_Error, + "%s: Problem with array buffer (read only?)", me->descr.name); + + funcptr = (CFUNCfromPyValue) me->descr.fptr; + + /* Convert python object into "temp". Always safe. */ + if (!((*funcptr)(valueObj, (void *)( &temp)))) + return PyErr_Format(_Error, + "%s: Problem converting value", me->descr.name); + + /* Check buffer offset. */ + if (offset < 0) + return PyErr_Format(_Error, + "%s: invalid negative offset: %d", me->descr.name, (int) offset); + + if (offset+itemsize > buffersize) + return PyErr_Format(_Error, + "%s: buffer too small(%d) for offset(%d) and itemsize(%d)", + me->descr.name, (int) buffersize, (int) offset, (int) itemsize); + + /* Copy "temp" to array buffer. */ + tempptr = (char *) &temp; + if (!byteswap) { + for (i=0; i<itemsize; i++) + *(((char *) buffer)+offset+i) = *(tempptr++); + } else { + tempptr += itemsize-1; + for (i=0; i<itemsize; i++) + *(((char *) buffer)+offset+i) = *(tempptr--); + } + Py_INCREF(Py_None); + return Py_None; +} + +/* Handle "calling" the cfunc object at the python level. + Dispatch the call to the appropriate python-c wrapper based + on the cfunc type. Do this dispatch to avoid having to + check that python code didn't somehow create a mismatch between + cfunc and wrapper. +*/ +static PyObject * +cfunc_call(PyObject *self, PyObject *argsTuple, PyObject *argsDict) +{ + CfuncObject *me = (CfuncObject *) self; + switch(me->descr.type) { + case CFUNC_UFUNC: + return callCUFunc(self, argsTuple); + break; + case CFUNC_STRIDING: + return callStrideConvCFunc(self, argsTuple); + break; + case CFUNC_NSTRIDING: + return callStridingCFunc(self, argsTuple); + case CFUNC_FROM_PY_VALUE: + return NumTypeFromPyValue(self, argsTuple); + break; + case CFUNC_AS_PY_VALUE: + return NumTypeAsPyValue(self, argsTuple); + break; + default: + return PyErr_Format( _Error, + "cfunc_call: Can't dispatch cfunc '%s' with type: %d.", + me->descr.name, me->descr.type); + } +} + +staticforward PyTypeObject CfuncType; + +static void +cfunc_dealloc(PyObject* self) +{ + PyObject_Del(self); +} + +static PyObject * +cfunc_repr(PyObject *self) +{ + char buf[256]; + CfuncObject *me = (CfuncObject *) self; + sprintf(buf, "<cfunc '%s' at %08lx check-self:%d align:%d io:(%d, %d)>", + me->descr.name, (unsigned long ) me->descr.fptr, + me->descr.chkself, me->descr.align, + me->descr.wantIn, me->descr.wantOut); + return PyString_FromString(buf); +} + +static PyTypeObject CfuncType = { + PyObject_HEAD_INIT(NULL) + 0, + "Cfunc", + sizeof(CfuncObject), + 0, + cfunc_dealloc, /*tp_dealloc*/ + 0, /*tp_print*/ + 0, /*tp_getattr*/ + 0, /*tp_setattr*/ + 0, /*tp_compare*/ + cfunc_repr, /*tp_repr*/ + 0, /*tp_as_number*/ + 0, /*tp_as_sequence*/ + 0, /*tp_as_mapping*/ + 0, /*tp_hash */ + cfunc_call, /* tp_call */ +}; + +/* CfuncObjects are created at the c-level only. They ensure that each +cfunc is called via the correct python-c-wrapper as defined by its +CfuncDescriptor. The wrapper, in turn, does conversions and buffer size +and alignment checking. Allowing these to be created at the python level +would enable them to be created *wrong* at the python level, and thereby +enable python code to *crash* python. +*/ +static PyObject* +NA_new_cfunc(CfuncDescriptor *cfd) +{ + CfuncObject* cfunc; + + CfuncType.ob_type = &PyType_Type; /* Should be done once at init. + Do now since there is no init. */ + + cfunc = PyObject_New(CfuncObject, &CfuncType); + + if (!cfunc) { + return PyErr_Format(_Error, + "NA_new_cfunc: failed creating '%s'", + cfd->name); + } + + cfunc->descr = *cfd; + + return (PyObject*)cfunc; +} + +static int NA_add_cfunc(PyObject *dict, char *keystr, CfuncDescriptor *descr) +{ + PyObject *c = (PyObject *) NA_new_cfunc(descr); + if (!c) return -1; + return PyDict_SetItemString(dict, keystr, c); +} + +static PyArrayObject* +NA_InputArray(PyObject *a, NumarrayType t, int requires) +{ + PyArray_Descr *descr; + if (t == tAny) descr = NULL; + else descr = PyArray_DescrFromType(t); + return (PyArrayObject *) \ + PyArray_CheckFromAny(a, descr, 0, 0, requires, NULL); +} + +/* satisfies ensures that 'a' meets a set of requirements and matches +the specified type. +*/ +static int +satisfies(PyArrayObject *a, int requirements, NumarrayType t) +{ + int type_ok = (a->descr->type_num == t) || (t == tAny); + + if (PyArray_ISCARRAY(a)) + return type_ok; + if (PyArray_ISBYTESWAPPED(a) && (requirements & NUM_NOTSWAPPED)) + return 0; + if (!PyArray_ISALIGNED(a) && (requirements & NUM_ALIGNED)) + return 0; + if (!PyArray_ISCONTIGUOUS(a) && (requirements & NUM_CONTIGUOUS)) + return 0; + if (!PyArray_ISWRITABLE(a) && (requirements & NUM_WRITABLE)) + return 0; + if (requirements & NUM_COPY) + return 0; + return type_ok; +} + + +static PyArrayObject * +NA_OutputArray(PyObject *a, NumarrayType t, int requires) +{ + PyArray_Descr *dtype; + PyArrayObject *ret; + + if (!PyArray_Check(a) || !PyArray_ISWRITEABLE(a)) { + PyErr_Format(PyExc_TypeError, + "NA_OutputArray: only writeable arrays work for output."); + return NULL; + } + + if (satisfies((PyArrayObject *)a, requires, t)) { + Py_INCREF(a); + return (PyArrayObject *)a; + } + if (t == tAny) { + dtype = PyArray_DESCR(a); + Py_INCREF(dtype); + } + else { + dtype = PyArray_DescrFromType(t); + } + ret = (PyArrayObject *)PyArray_Empty(PyArray_NDIM(a), PyArray_DIMS(a), + dtype, 0); + ret->flags |= NPY_UPDATEIFCOPY; + ret->base = a; + PyArray_FLAGS(a) &= ~NPY_WRITEABLE; + Py_INCREF(a); + return ret; +} + + +/* NA_IoArray is a combination of NA_InputArray and NA_OutputArray. + +Unlike NA_OutputArray, if a temporary is required it is initialized to a copy +of the input array. + +Unlike NA_InputArray, deallocating any resulting temporary array results in a +copy from the temporary back to the original. +*/ +static PyArrayObject * +NA_IoArray(PyObject *a, NumarrayType t, int requires) +{ + PyArrayObject *shadow = NA_InputArray(a, t, requires | NPY_UPDATEIFCOPY ); + + if (!shadow) return NULL; + + /* Guard against non-writable, but otherwise satisfying requires. + In this case, shadow == a. + */ + if (!PyArray_ISWRITABLE(shadow)) { + PyErr_Format(PyExc_TypeError, + "NA_IoArray: I/O array must be writable array"); + PyArray_XDECREF_ERR(shadow); + return NULL; + } + + return shadow; +} + +/* NA_OptionalOutputArray works like NA_OutputArray, but handles the case +where the output array 'optional' is omitted entirely at the python level, +resulting in 'optional'==Py_None. When 'optional' is Py_None, the return +value is cloned (but with NumarrayType 't') from 'master', typically an input +array with the same shape as the output array. +*/ +static PyArrayObject * +NA_OptionalOutputArray(PyObject *optional, NumarrayType t, int requires, + PyArrayObject *master) +{ + if ((optional == Py_None) || (optional == NULL)) { + PyObject *rval; + PyArray_Descr *descr; + if (t == tAny) descr=NULL; + else descr = PyArray_DescrFromType(t); + rval = PyArray_FromArray( + master, descr, NUM_C_ARRAY | NUM_COPY | NUM_WRITABLE); + return (PyArrayObject *)rval; + } else { + return NA_OutputArray(optional, t, requires); + } +} + +Complex64 NA_get_Complex64(PyArrayObject *a, long offset) +{ + Complex32 v0; + Complex64 v; + + switch(a->descr->type_num) { + case tComplex32: + v0 = NA_GETP(a, Complex32, (NA_PTR(a)+offset)); + v.r = v0.r; + v.i = v0.i; + break; + case tComplex64: + v = NA_GETP(a, Complex64, (NA_PTR(a)+offset)); + break; + default: + v.r = NA_get_Float64(a, offset); + v.i = 0; + break; + } + return v; +} + +void NA_set_Complex64(PyArrayObject *a, long offset, Complex64 v) +{ + Complex32 v0; + + switch(a->descr->type_num) { + case tComplex32: + v0.r = v.r; + v0.i = v.i; + NA_SETP(a, Complex32, (NA_PTR(a)+offset), v0); + break; + case tComplex64: + NA_SETP(a, Complex64, (NA_PTR(a)+offset), v); + break; + default: + NA_set_Float64(a, offset, v.r); + break; + } +} + +Int64 NA_get_Int64(PyArrayObject *a, long offset) +{ + switch(a->descr->type_num) { + case tBool: + return NA_GETP(a, Bool, (NA_PTR(a)+offset)) != 0; + case tInt8: + return NA_GETP(a, Int8, (NA_PTR(a)+offset)); + case tUInt8: + return NA_GETP(a, UInt8, (NA_PTR(a)+offset)); + case tInt16: + return NA_GETP(a, Int16, (NA_PTR(a)+offset)); + case tUInt16: + return NA_GETP(a, UInt16, (NA_PTR(a)+offset)); + case tInt32: + return NA_GETP(a, Int32, (NA_PTR(a)+offset)); + case tUInt32: + return NA_GETP(a, UInt32, (NA_PTR(a)+offset)); + case tInt64: + return NA_GETP(a, Int64, (NA_PTR(a)+offset)); + case tUInt64: + return NA_GETP(a, UInt64, (NA_PTR(a)+offset)); + case tFloat32: + return NA_GETP(a, Float32, (NA_PTR(a)+offset)); + case tFloat64: + return NA_GETP(a, Float64, (NA_PTR(a)+offset)); + case tComplex32: + return NA_GETP(a, Float32, (NA_PTR(a)+offset)); + case tComplex64: + return NA_GETP(a, Float64, (NA_PTR(a)+offset)); + default: + PyErr_Format( PyExc_TypeError, + "Unknown type %d in NA_get_Int64", + a->descr->type_num); + PyErr_Print(); + } + return 0; /* suppress warning */ +} + +void NA_set_Int64(PyArrayObject *a, long offset, Int64 v) +{ + Bool b; + + switch(a->descr->type_num) { + case tBool: + b = (v != 0); + NA_SETP(a, Bool, (NA_PTR(a)+offset), b); + break; + case tInt8: NA_SETP(a, Int8, (NA_PTR(a)+offset), v); + break; + case tUInt8: NA_SETP(a, UInt8, (NA_PTR(a)+offset), v); + break; + case tInt16: NA_SETP(a, Int16, (NA_PTR(a)+offset), v); + break; + case tUInt16: NA_SETP(a, UInt16, (NA_PTR(a)+offset), v); + break; + case tInt32: NA_SETP(a, Int32, (NA_PTR(a)+offset), v); + break; + case tUInt32: NA_SETP(a, UInt32, (NA_PTR(a)+offset), v); + break; + case tInt64: NA_SETP(a, Int64, (NA_PTR(a)+offset), v); + break; + case tUInt64: NA_SETP(a, UInt64, (NA_PTR(a)+offset), v); + break; + case tFloat32: + NA_SETP(a, Float32, (NA_PTR(a)+offset), v); + break; + case tFloat64: + NA_SETP(a, Float64, (NA_PTR(a)+offset), v); + break; + case tComplex32: + NA_SETP(a, Float32, (NA_PTR(a)+offset), v); + NA_SETP(a, Float32, (NA_PTR(a)+offset+sizeof(Float32)), 0); + break; + case tComplex64: + NA_SETP(a, Float64, (NA_PTR(a)+offset), v); + NA_SETP(a, Float64, (NA_PTR(a)+offset+sizeof(Float64)), 0); + break; + default: + PyErr_Format( PyExc_TypeError, + "Unknown type %d in NA_set_Int64", + a->descr->type_num); + PyErr_Print(); + } +} + +/* NA_get_offset computes the offset specified by the set of indices. +If N > 0, the indices are taken from the outer dimensions of the array. +If N < 0, the indices are taken from the inner dimensions of the array. +If N == 0, the offset is 0. +*/ +long NA_get_offset(PyArrayObject *a, int N, ...) +{ + int i; + long offset = 0; + va_list ap; + va_start(ap, N); + if (N > 0) { /* compute offset of "outer" indices. */ + for(i=0; i<N; i++) + offset += va_arg(ap, long) * a->strides[i]; + } else { /* compute offset of "inner" indices. */ + N = -N; + for(i=0; i<N; i++) + offset += va_arg(ap, long) * a->strides[a->nd-N+i]; + } + va_end(ap); + return offset; +} + +Float64 NA_get_Float64(PyArrayObject *a, long offset) +{ + switch(a->descr->type_num) { + case tBool: + return NA_GETP(a, Bool, (NA_PTR(a)+offset)) != 0; + case tInt8: + return NA_GETP(a, Int8, (NA_PTR(a)+offset)); + case tUInt8: + return NA_GETP(a, UInt8, (NA_PTR(a)+offset)); + case tInt16: + return NA_GETP(a, Int16, (NA_PTR(a)+offset)); + case tUInt16: + return NA_GETP(a, UInt16, (NA_PTR(a)+offset)); + case tInt32: + return NA_GETP(a, Int32, (NA_PTR(a)+offset)); + case tUInt32: + return NA_GETP(a, UInt32, (NA_PTR(a)+offset)); + case tInt64: + return NA_GETP(a, Int64, (NA_PTR(a)+offset)); + #if HAS_UINT64 + case tUInt64: + return NA_GETP(a, UInt64, (NA_PTR(a)+offset)); + #endif + case tFloat32: + return NA_GETP(a, Float32, (NA_PTR(a)+offset)); + case tFloat64: + return NA_GETP(a, Float64, (NA_PTR(a)+offset)); + case tComplex32: /* Since real value is first */ + return NA_GETP(a, Float32, (NA_PTR(a)+offset)); + case tComplex64: /* Since real value is first */ + return NA_GETP(a, Float64, (NA_PTR(a)+offset)); + default: + PyErr_Format( PyExc_TypeError, + "Unknown type %d in NA_get_Float64", + a->descr->type_num); + } + return 0; /* suppress warning */ +} + +void NA_set_Float64(PyArrayObject *a, long offset, Float64 v) +{ + Bool b; + + switch(a->descr->type_num) { + case tBool: + b = (v != 0); + NA_SETP(a, Bool, (NA_PTR(a)+offset), b); + break; + case tInt8: NA_SETP(a, Int8, (NA_PTR(a)+offset), v); + break; + case tUInt8: NA_SETP(a, UInt8, (NA_PTR(a)+offset), v); + break; + case tInt16: NA_SETP(a, Int16, (NA_PTR(a)+offset), v); + break; + case tUInt16: NA_SETP(a, UInt16, (NA_PTR(a)+offset), v); + break; + case tInt32: NA_SETP(a, Int32, (NA_PTR(a)+offset), v); + break; + case tUInt32: NA_SETP(a, UInt32, (NA_PTR(a)+offset), v); + break; + case tInt64: NA_SETP(a, Int64, (NA_PTR(a)+offset), v); + break; + #if HAS_UINT64 + case tUInt64: NA_SETP(a, UInt64, (NA_PTR(a)+offset), v); + break; + #endif + case tFloat32: + NA_SETP(a, Float32, (NA_PTR(a)+offset), v); + break; + case tFloat64: + NA_SETP(a, Float64, (NA_PTR(a)+offset), v); + break; + case tComplex32: { + NA_SETP(a, Float32, (NA_PTR(a)+offset), v); + NA_SETP(a, Float32, (NA_PTR(a)+offset+sizeof(Float32)), 0); + break; + } + case tComplex64: { + NA_SETP(a, Float64, (NA_PTR(a)+offset), v); + NA_SETP(a, Float64, (NA_PTR(a)+offset+sizeof(Float64)), 0); + break; + } + default: + PyErr_Format( PyExc_TypeError, + "Unknown type %d in NA_set_Float64", + a->descr->type_num ); + PyErr_Print(); + } +} + + +Float64 NA_get1_Float64(PyArrayObject *a, long i) +{ + long offset = i * a->strides[0]; + return NA_get_Float64(a, offset); +} + +Float64 NA_get2_Float64(PyArrayObject *a, long i, long j) +{ + long offset = i * a->strides[0] + + j * a->strides[1]; + return NA_get_Float64(a, offset); +} + +Float64 NA_get3_Float64(PyArrayObject *a, long i, long j, long k) +{ + long offset = i * a->strides[0] + + j * a->strides[1] + + k * a->strides[2]; + return NA_get_Float64(a, offset); +} + +void NA_set1_Float64(PyArrayObject *a, long i, Float64 v) +{ + long offset = i * a->strides[0]; + NA_set_Float64(a, offset, v); +} + +void NA_set2_Float64(PyArrayObject *a, long i, long j, Float64 v) +{ + long offset = i * a->strides[0] + + j * a->strides[1]; + NA_set_Float64(a, offset, v); +} + +void NA_set3_Float64(PyArrayObject *a, long i, long j, long k, Float64 v) +{ + long offset = i * a->strides[0] + + j * a->strides[1] + + k * a->strides[2]; + NA_set_Float64(a, offset, v); +} + +Complex64 NA_get1_Complex64(PyArrayObject *a, long i) +{ + long offset = i * a->strides[0]; + return NA_get_Complex64(a, offset); +} + +Complex64 NA_get2_Complex64(PyArrayObject *a, long i, long j) +{ + long offset = i * a->strides[0] + + j * a->strides[1]; + return NA_get_Complex64(a, offset); +} + +Complex64 NA_get3_Complex64(PyArrayObject *a, long i, long j, long k) +{ + long offset = i * a->strides[0] + + j * a->strides[1] + + k * a->strides[2]; + return NA_get_Complex64(a, offset); +} + +void NA_set1_Complex64(PyArrayObject *a, long i, Complex64 v) +{ + long offset = i * a->strides[0]; + NA_set_Complex64(a, offset, v); +} + +void NA_set2_Complex64(PyArrayObject *a, long i, long j, Complex64 v) +{ + long offset = i * a->strides[0] + + j * a->strides[1]; + NA_set_Complex64(a, offset, v); +} + +void NA_set3_Complex64(PyArrayObject *a, long i, long j, long k, Complex64 v) +{ + long offset = i * a->strides[0] + + j * a->strides[1] + + k * a->strides[2]; + NA_set_Complex64(a, offset, v); +} + +Int64 NA_get1_Int64(PyArrayObject *a, long i) +{ + long offset = i * a->strides[0]; + return NA_get_Int64(a, offset); +} + +Int64 NA_get2_Int64(PyArrayObject *a, long i, long j) +{ + long offset = i * a->strides[0] + + j * a->strides[1]; + return NA_get_Int64(a, offset); +} + +Int64 NA_get3_Int64(PyArrayObject *a, long i, long j, long k) +{ + long offset = i * a->strides[0] + + j * a->strides[1] + + k * a->strides[2]; + return NA_get_Int64(a, offset); +} + +void NA_set1_Int64(PyArrayObject *a, long i, Int64 v) +{ + long offset = i * a->strides[0]; + NA_set_Int64(a, offset, v); +} + +void NA_set2_Int64(PyArrayObject *a, long i, long j, Int64 v) +{ + long offset = i * a->strides[0] + + j * a->strides[1]; + NA_set_Int64(a, offset, v); +} + +void NA_set3_Int64(PyArrayObject *a, long i, long j, long k, Int64 v) +{ + long offset = i * a->strides[0] + + j * a->strides[1] + + k * a->strides[2]; + NA_set_Int64(a, offset, v); +} + +/* SET_CMPLX could be made faster by factoring it into 3 seperate loops. +*/ +#define NA_SET_CMPLX(a, type, base, cnt, in) \ +{ \ + int i; \ + int stride = a->strides[ a->nd - 1]; \ + NA_SET1D(a, type, base, cnt, in); \ + base = NA_PTR(a) + offset + sizeof(type); \ + for(i=0; i<cnt; i++) { \ + NA_SETP(a, Float32, base, 0); \ + base += stride; \ + } \ +} + +static int +NA_get1D_Float64(PyArrayObject *a, long offset, int cnt, Float64*out) +{ + char *base = NA_PTR(a) + offset; + + switch(a->descr->type_num) { + case tBool: + NA_GET1D(a, Bool, base, cnt, out); + break; + case tInt8: + NA_GET1D(a, Int8, base, cnt, out); + break; + case tUInt8: + NA_GET1D(a, UInt8, base, cnt, out); + break; + case tInt16: + NA_GET1D(a, Int16, base, cnt, out); + break; + case tUInt16: + NA_GET1D(a, UInt16, base, cnt, out); + break; + case tInt32: + NA_GET1D(a, Int32, base, cnt, out); + break; + case tUInt32: + NA_GET1D(a, UInt32, base, cnt, out); + break; + case tInt64: + NA_GET1D(a, Int64, base, cnt, out); + break; + #if HAS_UINT64 + case tUInt64: + NA_GET1D(a, UInt64, base, cnt, out); + break; + #endif + case tFloat32: + NA_GET1D(a, Float32, base, cnt, out); + break; + case tFloat64: + NA_GET1D(a, Float64, base, cnt, out); + break; + case tComplex32: + NA_GET1D(a, Float32, base, cnt, out); + break; + case tComplex64: + NA_GET1D(a, Float64, base, cnt, out); + break; + default: + PyErr_Format( PyExc_TypeError, + "Unknown type %d in NA_get1D_Float64", + a->descr->type_num); + PyErr_Print(); + return -1; + } + return 0; +} + +static Float64 * +NA_alloc1D_Float64(PyArrayObject *a, long offset, int cnt) +{ + Float64 *result = PyMem_New(Float64, cnt); + if (!result) return NULL; + if (NA_get1D_Float64(a, offset, cnt, result) < 0) { + PyMem_Free(result); + return NULL; + } + return result; +} + +static int +NA_set1D_Float64(PyArrayObject *a, long offset, int cnt, Float64*in) +{ + char *base = NA_PTR(a) + offset; + + switch(a->descr->type_num) { + case tBool: + NA_SET1D(a, Bool, base, cnt, in); + break; + case tInt8: + NA_SET1D(a, Int8, base, cnt, in); + break; + case tUInt8: + NA_SET1D(a, UInt8, base, cnt, in); + break; + case tInt16: + NA_SET1D(a, Int16, base, cnt, in); + break; + case tUInt16: + NA_SET1D(a, UInt16, base, cnt, in); + break; + case tInt32: + NA_SET1D(a, Int32, base, cnt, in); + break; + case tUInt32: + NA_SET1D(a, UInt32, base, cnt, in); + break; + case tInt64: + NA_SET1D(a, Int64, base, cnt, in); + break; + #if HAS_UINT64 + case tUInt64: + NA_SET1D(a, UInt64, base, cnt, in); + break; + #endif + case tFloat32: + NA_SET1D(a, Float32, base, cnt, in); + break; + case tFloat64: + NA_SET1D(a, Float64, base, cnt, in); + break; + case tComplex32: + NA_SET_CMPLX(a, Float32, base, cnt, in); + break; + case tComplex64: + NA_SET_CMPLX(a, Float64, base, cnt, in); + break; + default: + PyErr_Format( PyExc_TypeError, + "Unknown type %d in NA_set1D_Float64", + a->descr->type_num); + PyErr_Print(); + return -1; + } + return 0; +} + +static int +NA_get1D_Int64(PyArrayObject *a, long offset, int cnt, Int64*out) +{ + char *base = NA_PTR(a) + offset; + + switch(a->descr->type_num) { + case tBool: + NA_GET1D(a, Bool, base, cnt, out); + break; + case tInt8: + NA_GET1D(a, Int8, base, cnt, out); + break; + case tUInt8: + NA_GET1D(a, UInt8, base, cnt, out); + break; + case tInt16: + NA_GET1D(a, Int16, base, cnt, out); + break; + case tUInt16: + NA_GET1D(a, UInt16, base, cnt, out); + break; + case tInt32: + NA_GET1D(a, Int32, base, cnt, out); + break; + case tUInt32: + NA_GET1D(a, UInt32, base, cnt, out); + break; + case tInt64: + NA_GET1D(a, Int64, base, cnt, out); + break; + case tUInt64: + NA_GET1D(a, UInt64, base, cnt, out); + break; + case tFloat32: + NA_GET1D(a, Float32, base, cnt, out); + break; + case tFloat64: + NA_GET1D(a, Float64, base, cnt, out); + break; + case tComplex32: + NA_GET1D(a, Float32, base, cnt, out); + break; + case tComplex64: + NA_GET1D(a, Float64, base, cnt, out); + break; + default: + PyErr_Format( PyExc_TypeError, + "Unknown type %d in NA_get1D_Int64", + a->descr->type_num); + PyErr_Print(); + return -1; + } + return 0; +} + +static Int64 * +NA_alloc1D_Int64(PyArrayObject *a, long offset, int cnt) +{ + Int64 *result = PyMem_New(Int64, cnt); + if (!result) return NULL; + if (NA_get1D_Int64(a, offset, cnt, result) < 0) { + PyMem_Free(result); + return NULL; + } + return result; +} + +static int +NA_set1D_Int64(PyArrayObject *a, long offset, int cnt, Int64*in) +{ + char *base = NA_PTR(a) + offset; + + switch(a->descr->type_num) { + case tBool: + NA_SET1D(a, Bool, base, cnt, in); + break; + case tInt8: + NA_SET1D(a, Int8, base, cnt, in); + break; + case tUInt8: + NA_SET1D(a, UInt8, base, cnt, in); + break; + case tInt16: + NA_SET1D(a, Int16, base, cnt, in); + break; + case tUInt16: + NA_SET1D(a, UInt16, base, cnt, in); + break; + case tInt32: + NA_SET1D(a, Int32, base, cnt, in); + break; + case tUInt32: + NA_SET1D(a, UInt32, base, cnt, in); + break; + case tInt64: + NA_SET1D(a, Int64, base, cnt, in); + break; + case tUInt64: + NA_SET1D(a, UInt64, base, cnt, in); + break; + case tFloat32: + NA_SET1D(a, Float32, base, cnt, in); + break; + case tFloat64: + NA_SET1D(a, Float64, base, cnt, in); + break; + case tComplex32: + NA_SET_CMPLX(a, Float32, base, cnt, in); + break; + case tComplex64: + NA_SET_CMPLX(a, Float64, base, cnt, in); + break; + default: + PyErr_Format( PyExc_TypeError, + "Unknown type %d in NA_set1D_Int64", + a->descr->type_num); + PyErr_Print(); + return -1; + } + return 0; +} + +static int +NA_get1D_Complex64(PyArrayObject *a, long offset, int cnt, Complex64*out) +{ + char *base = NA_PTR(a) + offset; + + switch(a->descr->type_num) { + case tComplex64: + NA_GET1D(a, Complex64, base, cnt, out); + break; + default: + PyErr_Format( PyExc_TypeError, + "Unsupported type %d in NA_get1D_Complex64", + a->descr->type_num); + PyErr_Print(); + return -1; + } + return 0; +} + +static int +NA_set1D_Complex64(PyArrayObject *a, long offset, int cnt, Complex64*in) +{ + char *base = NA_PTR(a) + offset; + + switch(a->descr->type_num) { + case tComplex64: + NA_SET1D(a, Complex64, base, cnt, in); + break; + default: + PyErr_Format( PyExc_TypeError, + "Unsupported type %d in NA_set1D_Complex64", + a->descr->type_num); + PyErr_Print(); + return -1; + } + return 0; +} + + +/* NA_ShapeEqual returns 1 if 'a' and 'b' have the same shape, 0 otherwise. +*/ +static int +NA_ShapeEqual(PyArrayObject *a, PyArrayObject *b) +{ + int i; + + if (!NA_NDArrayCheck((PyObject *) a) || + !NA_NDArrayCheck((PyObject*) b)) { + PyErr_Format( + PyExc_TypeError, + "NA_ShapeEqual: non-array as parameter."); + return -1; + } + if (a->nd != b->nd) + return 0; + for(i=0; i<a->nd; i++) + if (a->dimensions[i] != b->dimensions[i]) + return 0; + return 1; +} + +/* NA_ShapeLessThan returns 1 if a.shape[i] < b.shape[i] for all i, else 0. +If they have a different number of dimensions, it compares the innermost +overlapping dimensions of each. +*/ +static int +NA_ShapeLessThan(PyArrayObject *a, PyArrayObject *b) +{ + int i; + int mindim, aoff, boff; + if (!NA_NDArrayCheck((PyObject *) a) || + !NA_NDArrayCheck((PyObject *) b)) { + PyErr_Format(PyExc_TypeError, + "NA_ShapeLessThan: non-array as parameter."); + return -1; + } + mindim = MIN(a->nd, b->nd); + aoff = a->nd - mindim; + boff = b->nd - mindim; + for(i=0; i<mindim; i++) + if (a->dimensions[i+aoff] >= b->dimensions[i+boff]) + return 0; + return 1; +} + +static int +NA_ByteOrder(void) +{ + unsigned long byteorder_test; + byteorder_test = 1; + if (*((char *) &byteorder_test)) + return NUM_LITTLE_ENDIAN; + else + return NUM_BIG_ENDIAN; +} + +static Bool +NA_IeeeSpecial32( Float32 *f, Int32 *mask) +{ + return NA_IeeeMask32(*f, *mask); +} + +static Bool +NA_IeeeSpecial64( Float64 *f, Int32 *mask) +{ + return NA_IeeeMask64(*f, *mask); +} + +static PyArrayObject * +NA_updateDataPtr(PyArrayObject *me) +{ + return me; +} + + +#define ELEM(x) (sizeof(x)/sizeof(x[0])) + +typedef struct +{ + char *name; + int typeno; +} NumarrayTypeNameMapping; + +static NumarrayTypeNameMapping NumarrayTypeNameMap[] = { + {"Any", tAny}, + {"Bool", tBool}, + {"Int8", tInt8}, + {"UInt8", tUInt8}, + {"Int16", tInt16}, + {"UInt16", tUInt16}, + {"Int32", tInt32}, + {"UInt32", tUInt32}, + {"Int64", tInt64}, + {"UInt64", tUInt64}, + {"Float32", tFloat32}, + {"Float64", tFloat64}, + {"Complex32", tComplex32}, + {"Complex64", tComplex64}, + {"Object", tObject}, + {"Long", tLong}, +}; + + +/* Convert NumarrayType 'typeno' into the string of the type's name. */ +static char * +NA_typeNoToName(int typeno) +{ + int i; + PyObject *typeObj; + int typeno2; + + for(i=0; i<ELEM(NumarrayTypeNameMap); i++) + if (typeno == NumarrayTypeNameMap[i].typeno) + return NumarrayTypeNameMap[i].name; + + /* Handle Numeric typecodes */ + typeObj = NA_typeNoToTypeObject(typeno); + if (!typeObj) return 0; + typeno2 = NA_typeObjectToTypeNo(typeObj); + Py_DECREF(typeObj); + + return NA_typeNoToName(typeno2); +} + +/* Look up the NumarrayType which corresponds to typename */ + +static int +NA_nameToTypeNo(char *typename) +{ + int i; + for(i=0; i<ELEM(NumarrayTypeNameMap); i++) + if (!strcmp(typename, NumarrayTypeNameMap[i].name)) + return NumarrayTypeNameMap[i].typeno; + return -1; +} + +static PyObject * +getTypeObject(NumarrayType type) +{ + return (PyObject *)PyArray_DescrFromType(type); +} + + +static PyObject * +NA_typeNoToTypeObject(int typeno) +{ + PyObject *o; + o = getTypeObject(typeno); + if (o) Py_INCREF(o); + return o; +} + + +static PyObject * +NA_intTupleFromMaybeLongs(int len, maybelong *Longs) +{ + return PyArray_IntTupleFromIntp(len, Longs); +} + +static long +NA_maybeLongsFromIntTuple(int len, maybelong *arr, PyObject *sequence) +{ + return PyArray_IntpFromSequence(sequence, arr, len); +} + + +static int +NA_intTupleProduct(PyObject *shape, long *prod) +{ + int i, nshape, rval = -1; + + if (!PySequence_Check(shape)) { + PyErr_Format(PyExc_TypeError, + "NA_intSequenceProduct: object is not a sequence."); + goto _exit; + } + nshape = PySequence_Size(shape); + + for(i=0, *prod=1; i<nshape; i++) { + PyObject *obj = PySequence_GetItem(shape, i); + if (!obj || !(PyInt_Check(obj) || PyLong_Check(obj))) { + PyErr_Format(PyExc_TypeError, + "NA_intTupleProduct: non-integer in shape."); + Py_XDECREF(obj); + goto _exit; + } + *prod *= PyInt_AsLong(obj); + Py_DECREF(obj); + if (PyErr_Occurred()) + goto _exit; + } + rval = 0; + _exit: + return rval; +} + +static long +NA_isIntegerSequence(PyObject *sequence) +{ + PyObject *o; + long i, size, isInt = 1; + if (!sequence) { + isInt = -1; + goto _exit; + } + if (!PySequence_Check(sequence)) { + isInt = 0; + goto _exit; + } + if ((size = PySequence_Length(sequence)) < 0) { + isInt = -1; + goto _exit; + } + for(i=0; i<size; i++) { + o = PySequence_GetItem(sequence, i); + if (!PyInt_Check(o) && !PyLong_Check(o)) { + isInt = 0; + Py_XDECREF(o); + goto _exit; + } + Py_XDECREF(o); + } + _exit: + return isInt; +} + +static int +getShape(PyObject *a, maybelong *shape, int dims) +{ + long slen; + + if (PyString_Check(a)) { + PyErr_Format(PyExc_TypeError, + "getShape: numerical sequences can't contain strings."); + return -1; + } + + if (!PySequence_Check(a) || + (NA_NDArrayCheck(a) && (PyArray(a)->nd == 0))) + return dims; + slen = PySequence_Length(a); + if (slen < 0) { + PyErr_Format(_Error, + "getShape: couldn't get sequence length."); + return -1; + } + if (!slen) { + *shape = 0; + return dims+1; + } else if (dims < MAXDIM) { + PyObject *item0 = PySequence_GetItem(a, 0); + if (item0) { + *shape = PySequence_Length(a); + dims = getShape(item0, ++shape, dims+1); + Py_DECREF(item0); + } else { + PyErr_Format(_Error, + "getShape: couldn't get sequence item."); + return -1; + } + } else { + PyErr_Format(_Error, + "getShape: sequence object nested more than MAXDIM deep."); + return -1; + } + return dims; +} + + + +typedef enum { + NOTHING, + NUMBER, + SEQUENCE +} SequenceConstraint; + +static int +setArrayFromSequence(PyArrayObject *a, PyObject *s, int dim, long offset) +{ + SequenceConstraint mustbe = NOTHING; + int i, seqlen=-1, slen = PySequence_Length(s); + + if (dim > a->nd) { + PyErr_Format(PyExc_ValueError, + "setArrayFromSequence: sequence/array dimensions mismatch."); + return -1; + } + + if (slen != a->dimensions[dim]) { + PyErr_Format(PyExc_ValueError, + "setArrayFromSequence: sequence/array shape mismatch."); + return -1; + } + + for(i=0; i<slen; i++) { + PyObject *o = PySequence_GetItem(s, i); + if (!o) { + PyErr_SetString(_Error, + "setArrayFromSequence: Can't get a sequence item"); + return -1; + } else if ((NA_isPythonScalar(o) || + (NA_NumArrayCheck(o) && PyArray(o)->nd == 0)) && + ((mustbe == NOTHING) || (mustbe == NUMBER))) { + if (NA_setFromPythonScalar(a, offset, o) < 0) + return -2; + mustbe = NUMBER; + } else if (PyString_Check(o)) { + PyErr_SetString( PyExc_ValueError, + "setArrayFromSequence: strings can't define numeric numarray."); + return -3; + } else if (PySequence_Check(o)) { + if ((mustbe == NOTHING) || (mustbe == SEQUENCE)) { + if (mustbe == NOTHING) { + mustbe = SEQUENCE; + seqlen = PySequence_Length(o); + } else if (PySequence_Length(o) != seqlen) { + PyErr_SetString( + PyExc_ValueError, + "Nested sequences with different lengths."); + return -5; + } + setArrayFromSequence(a, o, dim+1, offset); + } else { + PyErr_SetString(PyExc_ValueError, + "Nested sequences with different lengths."); + return -4; + } + } else { + PyErr_SetString(PyExc_ValueError, "Invalid sequence."); + return -6; + } + Py_DECREF(o); + offset += a->strides[dim]; + } + return 0; +} + +static PyObject * +NA_setArrayFromSequence(PyArrayObject *a, PyObject *s) +{ + maybelong shape[MAXDIM]; + + if (!PySequence_Check(s)) + return PyErr_Format( PyExc_TypeError, + "NA_setArrayFromSequence: (array, seq) expected."); + + if (getShape(s, shape, 0) < 0) + return NULL; + + if (!NA_updateDataPtr(a)) + return NULL; + + if (setArrayFromSequence(a, s, 0, 0) < 0) + return NULL; + + Py_INCREF(Py_None); + return Py_None; +} + +enum { + BOOL_SCALAR, + INT_SCALAR, + LONG_SCALAR, + FLOAT_SCALAR, + COMPLEX_SCALAR +}; + + +static int +_NA_maxType(PyObject *seq, int limit) +{ + if (limit > MAXDIM) { + PyErr_Format( PyExc_ValueError, + "NA_maxType: sequence nested too deep." ); + return -1; + } + if (NA_NumArrayCheck(seq)) { + switch(PyArray(seq)->descr->type_num) { + case tBool: + return BOOL_SCALAR; + case tInt8: + case tUInt8: + case tInt16: + case tUInt16: + case tInt32: + case tUInt32: + return INT_SCALAR; + case tInt64: + case tUInt64: + return LONG_SCALAR; + case tFloat32: + case tFloat64: + return FLOAT_SCALAR; + case tComplex32: + case tComplex64: + return COMPLEX_SCALAR; + default: + PyErr_Format(PyExc_TypeError, + "Expecting a python numeric type, got something else."); + return -1; + } + } else if (PySequence_Check(seq) && !PyString_Check(seq)) { + long i, maxtype=BOOL_SCALAR, slen; + + slen = PySequence_Length(seq); + if (slen < 0) return -1; + + if (slen == 0) return INT_SCALAR; + + for(i=0; i<slen; i++) { + long newmax; + PyObject *o = PySequence_GetItem(seq, i); + if (!o) return -1; + newmax = _NA_maxType(o, limit+1); + if (newmax < 0) + return -1; + else if (newmax > maxtype) { + maxtype = newmax; + } + Py_DECREF(o); + } + return maxtype; + } else { +#if PY_VERSION_HEX >= 0x02030000 + if (PyBool_Check(seq)) + return BOOL_SCALAR; + else +#endif + if (PyInt_Check(seq)) + return INT_SCALAR; + else if (PyLong_Check(seq)) + return LONG_SCALAR; + else if (PyFloat_Check(seq)) + return FLOAT_SCALAR; + else if (PyComplex_Check(seq)) + return COMPLEX_SCALAR; + else { + PyErr_Format(PyExc_TypeError, + "Expecting a python numeric type, got something else."); + return -1; + } + } +} + +static int +NA_maxType(PyObject *seq) +{ + int rval; + rval = _NA_maxType(seq, 0); + return rval; +} + +static int +NA_isPythonScalar(PyObject *o) +{ + int rval; + rval = PyInt_Check(o) || + PyLong_Check(o) || + PyFloat_Check(o) || + PyComplex_Check(o) || + (PyString_Check(o) && (PyString_Size(o) == 1)); + return rval; +} + +#if (NPY_SIZEOF_INTP == 8) +#define PlatBigInt PyInt_FromLong +#define PlatBigUInt PyLong_FromUnsignedLong +#else +#define PlatBigInt PyLong_FromLongLong +#define PlatBigUInt PyLong_FromUnsignedLongLong +#endif + + +static PyObject * +NA_getPythonScalar(PyArrayObject *a, long offset) +{ + int type = a->descr->type_num; + PyObject *rval = NULL; + + switch(type) { + case tBool: + case tInt8: + case tUInt8: + case tInt16: + case tUInt16: + case tInt32: { + Int64 v = NA_get_Int64(a, offset); + rval = PyInt_FromLong(v); + break; + } + case tUInt32: { + Int64 v = NA_get_Int64(a, offset); + rval = PlatBigUInt(v); + break; + } + case tInt64: { + Int64 v = NA_get_Int64(a, offset); + rval = PlatBigInt( v); + break; + } + case tUInt64: { + Int64 v = NA_get_Int64(a, offset); + rval = PlatBigUInt( v); + break; + } + case tFloat32: + case tFloat64: { + Float64 v = NA_get_Float64(a, offset); + rval = PyFloat_FromDouble( v ); + break; + } + case tComplex32: + case tComplex64: + { + Complex64 v = NA_get_Complex64(a, offset); + rval = PyComplex_FromDoubles(v.r, v.i); + break; + } + default: + rval = PyErr_Format(PyExc_TypeError, + "NA_getPythonScalar: bad type %d\n", + type); + } + return rval; +} + +static int +NA_overflow(PyArrayObject *a, Float64 v) +{ + if ((a->flags & CHECKOVERFLOW) == 0) return 0; + + switch(a->descr->type_num) { + case tBool: + return 0; + case tInt8: + if ((v < -128) || (v > 127)) goto _fail; + return 0; + case tUInt8: + if ((v < 0) || (v > 255)) goto _fail; + return 0; + case tInt16: + if ((v < -32768) || (v > 32767)) goto _fail; + return 0; + case tUInt16: + if ((v < 0) || (v > 65535)) goto _fail; + return 0; + case tInt32: + if ((v < -2147483648.) || + (v > 2147483647.)) goto _fail; + return 0; + case tUInt32: + if ((v < 0) || (v > 4294967295.)) goto _fail; + return 0; + case tInt64: + if ((v < -9223372036854775808.) || + (v > 9223372036854775807.)) goto _fail; + return 0; + #if HAS_UINT64 + case tUInt64: + if ((v < 0) || + (v > 18446744073709551615.)) goto _fail; + return 0; + #endif + case tFloat32: + if ((v < -FLT_MAX) || (v > FLT_MAX)) goto _fail; + return 0; + case tFloat64: + return 0; + case tComplex32: + if ((v < -FLT_MAX) || (v > FLT_MAX)) goto _fail; + return 0; + case tComplex64: + return 0; + default: + PyErr_Format( PyExc_TypeError, + "Unknown type %d in NA_overflow", + a->descr->type_num ); + PyErr_Print(); + return -1; + } + _fail: + PyErr_Format(PyExc_OverflowError, "value out of range for array"); + return -1; +} + +static int +_setFromPythonScalarCore(PyArrayObject *a, long offset, PyObject*value, int entries) +{ + Int64 v; + if (entries >= 100) { + PyErr_Format(PyExc_RuntimeError, + "NA_setFromPythonScalar: __tonumtype__ conversion chain too long"); + return -1; + } else if (PyInt_Check(value)) { + v = PyInt_AsLong(value); + if (NA_overflow(a, v) < 0) + return -1; + NA_set_Int64(a, offset, v); + } else if (PyLong_Check(value)) { + if (a->descr->type_num == tInt64) { + v = (Int64) PyLong_AsLongLong( value ); + } else if (a->descr->type_num == tUInt64) { + v = (UInt64) PyLong_AsUnsignedLongLong( value ); + } else if (a->descr->type_num == tUInt32) { + v = PyLong_AsUnsignedLong(value); + } else { + v = PyLong_AsLongLong(value); + } + if (PyErr_Occurred()) + return -1; + if (NA_overflow(a, v) < 0) + return -1; + NA_set_Int64(a, offset, v); + } else if (PyFloat_Check(value)) { + Float64 v = PyFloat_AsDouble(value); + if (NA_overflow(a, v) < 0) + return -1; + NA_set_Float64(a, offset, v); + } else if (PyComplex_Check(value)) { + Complex64 vc; + vc.r = PyComplex_RealAsDouble(value); + vc.i = PyComplex_ImagAsDouble(value); + if (NA_overflow(a, vc.r) < 0) + return -1; + if (NA_overflow(a, vc.i) < 0) + return -1; + NA_set_Complex64(a, offset, vc); + } else if (PyObject_HasAttrString(value, "__tonumtype__")) { + int rval; + PyObject *type = NA_typeNoToTypeObject(a->descr->type_num); + if (!type) return -1; + value = PyObject_CallMethod( + value, "__tonumtype__", "(N)", type); + if (!value) return -1; + rval = _setFromPythonScalarCore(a, offset, value, entries+1); + Py_DECREF(value); + return rval; + } else if (PyString_Check(value)) { + long size = PyString_Size(value); + if ((size <= 0) || (size > 1)) { + PyErr_Format( PyExc_ValueError, + "NA_setFromPythonScalar: len(string) must be 1."); + return -1; + } + NA_set_Int64(a, offset, *PyString_AsString(value)); + } else { + PyErr_Format(PyExc_TypeError, + "NA_setFromPythonScalar: bad value type."); + return -1; + } + return 0; +} + +static int +NA_setFromPythonScalar(PyArrayObject *a, long offset, PyObject *value) +{ + if (a->flags & WRITABLE) + return _setFromPythonScalarCore(a, offset, value, 0); + else { + PyErr_Format( + PyExc_ValueError, "NA_setFromPythonScalar: assigment to readonly array buffer"); + return -1; + } +} + + +static int +NA_NDArrayCheck(PyObject *obj) { + return PyArray_Check(obj); +} + +static int +NA_NumArrayCheck(PyObject *obj) { + return PyArray_Check(obj); +} + +static int +NA_ComplexArrayCheck(PyObject *a) +{ + int rval = NA_NumArrayCheck(a); + if (rval > 0) { + PyArrayObject *arr = (PyArrayObject *) a; + switch(arr->descr->type_num) { + case tComplex64: case tComplex32: + return 1; + default: + return 0; + } + } + return rval; +} + +static unsigned long +NA_elements(PyArrayObject *a) +{ + int i; + unsigned long n = 1; + for(i = 0; i<a->nd; i++) + n *= a->dimensions[i]; + return n; +} + +static int +NA_typeObjectToTypeNo(PyObject *typeObj) +{ + PyArray_Descr *dtype; + int i; + if (PyArray_DescrConverter(typeObj, &dtype) == NPY_FAIL) i=-1; + else i=dtype->type_num; + return i; +} + +static int +NA_copyArray(PyArrayObject *to, const PyArrayObject *from) +{ + return PyArray_CopyInto(to, (PyArrayObject *)from); +} + +static PyArrayObject * +NA_copy(PyArrayObject *from) +{ + return (PyArrayObject *)PyArray_NewCopy(from, 0); +} + + +static PyObject * +NA_getType( PyObject *type) +{ + PyArray_Descr *typeobj = NULL; + if (!type && PyArray_DescrConverter(type, &typeobj) == NPY_FAIL) { + PyErr_Format(PyExc_ValueError, "NA_getType: unknown type."); + typeobj = NULL; + } + return (PyObject *)typeobj; +} + + +/* Call a standard "stride" function +** +** Stride functions always take one input and one output array. +** They can handle n-dimensional data with arbitrary strides (of +** either sign) for both the input and output numarray. Typically +** these functions are used to copy data, byteswap, or align data. +** +** +** It expects the following arguments: +** +** Number of iterations for each dimension as a tuple +** Input Buffer Object +** Offset in bytes for input buffer +** Input strides (in bytes) for each dimension as a tuple +** Output Buffer Object +** Offset in bytes for output buffer +** Output strides (in bytes) for each dimension as a tuple +** An integer (Optional), typically the number of bytes to copy per +* element. +** +** Returns None +** +** The arguments expected by the standard stride functions that this +** function calls are: +** +** Number of dimensions to iterate over +** Long int value (from the optional last argument to +** callStrideConvCFunc) +** often unused by the C Function +** An array of long ints. Each is the number of iterations for each +** dimension. NOTE: the previous argument as well as the stride +** arguments are reversed in order with respect to how they are +** used in Python. Fastest changing dimension is the first element +** in the numarray! +** A void pointer to the input data buffer. +** The starting offset for the input data buffer in bytes (long int). +** An array of long int input strides (in bytes) [reversed as with +** the iteration array] +** A void pointer to the output data buffer. +** The starting offset for the output data buffer in bytes (long int). +** An array of long int output strides (in bytes) [also reversed] +*/ + + +static PyObject * +NA_callStrideConvCFuncCore( + PyObject *self, int nshape, maybelong *shape, + PyObject *inbuffObj, long inboffset, + int ninbstrides, maybelong *inbstrides, + PyObject *outbuffObj, long outboffset, + int noutbstrides, maybelong *outbstrides, + long nbytes) +{ + CfuncObject *me = (CfuncObject *) self; + CFUNC_STRIDE_CONV_FUNC funcptr; + void *inbuffer, *outbuffer; + long inbsize, outbsize; + maybelong i, lshape[MAXDIM], in_strides[MAXDIM], out_strides[MAXDIM]; + maybelong shape_0, inbstr_0, outbstr_0; + + if (nshape == 0) { /* handle rank-0 numarray. */ + nshape = 1; + shape = &shape_0; + inbstrides = &inbstr_0; + outbstrides = &outbstr_0; + shape[0] = 1; + inbstrides[0] = outbstrides[0] = 0; + } + + for(i=0; i<nshape; i++) + lshape[i] = shape[nshape-1-i]; + for(i=0; i<nshape; i++) + in_strides[i] = inbstrides[nshape-1-i]; + for(i=0; i<nshape; i++) + out_strides[i] = outbstrides[nshape-1-i]; + + if (!PyObject_IsInstance(self , (PyObject *) &CfuncType) + || me->descr.type != CFUNC_STRIDING) + return PyErr_Format(PyExc_TypeError, + "NA_callStrideConvCFuncCore: problem with cfunc"); + + if ((inbsize = NA_getBufferPtrAndSize(inbuffObj, 1, &inbuffer)) < 0) + return PyErr_Format(_Error, + "%s: Problem with input buffer", me->descr.name); + + if ((outbsize = NA_getBufferPtrAndSize(outbuffObj, 0, &outbuffer)) < 0) + return PyErr_Format(_Error, + "%s: Problem with output buffer (read only?)", + me->descr.name); + + /* Check buffer alignment and bounds */ + if (NA_checkOneStriding(me->descr.name, nshape, lshape, + inboffset, in_strides, inbsize, + (me->descr.sizes[0] == -1) ? + nbytes : me->descr.sizes[0], + me->descr.align) || + NA_checkOneStriding(me->descr.name, nshape, lshape, + outboffset, out_strides, outbsize, + (me->descr.sizes[1] == -1) ? + nbytes : me->descr.sizes[1], + me->descr.align)) + return NULL; + + /* Cast function pointer and perform stride operation */ + funcptr = (CFUNC_STRIDE_CONV_FUNC) me->descr.fptr; + if ((*funcptr)(nshape-1, nbytes, lshape, + inbuffer, inboffset, in_strides, + outbuffer, outboffset, out_strides) == 0) { + Py_INCREF(Py_None); + return Py_None; + } else { + return NULL; + } +} + +static void +NA_stridesFromShape(int nshape, maybelong *shape, maybelong bytestride, + maybelong *strides) +{ + int i; + if (nshape > 0) { + for(i=0; i<nshape; i++) + strides[i] = bytestride; + for(i=nshape-2; i>=0; i--) + strides[i] = strides[i+1]*shape[i+1]; + } +} + +static int +NA_OperatorCheck(PyObject *op) { + return 0; +} + +static int +NA_ConverterCheck(PyObject *op) { + return 0; +} + +static int +NA_UfuncCheck(PyObject *op) { + return 0; +} + +static int +NA_CfuncCheck(PyObject *op) { + return PyObject_TypeCheck(op, &CfuncType); +} + +static int +NA_getByteOffset(PyArrayObject *array, int nindices, maybelong *indices, + long *offset) +{ + return 0; +} + +static int +NA_swapAxes(PyArrayObject *array, int x, int y) +{ + long temp; + + if (((PyObject *) array) == Py_None) return 0; + + if (array->nd < 2) return 0; + + if (x < 0) x += array->nd; + if (y < 0) y += array->nd; + + if ((x < 0) || (x >= array->nd) || + (y < 0) || (y >= array->nd)) { + PyErr_Format(PyExc_ValueError, + "Specified dimension does not exist"); + return -1; + } + + temp = array->dimensions[x]; + array->dimensions[x] = array->dimensions[y]; + array->dimensions[y] = temp; + + temp = array->strides[x]; + array->strides[x] = array->strides[y]; + array->strides[y] = temp; + + PyArray_UpdateFlags(array, NPY_UPDATE_ALL); + + return 0; +} + +static PyObject * +NA_initModuleGlobal(char *modulename, char *globalname) +{ + PyObject *module, *dict, *global = NULL; + module = PyImport_ImportModule(modulename); + if (!module) { + PyErr_Format(PyExc_RuntimeError, + "Can't import '%s' module", + modulename); + goto _exit; + } + dict = PyModule_GetDict(module); + global = PyDict_GetItemString(dict, globalname); + if (!global) { + PyErr_Format(PyExc_RuntimeError, + "Can't find '%s' global in '%s' module.", + globalname, modulename); + goto _exit; + } + Py_DECREF(module); + Py_INCREF(global); + _exit: + return global; +} + +NumarrayType +NA_NumarrayType(PyObject *seq) +{ + int maxtype = NA_maxType(seq); + int rval; + switch(maxtype) { + case BOOL_SCALAR: + rval = tBool; + goto _exit; + case INT_SCALAR: + case LONG_SCALAR: + rval = tLong; /* tLong corresponds to C long int, + not Python long int */ + goto _exit; + case FLOAT_SCALAR: + rval = tFloat64; + goto _exit; + case COMPLEX_SCALAR: + rval = tComplex64; + goto _exit; + default: + PyErr_Format(PyExc_TypeError, + "expecting Python numeric scalar value; got something else."); + rval = -1; + } + _exit: + return rval; +} + +/* ignores bytestride */ +static PyArrayObject * +NA_NewAllFromBuffer(int ndim, maybelong *shape, NumarrayType type, + PyObject *bufferObject, maybelong byteoffset, maybelong bytestride, + int byteorder, int aligned, int writeable) +{ + PyArrayObject *self = NULL; + PyArray_Descr *dtype; + + if (type == tAny) + type = tDefault; + + dtype = PyArray_DescrFromType(type); + if (dtype == NULL) return NULL; + + if (byteorder != NA_ByteOrder()) { + PyArray_Descr *temp; + temp = PyArray_DescrNewByteorder(dtype, PyArray_SWAP); + Py_DECREF(dtype); + if (temp == NULL) return NULL; + dtype = temp; + } + + if (bufferObject == Py_None || bufferObject == NULL) { + self = (PyArrayObject *) \ + PyArray_NewFromDescr(&PyArray_Type, dtype, + ndim, shape, NULL, NULL, + 0, NULL); + } + else { + npy_intp size = 1; + int i; + PyArrayObject *newself; + PyArray_Dims newdims; + for(i=0; i<ndim; i++) { + size *= shape[i]; + } + self = (PyArrayObject *)\ + PyArray_FromBuffer(bufferObject, dtype, + size, byteoffset); + + if (self == NULL) return self; + newdims.len = ndim; + newdims.ptr = shape; + newself = (PyArrayObject *)\ + PyArray_Newshape(self, &newdims, PyArray_CORDER); + Py_DECREF(self); + self = newself; + } + + return self; +} + +static void +NA_updateAlignment(PyArrayObject *self) +{ + PyArray_UpdateFlags(self, NPY_ALIGNED); +} + +static void +NA_updateContiguous(PyArrayObject *self) +{ + PyArray_UpdateFlags(self, NPY_CONTIGUOUS | NPY_FORTRAN); +} + + +static void +NA_updateStatus(PyArrayObject *self) +{ + PyArray_UpdateFlags(self, NPY_UPDATE_ALL); +} + +static int +NA_NumArrayCheckExact(PyObject *op) { + return (op->ob_type == &PyArray_Type); +} + +static int +NA_NDArrayCheckExact(PyObject *op) { + return (op->ob_type == &PyArray_Type); +} + +static int +NA_OperatorCheckExact(PyObject *op) { + return 0; +} + +static int +NA_ConverterCheckExact(PyObject *op) { + return 0; +} + +static int +NA_UfuncCheckExact(PyObject *op) { + return 0; +} + + +static int +NA_CfuncCheckExact(PyObject *op) { + return op->ob_type == &CfuncType; +} + +static char * +NA_getArrayData(PyArrayObject *obj) +{ + if (!NA_NDArrayCheck((PyObject *) obj)) { + PyErr_Format(PyExc_TypeError, + "expected an NDArray"); + } + return obj->data; +} + +/* Byteswap is not a flag of the array --- it is implicit in the data-type */ +static void +NA_updateByteswap(PyArrayObject *self) +{ + return; +} + +static PyArray_Descr * +NA_DescrFromType(int type) +{ + if (type == tAny) + type = tDefault; + return PyArray_DescrFromType(type); +} + +static PyObject * +NA_Cast(PyArrayObject *a, int type) +{ + return PyArray_Cast(a, type); +} + + +/* The following function has much platform dependent code since +** there is no platform-independent way of checking Floating Point +** status bits +*/ + +/* OSF/Alpha (Tru64) ---------------------------------------------*/ +#if defined(__osf__) && defined(__alpha) + +static int +NA_checkFPErrors(void) +{ + unsigned long fpstatus; + int retstatus; + +#include <machine/fpu.h> /* Should migrate to global scope */ + + fpstatus = ieee_get_fp_control(); + /* clear status bits as well as disable exception mode if on */ + ieee_set_fp_control( 0 ); + retstatus = + pyFPE_DIVIDE_BY_ZERO* (int)((IEEE_STATUS_DZE & fpstatus) != 0) + + pyFPE_OVERFLOW * (int)((IEEE_STATUS_OVF & fpstatus) != 0) + + pyFPE_UNDERFLOW * (int)((IEEE_STATUS_UNF & fpstatus) != 0) + + pyFPE_INVALID * (int)((IEEE_STATUS_INV & fpstatus) != 0); + + return retstatus; +} + +/* MS Windows -----------------------------------------------------*/ +#elif defined(_MSC_VER) + +#include <float.h> + +static int +NA_checkFPErrors(void) +{ + int fpstatus = (int) _clear87(); + int retstatus = + pyFPE_DIVIDE_BY_ZERO * ((SW_ZERODIVIDE & fpstatus) != 0) + + pyFPE_OVERFLOW * ((SW_OVERFLOW & fpstatus) != 0) + + pyFPE_UNDERFLOW * ((SW_UNDERFLOW & fpstatus) != 0) + + pyFPE_INVALID * ((SW_INVALID & fpstatus) != 0); + + + return retstatus; +} + +/* Solaris --------------------------------------------------------*/ +/* --------ignoring SunOS ieee_flags approach, someone else can +** deal with that! */ +#elif defined(sun) +#include <ieeefp.h> + +static int +NA_checkFPErrors(void) +{ + int fpstatus; + int retstatus; + + fpstatus = (int) fpgetsticky(); + retstatus = pyFPE_DIVIDE_BY_ZERO * ((FP_X_DZ & fpstatus) != 0) + + pyFPE_OVERFLOW * ((FP_X_OFL & fpstatus) != 0) + + pyFPE_UNDERFLOW * ((FP_X_UFL & fpstatus) != 0) + + pyFPE_INVALID * ((FP_X_INV & fpstatus) != 0); + (void) fpsetsticky(0); + + return retstatus; +} + +#elif defined(__GLIBC__) || defined(__APPLE__) || defined(__CYGWIN__) || defined(__MINGW32__) + +static int +NA_checkFPErrors(void) +{ + int fpstatus = (int) fetestexcept( + FE_DIVBYZERO | FE_OVERFLOW | FE_UNDERFLOW | FE_INVALID); + int retstatus = + pyFPE_DIVIDE_BY_ZERO * ((FE_DIVBYZERO & fpstatus) != 0) + + pyFPE_OVERFLOW * ((FE_OVERFLOW & fpstatus) != 0) + + pyFPE_UNDERFLOW * ((FE_UNDERFLOW & fpstatus) != 0) + + pyFPE_INVALID * ((FE_INVALID & fpstatus) != 0); + (void) feclearexcept(FE_DIVBYZERO | FE_OVERFLOW | + FE_UNDERFLOW | FE_INVALID); + return retstatus; +} + +#else + +static int +NA_checkFPErrors(void) +{ + return 0; +} + +#endif + +static void +NA_clearFPErrors() +{ + NA_checkFPErrors(); +} + +/* Not supported yet */ +static int +NA_checkAndReportFPErrors(char *name) +{ + int error = NA_checkFPErrors(); + if (error) { + PyObject *ans; + char msg[128]; + strcpy(msg, " in "); + strncat(msg, name, 100); + ans = PyObject_CallFunction(pHandleErrorFunc, "(is)", error, msg); + if (!ans) return -1; + Py_DECREF(ans); /* Py_None */ + } + return 0; + +} + + +#define WITHIN32(v, f) (((v) >= f##_MIN32) && ((v) <= f##_MAX32)) +#define WITHIN64(v, f) (((v) >= f##_MIN64) && ((v) <= f##_MAX64)) + +static Bool +NA_IeeeMask32( Float32 f, Int32 mask) +{ + Int32 category; + UInt32 v = *(UInt32 *) &f; + + if (v & BIT(31)) { + if (WITHIN32(v, NEG_NORMALIZED)) { + category = MSK_NEG_NOR; + } else if (WITHIN32(v, NEG_DENORMALIZED)) { + category = MSK_NEG_DEN; + } else if (WITHIN32(v, NEG_SIGNAL_NAN)) { + category = MSK_NEG_SNAN; + } else if (WITHIN32(v, NEG_QUIET_NAN)) { + category = MSK_NEG_QNAN; + } else if (v == NEG_INFINITY_MIN32) { + category = MSK_NEG_INF; + } else if (v == NEG_ZERO_MIN32) { + category = MSK_NEG_ZERO; + } else if (v == INDETERMINATE_MIN32) { + category = MSK_INDETERM; + } else { + category = MSK_BUG; + } + } else { + if (WITHIN32(v, POS_NORMALIZED)) { + category = MSK_POS_NOR; + } else if (WITHIN32(v, POS_DENORMALIZED)) { + category = MSK_POS_DEN; + } else if (WITHIN32(v, POS_SIGNAL_NAN)) { + category = MSK_POS_SNAN; + } else if (WITHIN32(v, POS_QUIET_NAN)) { + category = MSK_POS_QNAN; + } else if (v == POS_INFINITY_MIN32) { + category = MSK_POS_INF; + } else if (v == POS_ZERO_MIN32) { + category = MSK_POS_ZERO; + } else { + category = MSK_BUG; + } + } + return (category & mask) != 0; +} + +static Bool +NA_IeeeMask64( Float64 f, Int32 mask) +{ + Int32 category; + UInt64 v = *(UInt64 *) &f; + + if (v & BIT(63)) { + if (WITHIN64(v, NEG_NORMALIZED)) { + category = MSK_NEG_NOR; + } else if (WITHIN64(v, NEG_DENORMALIZED)) { + category = MSK_NEG_DEN; + } else if (WITHIN64(v, NEG_SIGNAL_NAN)) { + category = MSK_NEG_SNAN; + } else if (WITHIN64(v, NEG_QUIET_NAN)) { + category = MSK_NEG_QNAN; + } else if (v == NEG_INFINITY_MIN64) { + category = MSK_NEG_INF; + } else if (v == NEG_ZERO_MIN64) { + category = MSK_NEG_ZERO; + } else if (v == INDETERMINATE_MIN64) { + category = MSK_INDETERM; + } else { + category = MSK_BUG; + } + } else { + if (WITHIN64(v, POS_NORMALIZED)) { + category = MSK_POS_NOR; + } else if (WITHIN64(v, POS_DENORMALIZED)) { + category = MSK_POS_DEN; + } else if (WITHIN64(v, POS_SIGNAL_NAN)) { + category = MSK_POS_SNAN; + } else if (WITHIN64(v, POS_QUIET_NAN)) { + category = MSK_POS_QNAN; + } else if (v == POS_INFINITY_MIN64) { + category = MSK_POS_INF; + } else if (v == POS_ZERO_MIN64) { + category = MSK_POS_ZERO; + } else { + category = MSK_BUG; + } + } + return (category & mask) != 0; +} + +static PyArrayObject * +NA_FromDimsStridesDescrAndData(int nd, maybelong *d, maybelong *s, PyArray_Descr *descr, char *data) +{ + return (PyArrayObject *)\ + PyArray_NewFromDescr(&PyArray_Type, descr, nd, d, + s, data, 0, NULL); +} + +static PyArrayObject * +NA_FromDimsTypeAndData(int nd, maybelong *d, int type, char *data) +{ + PyArray_Descr *descr = NA_DescrFromType(type); + return NA_FromDimsStridesDescrAndData(nd, d, NULL, descr, data); +} + +static PyArrayObject * +NA_FromDimsStridesTypeAndData(int nd, maybelong *shape, maybelong *strides, + int type, char *data) +{ + PyArray_Descr *descr = NA_DescrFromType(type); + return NA_FromDimsStridesDescrAndData(nd, shape, strides, descr, data); +} + + +typedef struct +{ + NumarrayType type_num; + char suffix[5]; + int itemsize; +} scipy_typestr; + +static scipy_typestr scipy_descriptors[ ] = { + { tAny, ""}, + + { tBool, "b1", 1}, + + { tInt8, "i1", 1}, + { tUInt8, "u1", 1}, + + { tInt16, "i2", 2}, + { tUInt16, "u2", 2}, + + { tInt32, "i4", 4}, + { tUInt32, "u4", 4}, + + { tInt64, "i8", 8}, + { tUInt64, "u8", 8}, + + { tFloat32, "f4", 4}, + { tFloat64, "f8", 8}, + + { tComplex32, "c8", 8}, + { tComplex64, "c16", 16} +}; + + +static int +NA_scipy_typestr(NumarrayType t, int byteorder, char *typestr) +{ + int i; + if (byteorder) + strcpy(typestr, ">"); + else + strcpy(typestr, "<"); + for(i=0; i<ELEM(scipy_descriptors); i++) { + scipy_typestr *ts = &scipy_descriptors[i]; + if (ts->type_num == t) { + strncat(typestr, ts->suffix, 4); + return 0; + } + } + return -1; +} + +static PyArrayObject * +NA_FromArrayStruct(PyObject *obj) +{ + return (PyArrayObject *)PyArray_FromStructInterface(obj); +} + + +static PyObject *_Error; + +void *libnumarray_API[] = { + (void*) getBuffer, + (void*) isBuffer, + (void*) getWriteBufferDataPtr, + (void*) isBufferWriteable, + (void*) getReadBufferDataPtr, + (void*) getBufferSize, + (void*) num_log, + (void*) num_log10, + (void*) num_pow, + (void*) num_acosh, + (void*) num_asinh, + (void*) num_atanh, + (void*) num_round, + (void*) int_dividebyzero_error, + (void*) int_overflow_error, + (void*) umult64_overflow, + (void*) smult64_overflow, + (void*) NA_Done, + (void*) NA_NewAll, + (void*) NA_NewAllStrides, + (void*) NA_New, + (void*) NA_Empty, + (void*) NA_NewArray, + (void*) NA_vNewArray, + (void*) NA_ReturnOutput, + (void*) NA_getBufferPtrAndSize, + (void*) NA_checkIo, + (void*) NA_checkOneCBuffer, + (void*) NA_checkNCBuffers, + (void*) NA_checkOneStriding, + (void*) NA_new_cfunc, + (void*) NA_add_cfunc, + (void*) NA_InputArray, + (void*) NA_OutputArray, + (void*) NA_IoArray, + (void*) NA_OptionalOutputArray, + (void*) NA_get_offset, + (void*) NA_get_Float64, + (void*) NA_set_Float64, + (void*) NA_get_Complex64, + (void*) NA_set_Complex64, + (void*) NA_get_Int64, + (void*) NA_set_Int64, + (void*) NA_get1_Float64, + (void*) NA_get2_Float64, + (void*) NA_get3_Float64, + (void*) NA_set1_Float64, + (void*) NA_set2_Float64, + (void*) NA_set3_Float64, + (void*) NA_get1_Complex64, + (void*) NA_get2_Complex64, + (void*) NA_get3_Complex64, + (void*) NA_set1_Complex64, + (void*) NA_set2_Complex64, + (void*) NA_set3_Complex64, + (void*) NA_get1_Int64, + (void*) NA_get2_Int64, + (void*) NA_get3_Int64, + (void*) NA_set1_Int64, + (void*) NA_set2_Int64, + (void*) NA_set3_Int64, + (void*) NA_get1D_Float64, + (void*) NA_set1D_Float64, + (void*) NA_get1D_Int64, + (void*) NA_set1D_Int64, + (void*) NA_get1D_Complex64, + (void*) NA_set1D_Complex64, + (void*) NA_ShapeEqual, + (void*) NA_ShapeLessThan, + (void*) NA_ByteOrder, + (void*) NA_IeeeSpecial32, + (void*) NA_IeeeSpecial64, + (void*) NA_updateDataPtr, + (void*) NA_typeNoToName, + (void*) NA_nameToTypeNo, + (void*) NA_typeNoToTypeObject, + (void*) NA_intTupleFromMaybeLongs, + (void*) NA_maybeLongsFromIntTuple, + (void*) NA_intTupleProduct, + (void*) NA_isIntegerSequence, + (void*) NA_setArrayFromSequence, + (void*) NA_maxType, + (void*) NA_isPythonScalar, + (void*) NA_getPythonScalar, + (void*) NA_setFromPythonScalar, + (void*) NA_NDArrayCheck, + (void*) NA_NumArrayCheck, + (void*) NA_ComplexArrayCheck, + (void*) NA_elements, + (void*) NA_typeObjectToTypeNo, + (void*) NA_copyArray, + (void*) NA_copy, + (void*) NA_getType, + (void*) NA_callCUFuncCore, + (void*) NA_callStrideConvCFuncCore, + (void*) NA_stridesFromShape, + (void*) NA_OperatorCheck, + (void*) NA_ConverterCheck, + (void*) NA_UfuncCheck, + (void*) NA_CfuncCheck, + (void*) NA_getByteOffset, + (void*) NA_swapAxes, + (void*) NA_initModuleGlobal, + (void*) NA_NumarrayType, + (void*) NA_NewAllFromBuffer, + (void*) NA_alloc1D_Float64, + (void*) NA_alloc1D_Int64, + (void*) NA_updateAlignment, + (void*) NA_updateContiguous, + (void*) NA_updateStatus, + (void*) NA_NumArrayCheckExact, + (void*) NA_NDArrayCheckExact, + (void*) NA_OperatorCheckExact, + (void*) NA_ConverterCheckExact, + (void*) NA_UfuncCheckExact, + (void*) NA_CfuncCheckExact, + (void*) NA_getArrayData, + (void*) NA_updateByteswap, + (void*) NA_DescrFromType, + (void*) NA_Cast, + (void*) NA_checkFPErrors, + (void*) NA_clearFPErrors, + (void*) NA_checkAndReportFPErrors, + (void*) NA_IeeeMask32, + (void*) NA_IeeeMask64, + (void*) _NA_callStridingHelper, + (void*) NA_FromDimsStridesDescrAndData, + (void*) NA_FromDimsTypeAndData, + (void*) NA_FromDimsStridesTypeAndData, + (void*) NA_scipy_typestr, + (void*) NA_FromArrayStruct +}; + +#if (!defined(METHOD_TABLE_EXISTS)) +static PyMethodDef _libnumarrayMethods[] = { + {NULL, NULL} /* Sentinel */ +}; +#endif + +/* boiler plate API init */ +PyMODINIT_FUNC init_capi(void) +{ + PyObject *m = Py_InitModule("_capi", _libnumarrayMethods); + PyObject *c_api_object; + + _Error = PyErr_NewException("numpy.numarray._capi.error", NULL, NULL); + + /* Create a CObject containing the API pointer array's address */ + c_api_object = PyCObject_FromVoidPtr((void *)libnumarray_API, NULL); + + if (c_api_object != NULL) { + /* Create a name for this object in the module's namespace */ + PyObject *d = PyModule_GetDict(m); + + PyDict_SetItemString(d, "_C_API", c_api_object); + PyDict_SetItemString(d, "error", _Error); + Py_DECREF(c_api_object); + } else { + return; + } + if (PyModule_AddObject(m, "__version__", + PyString_FromString("0.9")) < 0) return; + + if (_import_array() < 0) return; + deferred_libnumarray_init(); + return; +} + + diff --git a/numpy/numarray/alter_code1.py b/numpy/numarray/alter_code1.py new file mode 100644 index 000000000..ae950e7e0 --- /dev/null +++ b/numpy/numarray/alter_code1.py @@ -0,0 +1,265 @@ +""" +This module converts code written for numarray to run with numpy + +Makes the following changes: + * Changes import statements + + import numarray.package + --> import numpy.numarray.package as numarray_package + with all numarray.package in code changed to numarray_package + + import numarray --> import numpy.numarray as numarray + import numarray.package as <yyy> --> import numpy.numarray.package as <yyy> + + from numarray import <xxx> --> from numpy.numarray import <xxx> + from numarray.package import <xxx> + --> from numpy.numarray.package import <xxx> + + package can be convolve, image, nd_image, mlab, linear_algebra, ma, + matrix, fft, random_array + + + * Makes search and replace changes to: + - .imaginary --> .imag + - .flat --> .ravel() (most of the time) + - .byteswapped() --> .byteswap(False) + - .byteswap() --> .byteswap(True) + - .info() --> numarray.info(self) + - .isaligned() --> .flags.aligned + - .isbyteswapped() --> (not .dtype.isnative) + - .typecode() --> .dtype.char + - .iscontiguous() --> .flags.contiguous + - .is_c_array() --> .flags.carray and .dtype.isnative + - .is_fortran_contiguous() --> .flags.fortran + - .is_f_array() --> .dtype.isnative and .flags.farray + - .itemsize() --> .itemsize + - .nelements() --> .size + - self.new(type) --> numarray.newobj(self, type) + - .repeat(r) --> .repeat(r, axis=0) + - .size() --> .size + - self.type() -- numarray.typefrom(self) + - .typecode() --> .dtype.char + - .stddev() --> .std() + - .togglebyteorder() --> numarray.togglebyteorder(self) + - .getshape() --> .shape + - .setshape(obj) --> .shape=obj + - .getflat() --> .ravel() + - .getreal() --> .real + - .setreal() --> .real = + - .getimag() --> .imag + - .setimag() --> .imag = + - .getimaginary() --> .imag + - .setimaginary() --> .imag + +""" +__all__ = ['convertfile', 'convertall', 'converttree', 'convertsrc'] + +import sys +import os +import re +import glob + +def changeimports(fstr, name, newname): + importstr = 'import %s' % name + importasstr = 'import %s as ' % name + fromstr = 'from %s import ' % name + fromall=0 + + name_ = name + if ('.' in name): + name_ = name.replace('.','_') + + fstr = re.sub(r'(import\s+[^,\n\r]+,\s*)(%s)' % name, + "\\1%s as %s" % (newname, name), fstr) + fstr = fstr.replace(importasstr, 'import %s as ' % newname) + fstr = fstr.replace(importstr, 'import %s as %s' % (newname,name_)) + if (name_ != name): + fstr = fstr.replace(name, name_) + + ind = 0 + Nlen = len(fromstr) + Nlen2 = len("from %s import " % newname) + while 1: + found = fstr.find(fromstr,ind) + if (found < 0): + break + ind = found + Nlen + if fstr[ind] == '*': + continue + fstr = "%sfrom %s import %s" % (fstr[:found], newname, fstr[ind:]) + ind += Nlen2 - Nlen + return fstr, fromall + +flatindex_re = re.compile('([.]flat(\s*?[[=]))') + + +def addimport(astr): + # find the first line with import on it + ind = astr.find('import') + start = astr.rfind(os.linesep, 0, ind) + astr = "%s%s%s%s" % (astr[:start], os.linesep, + "import numpy.numarray as numarray", + astr[start:]) + return astr + +def replaceattr(astr): + astr = astr.replace(".imaginary", ".imag") + astr = astr.replace(".byteswapped()",".byteswap(False)") + astr = astr.replace(".byteswap()", ".byteswap(True)") + astr = astr.replace(".isaligned()", ".flags.aligned") + astr = astr.replace(".iscontiguous()",".flags.contiguous") + astr = astr.replace(".is_fortran_contiguous()",".flags.fortran") + astr = astr.replace(".itemsize()",".itemsize") + astr = astr.replace(".size()",".size") + astr = astr.replace(".nelements()",".size") + astr = astr.replace(".typecode()",".dtype.char") + astr = astr.replace(".stddev()",".std()") + astr = astr.replace(".getshape()", ".shape") + astr = astr.replace(".getflat()", ".ravel()") + astr = astr.replace(".getreal", ".real") + astr = astr.replace(".getimag", ".imag") + astr = astr.replace(".getimaginary", ".imag") + + # preserve uses of flat that should be o.k. + tmpstr = flatindex_re.sub(r"@@@@\2",astr) + # replace other uses of flat + tmpstr = tmpstr.replace(".flat",".ravel()") + # put back .flat where it was valid + astr = tmpstr.replace("@@@@", ".flat") + return astr + +info_re = re.compile(r'(\S+)\s*[.]\s*info\s*[(]\s*[)]') +new_re = re.compile(r'(\S+)\s*[.]\s*new\s*[(]\s*(\S+)\s*[)]') +toggle_re = re.compile(r'(\S+)\s*[.]\s*togglebyteorder\s*[(]\s*[)]') +type_re = re.compile(r'(\S+)\s*[.]\s*type\s*[(]\s*[)]') + +isbyte_re = re.compile(r'(\S+)\s*[.]\s*isbyteswapped\s*[(]\s*[)]') +iscarr_re = re.compile(r'(\S+)\s*[.]\s*is_c_array\s*[(]\s*[)]') +isfarr_re = re.compile(r'(\S+)\s*[.]\s*is_f_array\s*[(]\s*[)]') +repeat_re = re.compile(r'(\S+)\s*[.]\s*repeat\s*[(]\s*(\S+)\s*[)]') + +setshape_re = re.compile(r'(\S+)\s*[.]\s*setshape\s*[(]\s*(\S+)\s*[)]') +setreal_re = re.compile(r'(\S+)\s*[.]\s*setreal\s*[(]\s*(\S+)\s*[)]') +setimag_re = re.compile(r'(\S+)\s*[.]\s*setimag\s*[(]\s*(\S+)\s*[)]') +setimaginary_re = re.compile(r'(\S+)\s*[.]\s*setimaginary\s*[(]\s*(\S+)\s*[)]') +def replaceother(astr): + # self.info() --> numarray.info(self) + # self.new(type) --> numarray.newobj(self, type) + # self.togglebyteorder() --> numarray.togglebyteorder(self) + # self.type() --> numarray.typefrom(self) + (astr, n1) = info_re.subn('numarray.info(\\1)', astr) + (astr, n2) = new_re.subn('numarray.newobj(\\1, \\2)', astr) + (astr, n3) = toggle_re.subn('numarray.togglebyteorder(\\1)', astr) + (astr, n4) = type_re.subn('numarray.typefrom(\\1)', astr) + if (n1+n2+n3+n4 > 0): + astr = addimport(astr) + + astr = isbyte_re.sub('not \\1.dtype.isnative', astr) + astr = iscarr_re.sub('\\1.dtype.isnative and \\1.flags.carray', astr) + astr = isfarr_re.sub('\\1.dtype.isnative and \\1.flags.farray', astr) + astr = repeat_re.sub('\\1.repeat(\\2, axis=0)', astr) + astr = setshape_re.sub('\\1.shape = \\2', astr) + astr = setreal_re.sub('\\1.real = \\2', astr) + astr = setimag_re.sub('\\1.imag = \\2', astr) + astr = setimaginary_re.sub('\\1.imag = \\2', astr) + return astr + +import datetime +def fromstr(filestr): + savestr = filestr[:] + filestr, fromall = changeimports(filestr, 'numarray', 'numpy.numarray') + base = 'numarray' + newbase = 'numpy.numarray' + for sub in ['', 'convolve', 'image', 'nd_image', 'mlab', 'linear_algebra', + 'ma', 'matrix', 'fft', 'random_array']: + if sub != '': + sub = '.'+sub + filestr, fromall = changeimports(filestr, base+sub, newbase+sub) + + filestr = replaceattr(filestr) + filestr = replaceother(filestr) + if savestr != filestr: + name = os.path.split(sys.argv[0])[-1] + today = datetime.date.today().strftime('%b %d, %Y') + filestr = '## Automatically adapted for '\ + 'numpy.numarray %s by %s\n\n%s' % (today, name, filestr) + return filestr, 1 + return filestr, 0 + +def makenewfile(name, filestr): + fid = file(name, 'w') + fid.write(filestr) + fid.close() + +def convertfile(filename, orig=1): + """Convert the filename given from using Numarray to using NumPy + + Copies the file to filename.orig and then over-writes the file + with the updated code + """ + fid = open(filename) + filestr = fid.read() + fid.close() + filestr, changed = fromstr(filestr) + if changed: + if orig: + base, ext = os.path.splitext(filename) + os.rename(filename, base+".orig") + else: + os.remove(filename) + makenewfile(filename, filestr) + +def fromargs(args): + filename = args[1] + convertfile(filename) + +def convertall(direc=os.path.curdir, orig=1): + """Convert all .py files to use numpy.oldnumeric (from Numeric) in the directory given + + For each file, a backup of <usesnumeric>.py is made as + <usesnumeric>.py.orig. A new file named <usesnumeric>.py + is then written with the updated code. + """ + files = glob.glob(os.path.join(direc,'*.py')) + for afile in files: + if afile[-8:] == 'setup.py': continue + convertfile(afile, orig) + +header_re = re.compile(r'(numarray/libnumarray.h)') + +def convertsrc(direc=os.path.curdir, ext=None, orig=1): + """Replace Numeric/arrayobject.h with numpy/oldnumeric.h in all files in the + directory with extension give by list ext (if ext is None, then all files are + replaced).""" + if ext is None: + files = glob.glob(os.path.join(direc,'*')) + else: + files = [] + for aext in ext: + files.extend(glob.glob(os.path.join(direc,"*.%s" % aext))) + for afile in files: + fid = open(afile) + fstr = fid.read() + fid.close() + fstr, n = header_re.subn(r'numpy/libnumarray.h',fstr) + if n > 0: + if orig: + base, ext = os.path.splitext(afile) + os.rename(afile, base+".orig") + else: + os.remove(afile) + makenewfile(afile, fstr) + +def _func(arg, dirname, fnames): + convertall(dirname, orig=0) + convertsrc(dirname, ['h','c'], orig=0) + +def converttree(direc=os.path.curdir): + """Convert all .py files in the tree given + + """ + os.path.walk(direc, _func, None) + + +if __name__ == '__main__': + converttree(sys.argv) diff --git a/numpy/numarray/alter_code2.py b/numpy/numarray/alter_code2.py new file mode 100644 index 000000000..87ec5aa07 --- /dev/null +++ b/numpy/numarray/alter_code2.py @@ -0,0 +1,70 @@ +""" +This module converts code written for numpy.numarray to work +with numpy + +FIXME: finish this. + +""" +#__all__ = ['convertfile', 'convertall', 'converttree'] +__all__ = [] + +import warnings +warnings.warn("numpy.numarray.alter_code2 is not working yet.") +import sys + + +import os +import re +import glob + + +def makenewfile(name, filestr): + fid = file(name, 'w') + fid.write(filestr) + fid.close() + +def getandcopy(name): + fid = file(name) + filestr = fid.read() + fid.close() + base, ext = os.path.splitext(name) + makenewfile(base+'.orig', filestr) + return filestr + +def convertfile(filename): + """Convert the filename given from using Numeric to using NumPy + + Copies the file to filename.orig and then over-writes the file + with the updated code + """ + filestr = getandcopy(filename) + filestr = fromstr(filestr) + makenewfile(filename, filestr) + +def fromargs(args): + filename = args[1] + convertfile(filename) + +def convertall(direc=os.path.curdir): + """Convert all .py files to use NumPy (from Numeric) in the directory given + + For each file, a backup of <usesnumeric>.py is made as + <usesnumeric>.py.orig. A new file named <usesnumeric>.py + is then written with the updated code. + """ + files = glob.glob(os.path.join(direc,'*.py')) + for afile in files: + convertfile(afile) + +def _func(arg, dirname, fnames): + convertall(dirname) + +def converttree(direc=os.path.curdir): + """Convert all .py files in the tree given + + """ + os.path.walk(direc, _func, None) + + +if __name__ == '__main__': + fromargs(sys.argv) diff --git a/numpy/numarray/compat.py b/numpy/numarray/compat.py new file mode 100644 index 000000000..e0d13a7c2 --- /dev/null +++ b/numpy/numarray/compat.py @@ -0,0 +1,4 @@ + +__all__ = ['NewAxis', 'ArrayType'] + +from numpy import newaxis as NewAxis, ndarray as ArrayType diff --git a/numpy/numarray/convolve.py b/numpy/numarray/convolve.py new file mode 100644 index 000000000..68a4730a1 --- /dev/null +++ b/numpy/numarray/convolve.py @@ -0,0 +1,14 @@ +try: + from stsci.convolve import * +except ImportError: + try: + from scipy.stsci.convolve import * + except ImportError: + msg = \ +"""The convolve package is not installed. + +It can be downloaded by checking out the latest source from +http://svn.scipy.org/svn/scipy/trunk/Lib/stsci or by downloading and +installing all of SciPy from http://www.scipy.org. +""" + raise ImportError(msg) diff --git a/numpy/numarray/fft.py b/numpy/numarray/fft.py new file mode 100644 index 000000000..c7ac6a27e --- /dev/null +++ b/numpy/numarray/fft.py @@ -0,0 +1,7 @@ + +from numpy.oldnumeric.fft import * +import numpy.oldnumeric.fft as nof + +__all__ = nof.__all__ + +del nof diff --git a/numpy/numarray/functions.py b/numpy/numarray/functions.py new file mode 100644 index 000000000..afb5ce875 --- /dev/null +++ b/numpy/numarray/functions.py @@ -0,0 +1,490 @@ +# missing Numarray defined names (in from numarray import *) +##__all__ = ['ClassicUnpickler', 'Complex32_fromtype', +## 'Complex64_fromtype', 'ComplexArray', 'Error', +## 'MAX_ALIGN', 'MAX_INT_SIZE', 'MAX_LINE_WIDTH', +## 'NDArray', 'NewArray', 'NumArray', +## 'NumError', 'PRECISION', 'Py2NumType', +## 'PyINT_TYPES', 'PyLevel2Type', 'PyNUMERIC_TYPES', 'PyREAL_TYPES', +## 'SUPPRESS_SMALL', +## 'SuitableBuffer', 'USING_BLAS', +## 'UsesOpPriority', +## 'codegenerator', 'generic', 'libnumarray', 'libnumeric', +## 'make_ufuncs', 'memory', +## 'numarrayall', 'numarraycore', 'numinclude', 'safethread', +## 'typecode', 'typecodes', 'typeconv', 'ufunc', 'ufuncFactory', +## 'ieeemask'] + +__all__ = ['asarray', 'ones', 'zeros', 'array', 'where'] +__all__ += ['vdot', 'dot', 'matrixmultiply', 'ravel', 'indices', + 'arange', 'concatenate', 'all', 'allclose', 'alltrue', 'and_', + 'any', 'argmax', 'argmin', 'argsort', 'around', 'array_equal', + 'array_equiv', 'arrayrange', 'array_str', 'array_repr', + 'array2list', 'average', 'choose', 'CLIP', 'RAISE', 'WRAP', + 'clip', 'compress', 'concatenate', 'copy', 'copy_reg', + 'diagonal', 'divide_remainder', 'e', 'explicit_type', 'pi', + 'flush_caches', 'fromfile', 'os', 'sys', 'STRICT', + 'SLOPPY', 'WARN', 'EarlyEOFError', 'SizeMismatchError', + 'SizeMismatchWarning', 'FileSeekWarning', 'fromstring', + 'fromfunction', 'fromlist', 'getShape', 'getTypeObject', + 'identity', 'indices', 'info', 'innerproduct', 'inputarray', + 'isBigEndian', 'kroneckerproduct', 'lexsort', 'math', + 'operator', 'outerproduct', 'put', 'putmask', 'rank', + 'repeat', 'reshape', 'resize', 'round', 'searchsorted', + 'shape', 'size', 'sometrue', 'sort', 'swapaxes', 'take', + 'tcode', 'tname', 'tensormultiply', 'trace', 'transpose', + 'types', 'value', 'cumsum', 'cumproduct', 'nonzero', 'newobj', + 'togglebyteorder' + ] + +import copy, copy_reg, types +import os, sys, math, operator + +from numpy import dot as matrixmultiply, dot, vdot, ravel, concatenate, all,\ + allclose, any, around, argsort, array_equal, array_equiv,\ + array_str, array_repr, CLIP, RAISE, WRAP, clip, concatenate, \ + diagonal, e, pi, indices, inner as innerproduct, nonzero, \ + outer as outerproduct, kron as kroneckerproduct, lexsort, putmask, rank, \ + resize, searchsorted, shape, size, sort, swapaxes, trace, transpose +import numpy as N + +from numerictypes import typefrom + +isBigEndian = sys.byteorder != 'little' +value = tcode = 'f' +tname = 'Float32' + +# If dtype is not None, then it is used +# If type is not None, then it is used +# If typecode is not None then it is used +# If use_default is True, then the default +# data-type is returned if all are None +def type2dtype(typecode, type, dtype, use_default=True): + if dtype is None: + if type is None: + if use_default or typecode is not None: + dtype = N.dtype(typecode) + else: + dtype = N.dtype(type) + if use_default and dtype is None: + dtype = N.dtype('int') + return dtype + +def fromfunction(shape, dimensions, type=None, typecode=None, dtype=None): + dtype = type2dtype(typecode, type, dtype, 1) + return N.fromfunction(shape, dimensions, dtype=dtype) +def ones(shape, type=None, typecode=None, dtype=None): + dtype = type2dtype(typecode, type, dtype, 1) + return N.ones(shape, dtype) + +def zeros(shape, type=None, typecode=None, dtype=None): + dtype = type2dtype(typecode, type, dtype, 1) + return N.zeros(shape, dtype) + +def where(condition, x=None, y=None, out=None): + if x is None and y is None: + arr = N.where(condition) + else: + arr = N.where(condition, x, y) + if out is not None: + out[...] = arr + return out + return arr + +def indices(shape, type=None): + return N.indices(shape, type) + +def arange(a1, a2=None, stride=1, type=None, shape=None, + typecode=None, dtype=None): + dtype = type2dtype(typecode, type, dtype, 0) + return N.arange(a1, a2, stride, dtype) + +arrayrange = arange + +def alltrue(x, axis=0): + return N.alltrue(x, axis) + +def and_(a, b): + """Same as a & b + """ + return a & b + +def divide_remainder(a, b): + a, b = asarray(a), asarray(b) + return (a/b,a%b) + +def around(array, digits=0, output=None): + ret = N.around(array, digits, output) + if output is None: + return ret + return + +def array2list(arr): + return arr.tolist() + + +def choose(selector, population, outarr=None, clipmode=RAISE): + a = N.asarray(selector) + ret = a.choose(population, out=outarr, mode=clipmode) + if outarr is None: + return ret + return + +def compress(condition, a, axis=0): + return N.compress(condition, a, axis) + +# only returns a view +def explicit_type(a): + x = a.view() + return x + +# stub +def flush_caches(): + pass + + +class EarlyEOFError(Exception): + "Raised in fromfile() if EOF unexpectedly occurs." + pass + +class SizeMismatchError(Exception): + "Raised in fromfile() if file size does not match shape." + pass + +class SizeMismatchWarning(Warning): + "Issued in fromfile() if file size does not match shape." + pass + +class FileSeekWarning(Warning): + "Issued in fromfile() if there is unused data and seek() fails" + pass + + +STRICT, SLOPPY, WARN = range(3) + +_BLOCKSIZE=1024 + +# taken and adapted directly from numarray +def fromfile(infile, type=None, shape=None, sizing=STRICT, + typecode=None, dtype=None): + if isinstance(infile, (str, unicode)): + infile = open(infile, 'rb') + dtype = type2dtype(typecode, type, dtype, True) + if shape is None: + shape = (-1,) + if not isinstance(shape, tuple): + shape = (shape,) + + if (list(shape).count(-1)>1): + raise ValueError("At most one unspecified dimension in shape") + + if -1 not in shape: + if sizing != STRICT: + raise ValueError("sizing must be STRICT if size complete") + arr = N.empty(shape, dtype) + bytesleft=arr.nbytes + bytesread=0 + while(bytesleft > _BLOCKSIZE): + data = infile.read(_BLOCKSIZE) + if len(data) != _BLOCKSIZE: + raise EarlyEOFError("Unexpected EOF reading data for size complete array") + arr.data[bytesread:bytesread+_BLOCKSIZE]=data + bytesread += _BLOCKSIZE + bytesleft -= _BLOCKSIZE + if bytesleft > 0: + data = infile.read(bytesleft) + if len(data) != bytesleft: + raise EarlyEOFError("Unexpected EOF reading data for size complete array") + arr.data[bytesread:bytesread+bytesleft]=data + return arr + + + ##shape is incompletely specified + ##read until EOF + ##implementation 1: naively use memory blocks + ##problematic because memory allocation can be double what is + ##necessary (!) + + ##the most common case, namely reading in data from an unchanging + ##file whose size may be determined before allocation, should be + ##quick -- only one allocation will be needed. + + recsize = dtype.itemsize * N.product([i for i in shape if i != -1]) + blocksize = max(_BLOCKSIZE/recsize, 1)*recsize + + ##try to estimate file size + try: + curpos=infile.tell() + infile.seek(0,2) + endpos=infile.tell() + infile.seek(curpos) + except (AttributeError, IOError): + initsize=blocksize + else: + initsize=max(1,(endpos-curpos)/recsize)*recsize + + buf = N.newbuffer(initsize) + + bytesread=0 + while 1: + data=infile.read(blocksize) + if len(data) != blocksize: ##eof + break + ##do we have space? + if len(buf) < bytesread+blocksize: + buf=_resizebuf(buf,len(buf)+blocksize) + ## or rather a=resizebuf(a,2*len(a)) ? + assert len(buf) >= bytesread+blocksize + buf[bytesread:bytesread+blocksize]=data + bytesread += blocksize + + if len(data) % recsize != 0: + if sizing == STRICT: + raise SizeMismatchError("Filesize does not match specified shape") + if sizing == WARN: + _warnings.warn("Filesize does not match specified shape", + SizeMismatchWarning) + try: + infile.seek(-(len(data) % recsize),1) + except AttributeError: + _warnings.warn("Could not rewind (no seek support)", + FileSeekWarning) + except IOError: + _warnings.warn("Could not rewind (IOError in seek)", + FileSeekWarning) + datasize = (len(data)/recsize) * recsize + if len(buf) != bytesread+datasize: + buf=_resizebuf(buf,bytesread+datasize) + buf[bytesread:bytesread+datasize]=data[:datasize] + ##deduce shape from len(buf) + shape = list(shape) + uidx = shape.index(-1) + shape[uidx]=len(buf) / recsize + + a = N.ndarray(shape=shape, dtype=type, buffer=buf) + if a.dtype.char == '?': + N.not_equal(a, 0, a) + return a + +def fromstring(datastring, type=None, shape=None, typecode=None, dtype=None): + dtype = type2dtype(typecode, type, dtype, True) + if shape is None: + count = -1 + else: + count = N.product(shape) + res = N.fromstring(datastring, dtype=dtype, count=count) + if shape is not None: + res.shape = shape + return res + + +# check_overflow is ignored +def fromlist(seq, type=None, shape=None, check_overflow=0, typecode=None, dtype=None): + dtype = type2dtype(typecode, type, dtype, False) + return N.array(seq, dtype) + +def array(sequence=None, typecode=None, copy=1, savespace=0, + type=None, shape=None, dtype=None): + dtype = type2dtype(typecode, type, dtype, 0) + if sequence is None: + if shape is None: + return None + if dtype is None: + dtype = 'l' + return N.empty(shape, dtype) + if isinstance(sequence, file): + return fromfile(sequence, dtype=dtype, shape=shape) + if isinstance(sequence, str): + return fromstring(sequence, dtype=dtype, shape=shape) + if isinstance(sequence, buffer): + arr = N.frombuffer(sequence, dtype=dtype) + else: + arr = N.array(sequence, dtype, copy=copy) + if shape is not None: + arr.shape = shape + return arr + +def asarray(seq, type=None, typecode=None, dtype=None): + if isinstance(seq, N.ndarray) and type is None and \ + typecode is None and dtype is None: + return seq + return array(seq, type=type, typecode=typecode, copy=0, dtype=dtype) + +inputarray = asarray + + +def getTypeObject(sequence, type): + if type is not None: + return type + try: + return typefrom(N.array(sequence)) + except: + raise TypeError("Can't determine a reasonable type from sequence") + +def getShape(shape, *args): + try: + if shape is () and not args: + return () + if len(args) > 0: + shape = (shape, ) + args + else: + shape = tuple(shape) + dummy = N.array(shape) + if not issubclass(dummy.dtype.type, N.integer): + raise TypeError + if len(dummy) > N.MAXDIMS: + raise TypeError + except: + raise TypeError("Shape must be a sequence of integers") + return shape + + +def identity(n, type=None, typecode=None, dtype=None): + dtype = type2dtype(typecode, type, dtype, True) + return N.identity(n, dtype) + +def info(obj, output=sys.stdout, numpy=0): + if numpy: + bp = lambda x: x + else: + bp = lambda x: int(x) + cls = getattr(obj, '__class__', type(obj)) + if numpy: + nm = getattr(cls, '__name__', cls) + else: + nm = cls + print >> output, "class: ", nm + print >> output, "shape: ", obj.shape + strides = obj.strides + print >> output, "strides: ", strides + if not numpy: + print >> output, "byteoffset: 0" + if len(strides) > 0: + bs = obj.strides[0] + else: + bs = obj.itemsize + print >> output, "bytestride: ", bs + print >> output, "itemsize: ", obj.itemsize + print >> output, "aligned: ", bp(obj.flags.aligned) + print >> output, "contiguous: ", bp(obj.flags.contiguous) + if numpy: + print >> output, "fortran: ", obj.flags.fortran + if not numpy: + print >> output, "buffer: ", repr(obj.data) + if not numpy: + extra = " (DEBUG ONLY)" + tic = "'" + else: + extra = "" + tic = "" + print >> output, "data pointer: %s%s" % (hex(obj.ctypes._as_parameter_), extra) + print >> output, "byteorder: ", + endian = obj.dtype.byteorder + if endian in ['|','=']: + print >> output, "%s%s%s" % (tic, sys.byteorder, tic) + byteswap = False + elif endian == '>': + print >> output, "%sbig%s" % (tic, tic) + byteswap = sys.byteorder != "big" + else: + print >> output, "%slittle%s" % (tic, tic) + byteswap = sys.byteorder != "little" + print >> output, "byteswap: ", bp(byteswap) + if not numpy: + print >> output, "type: ", typefrom(obj).name + else: + print >> output, "type: %s" % obj.dtype + +#clipmode is ignored if axis is not 0 and array is not 1d +def put(array, indices, values, axis=0, clipmode=RAISE): + if not isinstance(array, N.ndarray): + raise TypeError("put only works on subclass of ndarray") + work = asarray(array) + if axis == 0: + if array.ndim == 1: + work.put(indices, values, clipmode) + else: + work[indices] = values + elif isinstance(axis, (int, long, N.integer)): + work = work.swapaxes(0, axis) + work[indices] = values + work = work.swapaxes(0, axis) + else: + def_axes = range(work.ndim) + for x in axis: + def_axes.remove(x) + axis = list(axis)+def_axes + work = work.transpose(axis) + work[indices] = values + work = work.transpose(axis) + +def repeat(array, repeats, axis=0): + return N.repeat(array, repeats, axis) + + +def reshape(array, shape, *args): + if len(args) > 0: + shape = (shape,) + args + return N.reshape(array, shape) + + +import warnings as _warnings +def round(*args, **keys): + _warnings.warn("round() is deprecated. Switch to around()", + DeprecationWarning) + return around(*args, **keys) + +def sometrue(array, axis=0): + return N.sometrue(array, axis) + +#clipmode is ignored if axis is not an integer +def take(array, indices, axis=0, outarr=None, clipmode=RAISE): + array = N.asarray(array) + if isinstance(axis, (int, long, N.integer)): + res = array.take(indices, axis, outarr, clipmode) + if outarr is None: + return res + return + else: + def_axes = range(array.ndim) + for x in axis: + def_axes.remove(x) + axis = list(axis) + def_axes + work = array.transpose(axis) + res = work[indices] + if outarr is None: + return res + out[...] = res + return + +def tensormultiply(a1, a2): + a1, a2 = N.asarray(a1), N.asarray(a2) + if (a1.shape[-1] != a2.shape[0]): + raise ValueError("Unmatched dimensions") + shape = a1.shape[:-1] + a2.shape[1:] + return N.reshape(dot(N.reshape(a1, (-1, a1.shape[-1])), + N.reshape(a2, (a2.shape[0],-1))), + shape) + +def cumsum(a1, axis=0, out=None, type=None, dim=0): + return N.asarray(a1).cumsum(axis,dtype=type,out=out) + +def cumproduct(a1, axis=0, out=None, type=None, dim=0): + return N.asarray(a1).cumprod(axis,dtype=type,out=out) + +def argmax(x, axis=-1): + return N.argmax(x, axis) + +def argmin(x, axis=-1): + return N.argmin(x, axis) + +def newobj(self, type): + if type is None: + return N.empty_like(self) + else: + return N.empty(self.shape, type) + +def togglebyteorder(self): + self.dtype=self.dtype.newbyteorder() + +def average(a, axis=0, weights=None, returned=0): + return N.average(a, axis, weights, returned) diff --git a/numpy/numarray/image.py b/numpy/numarray/image.py new file mode 100644 index 000000000..e24326f79 --- /dev/null +++ b/numpy/numarray/image.py @@ -0,0 +1,15 @@ +try: + from stsci.image import * +except ImportError: + try: + from scipy.stsci.image import * + except ImportError: + msg = \ +"""The image package is not installed + +It can be downloaded by checking out the latest source from +http://svn.scipy.org/svn/scipy/trunk/Lib/stsci or by downloading and +installing all of SciPy from http://www.scipy.org. +""" + raise ImportError(msg) + diff --git a/numpy/numarray/linear_algebra.py b/numpy/numarray/linear_algebra.py new file mode 100644 index 000000000..238dff952 --- /dev/null +++ b/numpy/numarray/linear_algebra.py @@ -0,0 +1,15 @@ + +from numpy.oldnumeric.linear_algebra import * + +import numpy.oldnumeric.linear_algebra as nol + +__all__ = list(nol.__all__) +__all__ += ['qr_decomposition'] + +from numpy.linalg import qr as _qr + +def qr_decomposition(a, mode='full'): + res = _qr(a, mode) + if mode == 'full': + return res + return (None, res) diff --git a/numpy/numarray/ma.py b/numpy/numarray/ma.py new file mode 100644 index 000000000..5c7a19cf2 --- /dev/null +++ b/numpy/numarray/ma.py @@ -0,0 +1,2 @@ + +from numpy.oldnumeric.ma import * diff --git a/numpy/numarray/matrix.py b/numpy/numarray/matrix.py new file mode 100644 index 000000000..a39812e1f --- /dev/null +++ b/numpy/numarray/matrix.py @@ -0,0 +1,8 @@ + +__all__ = ['Matrix'] + +from numpy import matrix as _matrix + +def Matrix(data, typecode=None, copy=1, savespace=0): + return _matrix(data, typecode, copy=copy) + diff --git a/numpy/numarray/mlab.py b/numpy/numarray/mlab.py new file mode 100644 index 000000000..05f234d37 --- /dev/null +++ b/numpy/numarray/mlab.py @@ -0,0 +1,7 @@ + +from numpy.oldnumeric.mlab import * +import numpy.oldnumeric.mlab as nom + +__all__ = nom.__all__ + +del nom diff --git a/numpy/numarray/nd_image.py b/numpy/numarray/nd_image.py new file mode 100644 index 000000000..dff7fa066 --- /dev/null +++ b/numpy/numarray/nd_image.py @@ -0,0 +1,14 @@ +try: + from ndimage import * +except ImportError: + try: + from scipy.ndimage import * + except ImportError: + msg = \ +"""The nd_image package is not installed + +It can be downloaded by checking out the latest source from +http://svn.scipy.org/svn/scipy/trunk/Lib/ndimage or by downloading and +installing all of SciPy from http://www.scipy.org. +""" + raise ImportError(msg) diff --git a/numpy/numarray/numerictypes.py b/numpy/numarray/numerictypes.py new file mode 100644 index 000000000..490ced970 --- /dev/null +++ b/numpy/numarray/numerictypes.py @@ -0,0 +1,551 @@ +"""numerictypes: Define the numeric type objects + +This module is designed so 'from numerictypes import *' is safe. +Exported symbols include: + + Dictionary with all registered number types (including aliases): + typeDict + + Numeric type objects: + Bool + Int8 Int16 Int32 Int64 + UInt8 UInt16 UInt32 UInt64 + Float32 Double64 + Complex32 Complex64 + + Numeric type classes: + NumericType + BooleanType + SignedType + UnsignedType + IntegralType + SignedIntegralType + UnsignedIntegralType + FloatingType + ComplexType + +$Id: numerictypes.py,v 1.55 2005/12/01 16:22:03 jaytmiller Exp $ +""" + +__all__ = ['NumericType','HasUInt64','typeDict','IsType', + 'BooleanType', 'SignedType', 'UnsignedType', 'IntegralType', + 'SignedIntegralType', 'UnsignedIntegralType', 'FloatingType', + 'ComplexType', 'AnyType', 'ObjectType', 'Any', 'Object', + 'Bool', 'Int8', 'Int16', 'Int32', 'Int64', 'Float32', + 'Float64', 'UInt8', 'UInt16', 'UInt32', 'UInt64', + 'Complex32', 'Complex64', 'Byte', 'Short', 'Int','Long', + 'Float', 'Complex', 'genericTypeRank', 'pythonTypeRank', + 'pythonTypeMap', 'scalarTypeMap', 'genericCoercions', + 'typecodes', 'genericPromotionExclusions','MaximumType', + 'getType','scalarTypes', 'typefrom'] + +MAX_ALIGN = 8 +MAX_INT_SIZE = 8 + +import numpy +LP64 = numpy.intp(0).itemsize == 8 + +HasUInt64 = 1 +try: + numpy.int64(0) +except: + HasUInt64 = 0 + +#from typeconv import typeConverters as _typeConverters +#import numinclude +#from _numerictype import _numerictype, typeDict +import types as _types +import copy as _copy +import sys as _sys + +# Enumeration of numarray type codes +typeDict = {} + +_tAny = 0 +_tBool = 1 +_tInt8 = 2 +_tUInt8 = 3 +_tInt16 = 4 +_tUInt16 = 5 +_tInt32 = 6 +_tUInt32 = 7 +_tInt64 = 8 +_tUInt64 = 9 +_tFloat32 = 10 +_tFloat64 = 11 +_tComplex32 = 12 +_tComplex64 = 13 +_tObject = 14 + +def IsType(rep): + """Determines whether the given object or string, 'rep', represents + a numarray type.""" + return isinstance(rep, NumericType) or typeDict.has_key(rep) + +def _register(name, type, force=0): + """Register the type object. Raise an exception if it is already registered + unless force is true. + """ + if typeDict.has_key(name) and not force: + raise ValueError("Type %s has already been registered" % name) + typeDict[name] = type + return type + + +class NumericType(object): + """Numeric type class + + Used both as a type identification and the repository of + characteristics and conversion functions. + """ + def __new__(type, name, bytes, default, typeno): + """__new__() implements a 'quasi-singleton pattern because attempts + to create duplicate types return the first created instance of that + particular type parameterization, i.e. the second time you try to + create "Int32", you get the original Int32, not a new one. + """ + if typeDict.has_key(name): + self = typeDict[name] + if self.bytes != bytes or self.default != default or \ + self.typeno != typeno: + raise ValueError("Redeclaration of existing NumericType "\ + "with different parameters.") + return self + else: + self = object.__new__(type) + self.name = "no name" + self.bytes = None + self.default = None + self.typeno = -1 + return self + + def __init__(self, name, bytes, default, typeno): + if not isinstance(name, str): + raise TypeError("name must be a string") + self.name = name + self.bytes = bytes + self.default = default + self.typeno = typeno + self._conv = None + _register(self.name, self) + + def __getnewargs__(self): + """support the pickling protocol.""" + return (self.name, self.bytes, self.default, self.typeno) + + def __getstate__(self): + """support pickling protocol... no __setstate__ required.""" + False + +class BooleanType(NumericType): + pass + +class SignedType: + """Marker class used for signed type check""" + pass + +class UnsignedType: + """Marker class used for unsigned type check""" + pass + +class IntegralType(NumericType): + pass + +class SignedIntegralType(IntegralType, SignedType): + pass + +class UnsignedIntegralType(IntegralType, UnsignedType): + pass + +class FloatingType(NumericType): + pass + +class ComplexType(NumericType): + pass + +class AnyType(NumericType): + pass + +class ObjectType(NumericType): + pass + +# C-API Type Any + +Any = AnyType("Any", None, None, _tAny) + +Object = ObjectType("Object", None, None, _tObject) + +# Numeric Types: + +Bool = BooleanType("Bool", 1, 0, _tBool) +Int8 = SignedIntegralType( "Int8", 1, 0, _tInt8) +Int16 = SignedIntegralType("Int16", 2, 0, _tInt16) +Int32 = SignedIntegralType("Int32", 4, 0, _tInt32) +Int64 = SignedIntegralType("Int64", 8, 0, _tInt64) + +Float32 = FloatingType("Float32", 4, 0.0, _tFloat32) +Float64 = FloatingType("Float64", 8, 0.0, _tFloat64) + +UInt8 = UnsignedIntegralType( "UInt8", 1, 0, _tUInt8) +UInt16 = UnsignedIntegralType("UInt16", 2, 0, _tUInt16) +UInt32 = UnsignedIntegralType("UInt32", 4, 0, _tUInt32) +UInt64 = UnsignedIntegralType("UInt64", 8, 0, _tUInt64) + +Complex32 = ComplexType("Complex32", 8, complex(0.0), _tComplex32) +Complex64 = ComplexType("Complex64", 16, complex(0.0), _tComplex64) + +Object.dtype = 'O' +Bool.dtype = '?' +Int8.dtype = 'i1' +Int16.dtype = 'i2' +Int32.dtype = 'i4' +Int64.dtype = 'i8' + +UInt8.dtype = 'u1' +UInt16.dtype = 'u2' +UInt32.dtype = 'u4' +UInt64.dtype = 'u8' + +Float32.dtype = 'f4' +Float64.dtype = 'f8' + +Complex32.dtype = 'c8' +Complex64.dtype = 'c16' + +# Aliases + +Byte = _register("Byte", Int8) +Short = _register("Short", Int16) +Int = _register("Int", Int32) +if LP64: + Long = _register("Long", Int64) + if HasUInt64: + _register("ULong", UInt64) + MaybeLong = _register("MaybeLong", Int64) + __all__.append('MaybeLong') +else: + Long = _register("Long", Int32) + _register("ULong", UInt32) + MaybeLong = _register("MaybeLong", Int32) + __all__.append('MaybeLong') + + +_register("UByte", UInt8) +_register("UShort", UInt16) +_register("UInt", UInt32) +Float = _register("Float", Float64) +Complex = _register("Complex", Complex64) + +# short forms + +_register("b1", Bool) +_register("u1", UInt8) +_register("u2", UInt16) +_register("u4", UInt32) +_register("i1", Int8) +_register("i2", Int16) +_register("i4", Int32) + +_register("i8", Int64) +if HasUInt64: + _register("u8", UInt64) + +_register("f4", Float32) +_register("f8", Float64) +_register("c8", Complex32) +_register("c16", Complex64) + +# NumPy forms + +_register("1", Int8) +_register("B", Bool) +_register("c", Int8) +_register("b", UInt8) +_register("s", Int16) +_register("w", UInt16) +_register("i", Int32) +_register("N", Int64) +_register("u", UInt32) +_register("U", UInt64) + +if LP64: + _register("l", Int64) +else: + _register("l", Int32) + +_register("d", Float64) +_register("f", Float32) +_register("D", Complex64) +_register("F", Complex32) + +# scipy.base forms + +def _scipy_alias(scipy_type, numarray_type): + _register(scipy_type, eval(numarray_type)) + globals()[scipy_type] = globals()[numarray_type] + +_scipy_alias("bool_", "Bool") +_scipy_alias("bool8", "Bool") +_scipy_alias("int8", "Int8") +_scipy_alias("uint8", "UInt8") +_scipy_alias("int16", "Int16") +_scipy_alias("uint16", "UInt16") +_scipy_alias("int32", "Int32") +_scipy_alias("uint32", "UInt32") +_scipy_alias("int64", "Int64") +_scipy_alias("uint64", "UInt64") + +_scipy_alias("float64", "Float64") +_scipy_alias("float32", "Float32") +_scipy_alias("complex128", "Complex64") +_scipy_alias("complex64", "Complex32") + +# The rest is used by numeric modules to determine conversions + +# Ranking of types from lowest to highest (sorta) +if not HasUInt64: + genericTypeRank = ['Bool','Int8','UInt8','Int16','UInt16', + 'Int32', 'UInt32', 'Int64', + 'Float32','Float64', 'Complex32', 'Complex64', 'Object'] +else: + genericTypeRank = ['Bool','Int8','UInt8','Int16','UInt16', + 'Int32', 'UInt32', 'Int64', 'UInt64', + 'Float32','Float64', 'Complex32', 'Complex64', 'Object'] + +pythonTypeRank = [ bool, int, long, float, complex ] + +# The next line is not platform independent XXX Needs to be generalized +if not LP64: + pythonTypeMap = { + int:("Int32","int"), + long:("Int64","int"), + float:("Float64","float"), + complex:("Complex64","complex")} + + scalarTypeMap = { + int:"Int32", + long:"Int64", + float:"Float64", + complex:"Complex64"} +else: + pythonTypeMap = { + int:("Int64","int"), + long:("Int64","int"), + float:("Float64","float"), + complex:("Complex64","complex")} + + scalarTypeMap = { + int:"Int64", + long:"Int64", + float:"Float64", + complex:"Complex64"} + +pythonTypeMap.update({bool:("Bool","bool") }) +scalarTypeMap.update({bool:"Bool"}) + +# Generate coercion matrix + +def _initGenericCoercions(): + global genericCoercions + genericCoercions = {} + + # vector with ... + for ntype1 in genericTypeRank: + nt1 = typeDict[ntype1] + rank1 = genericTypeRank.index(ntype1) + ntypesize1, inttype1, signedtype1 = nt1.bytes, \ + isinstance(nt1, IntegralType), isinstance(nt1, SignedIntegralType) + for ntype2 in genericTypeRank: + # vector + nt2 = typeDict[ntype2] + ntypesize2, inttype2, signedtype2 = nt2.bytes, \ + isinstance(nt2, IntegralType), isinstance(nt2, SignedIntegralType) + rank2 = genericTypeRank.index(ntype2) + if (signedtype1 != signedtype2) and inttype1 and inttype2: + # mixing of signed and unsigned ints is a special case + # If unsigned same size or larger, final size needs to be bigger + # if possible + if signedtype1: + if ntypesize2 >= ntypesize1: + size = min(2*ntypesize2, MAX_INT_SIZE) + else: + size = ntypesize1 + else: + if ntypesize1 >= ntypesize2: + size = min(2*ntypesize1, MAX_INT_SIZE) + else: + size = ntypesize2 + outtype = "Int"+str(8*size) + else: + if rank1 >= rank2: + outtype = ntype1 + else: + outtype = ntype2 + genericCoercions[(ntype1, ntype2)] = outtype + + for ntype2 in pythonTypeRank: + # scalar + mapto, kind = pythonTypeMap[ntype2] + if ((inttype1 and kind=="int") or (not inttype1 and kind=="float")): + # both are of the same "kind" thus vector type dominates + outtype = ntype1 + else: + rank2 = genericTypeRank.index(mapto) + if rank1 >= rank2: + outtype = ntype1 + else: + outtype = mapto + genericCoercions[(ntype1, ntype2)] = outtype + genericCoercions[(ntype2, ntype1)] = outtype + + # scalar-scalar + for ntype1 in pythonTypeRank: + maptype1 = scalarTypeMap[ntype1] + genericCoercions[(ntype1,)] = maptype1 + for ntype2 in pythonTypeRank: + maptype2 = scalarTypeMap[ntype2] + genericCoercions[(ntype1, ntype2)] = genericCoercions[(maptype1, maptype2)] + + # Special cases more easily dealt with outside of the loop + genericCoercions[("Complex32", "Float64")] = "Complex64" + genericCoercions[("Float64", "Complex32")] = "Complex64" + genericCoercions[("Complex32", "Int64")] = "Complex64" + genericCoercions[("Int64", "Complex32")] = "Complex64" + genericCoercions[("Complex32", "UInt64")] = "Complex64" + genericCoercions[("UInt64", "Complex32")] = "Complex64" + + genericCoercions[("Int64","Float32")] = "Float64" + genericCoercions[("Float32", "Int64")] = "Float64" + genericCoercions[("UInt64","Float32")] = "Float64" + genericCoercions[("Float32", "UInt64")] = "Float64" + + genericCoercions[(float, "Bool")] = "Float64" + genericCoercions[("Bool", float)] = "Float64" + + genericCoercions[(float,float,float)] = "Float64" # for scipy.special + genericCoercions[(int,int,float)] = "Float64" # for scipy.special + +_initGenericCoercions() + +# If complex is subclassed, the following may not be necessary +genericPromotionExclusions = { + 'Bool': (), + 'Int8': (), + 'Int16': (), + 'Int32': ('Float32','Complex32'), + 'UInt8': (), + 'UInt16': (), + 'UInt32': ('Float32','Complex32'), + 'Int64' : ('Float32','Complex32'), + 'UInt64' : ('Float32','Complex32'), + 'Float32': (), + 'Float64': ('Complex32',), + 'Complex32':(), + 'Complex64':() +} # e.g., don't allow promotion from Float64 to Complex32 or Int64 to Float32 + +# Numeric typecodes +typecodes = {'Integer': '1silN', + 'UnsignedInteger': 'bBwuU', + 'Float': 'fd', + 'Character': 'c', + 'Complex': 'FD' } + +if HasUInt64: + _MaximumType = { + Bool : UInt64, + + Int8 : Int64, + Int16 : Int64, + Int32 : Int64, + Int64 : Int64, + + UInt8 : UInt64, + UInt16 : UInt64, + UInt32 : UInt64, + UInt8 : UInt64, + + Float32 : Float64, + Float64 : Float64, + + Complex32 : Complex64, + Complex64 : Complex64 + } +else: + _MaximumType = { + Bool : Int64, + + Int8 : Int64, + Int16 : Int64, + Int32 : Int64, + Int64 : Int64, + + UInt8 : Int64, + UInt16 : Int64, + UInt32 : Int64, + UInt8 : Int64, + + Float32 : Float64, + Float64 : Float64, + + Complex32 : Complex64, + Complex64 : Complex64 + } + +def MaximumType(t): + """returns the type of highest precision of the same general kind as 't'""" + return _MaximumType[t] + + +def getType(type): + """Return the numeric type object for type + + type may be the name of a type object or the actual object + """ + if isinstance(type, NumericType): + return type + try: + return typeDict[type] + except KeyError: + raise TypeError("Not a numeric type") + +scalarTypes = (bool,int,long,float,complex) + +_scipy_dtypechar = { + Int8 : 'b', + UInt8 : 'B', + Int16 : 'h', + UInt16 : 'H', + Int32 : 'i', + UInt32 : 'I', + Int64 : 'q', + UInt64 : 'Q', + Float32 : 'f', + Float64 : 'd', + Complex32 : 'F', # Note the switchup here: + Complex64 : 'D' # numarray.Complex32 == scipy.complex64, etc. + } + +_scipy_dtypechar_inverse = {} +for key,value in _scipy_dtypechar.items(): + _scipy_dtypechar_inverse[value] = key + +_val = numpy.int_(0).itemsize +if _val == 8: + _scipy_dtypechar_inverse['l'] = Int64 + _scipy_dtypechar_inverse['L'] = UInt64 +elif _val == 4: + _scipy_dtypechar_inverse['l'] = Int32 + _scipy_dtypechar_inverse['L'] = UInt32 + +del _val + +if LP64: + _scipy_dtypechar_inverse['p'] = Int64 + _scipy_dtypechar_inverse['P'] = UInt64 +else: + _scipy_dtypechar_inverse['p'] = Int32 + _scipy_dtypechar_inverse['P'] = UInt32 + +def typefrom(obj): + return _scipy_dtypechar_inverse[obj.dtype.char] diff --git a/numpy/numarray/numpy/arraybase.h b/numpy/numarray/numpy/arraybase.h new file mode 100644 index 000000000..40d1394bf --- /dev/null +++ b/numpy/numarray/numpy/arraybase.h @@ -0,0 +1,71 @@ +#if !defined(__arraybase_h) +#define _arraybase_h 1 + +#define SZ_BUF 79 +#define MAXDIM NPY_MAXDIMS +#define MAXARGS 18 + +typedef npy_intp maybelong; +typedef npy_bool Bool; +typedef npy_int8 Int8; +typedef npy_uint8 UInt8; +typedef npy_int16 Int16; +typedef npy_uint16 UInt16; +typedef npy_int32 Int32; +typedef npy_uint32 UInt32; +typedef npy_int64 Int64; +typedef npy_int64 UInt64; +typedef npy_float32 Float32; +typedef npy_float64 Float64; + +typedef enum +{ + tAny=-1, + tBool=PyArray_BOOL, + tInt8=PyArray_INT8, + tUInt8=PyArray_UINT8, + tInt16=PyArray_INT16, + tUInt16=PyArray_UINT16, + tInt32=PyArray_INT32, + tUInt32=PyArray_UINT32, + tInt64=PyArray_INT64, + tUInt64=PyArray_UINT64, + tFloat32=PyArray_FLOAT32, + tFloat64=PyArray_FLOAT64, + tComplex32=PyArray_COMPLEX64, + tComplex64=PyArray_COMPLEX128, + tObject=PyArray_OBJECT, /* placeholder... does nothing */ + tMaxType=PyArray_NTYPES, + tDefault = tFloat64, +#if NPY_BITSOF_LONG == 64 + tLong = tInt64, +#else + tLong = tInt32, +#endif +} NumarrayType; + +#define nNumarrayType PyArray_NTYPES + +#define HAS_UINT64 1 + +typedef enum +{ + NUM_LITTLE_ENDIAN=0, + NUM_BIG_ENDIAN = 1 +} NumarrayByteOrder; + +typedef struct { Float32 r, i; } Complex32; +typedef struct { Float64 r, i; } Complex64; + +#define WRITABLE NPY_WRITEABLE +#define CHECKOVERFLOW 0x800 +#define UPDATEDICT 0x1000 +#define FORTRAN_CONTIGUOUS NPY_FORTRAN +#define IS_CARRAY (NPY_CONTIGUOUS | NPY_ALIGNED) + +#define PyArray(m) ((PyArrayObject *)(m)) +#define PyArray_ISFORTRAN_CONTIGUOUS(m) (((PyArray(m))->flags & FORTRAN_CONTIGUOUS) != 0) +#define PyArray_ISWRITABLE PyArray_ISWRITEABLE + + +#endif diff --git a/numpy/numarray/numpy/cfunc.h b/numpy/numarray/numpy/cfunc.h new file mode 100644 index 000000000..b581be08f --- /dev/null +++ b/numpy/numarray/numpy/cfunc.h @@ -0,0 +1,78 @@ +#if !defined(__cfunc__) +#define __cfunc__ 1 + +typedef PyObject *(*CFUNCasPyValue)(void *); +typedef int (*UFUNC)(long, long, long, void **, long*); +/* typedef void (*CFUNC_2ARG)(long, void *, void *); */ +/* typedef void (*CFUNC_3ARG)(long, void *, void *, void *); */ +typedef int (*CFUNCfromPyValue)(PyObject *, void *); +typedef int (*CFUNC_STRIDE_CONV_FUNC)(long, long, maybelong *, + void *, long, maybelong*, void *, long, maybelong *); + +typedef int (*CFUNC_STRIDED_FUNC)(PyObject *, long, PyArrayObject **, + char **data); + +#define MAXARRAYS 16 + +typedef enum { + CFUNC_UFUNC, + CFUNC_STRIDING, + CFUNC_NSTRIDING, + CFUNC_AS_PY_VALUE, + CFUNC_FROM_PY_VALUE +} eCfuncType; + +typedef struct { + char *name; + void *fptr; /* Pointer to "un-wrapped" c function */ + eCfuncType type; /* UFUNC, STRIDING, AsPyValue, FromPyValue */ + Bool chkself; /* CFUNC does own alignment/bounds checking */ + Bool align; /* CFUNC requires aligned buffer pointers */ + Int8 wantIn, wantOut; /* required input/output arg counts. */ + Int8 sizes[MAXARRAYS]; /* array of align/itemsizes. */ + Int8 iters[MAXARRAYS]; /* array of element counts. 0 --> niter. */ +} CfuncDescriptor; + +typedef struct { + PyObject_HEAD + CfuncDescriptor descr; +} CfuncObject; + +#define SELF_CHECKED_CFUNC_DESCR(name, type) \ + static CfuncDescriptor name##_descr = { #name, (void *) name, type, 1 } + +#define CHECK_ALIGN 1 + +#define CFUNC_DESCR(name, type, align, iargs, oargs, s1, s2, s3, i1, i2, i3) \ + static CfuncDescriptor name##_descr = \ + { #name, (void *)name, type, 0, align, iargs, oargs, {s1, s2, s3}, {i1, i2, i3} } + +#define UFUNC_DESCR1(name, s1) \ + CFUNC_DESCR(name, CFUNC_UFUNC, CHECK_ALIGN, 0, 1, s1, 0, 0, 0, 0, 0) + +#define UFUNC_DESCR2(name, s1, s2) \ + CFUNC_DESCR(name, CFUNC_UFUNC, CHECK_ALIGN, 1, 1, s1, s2, 0, 0, 0, 0) + +#define UFUNC_DESCR3(name, s1, s2, s3) \ + CFUNC_DESCR(name, CFUNC_UFUNC, CHECK_ALIGN, 2, 1, s1, s2, s3, 0, 0, 0) + +#define UFUNC_DESCR3sv(name, s1, s2, s3) \ + CFUNC_DESCR(name, CFUNC_UFUNC, CHECK_ALIGN, 2, 1, s1, s2, s3, 1, 0, 0) + +#define UFUNC_DESCR3vs(name, s1, s2, s3) \ + CFUNC_DESCR(name, CFUNC_UFUNC, CHECK_ALIGN, 2, 1, s1, s2, s3, 0, 1, 0) + +#define STRIDING_DESCR2(name, align, s1, s2) \ + CFUNC_DESCR(name, CFUNC_STRIDING, align, 1, 1, s1, s2, 0, 0, 0, 0) + +#define NSTRIDING_DESCR1(name) \ + CFUNC_DESCR(name, CFUNC_NSTRIDING, 0, 0, 1, 0, 0, 0, 0, 0, 0) + +#define NSTRIDING_DESCR2(name) \ + CFUNC_DESCR(name, CFUNC_NSTRIDING, 0, 1, 1, 0, 0, 0, 0, 0, 0) + +#define NSTRIDING_DESCR3(name) \ + CFUNC_DESCR(name, CFUNC_NSTRIDING, 0, 2, 1, 0, 0, 0, 0, 0, 0) + +#endif + diff --git a/numpy/numarray/numpy/ieeespecial.h b/numpy/numarray/numpy/ieeespecial.h new file mode 100644 index 000000000..0f3fff2a9 --- /dev/null +++ b/numpy/numarray/numpy/ieeespecial.h @@ -0,0 +1,124 @@ +/* 32-bit special value ranges */ + +#if defined(_MSC_VER) +#define MKINT(x) (x##UL) +#define MKINT64(x) (x##Ui64) +#define BIT(x) (1Ui64 << (x)) +#else +#define MKINT(x) (x##U) +#define MKINT64(x) (x##ULL) +#define BIT(x) (1ULL << (x)) +#endif + + +#define NEG_QUIET_NAN_MIN32 MKINT(0xFFC00001) +#define NEG_QUIET_NAN_MAX32 MKINT(0xFFFFFFFF) + +#define INDETERMINATE_MIN32 MKINT(0xFFC00000) +#define INDETERMINATE_MAX32 MKINT(0xFFC00000) + +#define NEG_SIGNAL_NAN_MIN32 MKINT(0xFF800001) +#define NEG_SIGNAL_NAN_MAX32 MKINT(0xFFBFFFFF) + +#define NEG_INFINITY_MIN32 MKINT(0xFF800000) + +#define NEG_NORMALIZED_MIN32 MKINT(0x80800000) +#define NEG_NORMALIZED_MAX32 MKINT(0xFF7FFFFF) + +#define NEG_DENORMALIZED_MIN32 MKINT(0x80000001) +#define NEG_DENORMALIZED_MAX32 MKINT(0x807FFFFF) + +#define NEG_ZERO_MIN32 MKINT(0x80000000) +#define NEG_ZERO_MAX32 MKINT(0x80000000) + +#define POS_ZERO_MIN32 MKINT(0x00000000) +#define POS_ZERO_MAX32 MKINT(0x00000000) + +#define POS_DENORMALIZED_MIN32 MKINT(0x00000001) +#define POS_DENORMALIZED_MAX32 MKINT(0x007FFFFF) + +#define POS_NORMALIZED_MIN32 MKINT(0x00800000) +#define POS_NORMALIZED_MAX32 MKINT(0x7F7FFFFF) + +#define POS_INFINITY_MIN32 MKINT(0x7F800000) +#define POS_INFINITY_MAX32 MKINT(0x7F800000) + +#define POS_SIGNAL_NAN_MIN32 MKINT(0x7F800001) +#define POS_SIGNAL_NAN_MAX32 MKINT(0x7FBFFFFF) + +#define POS_QUIET_NAN_MIN32 MKINT(0x7FC00000) +#define POS_QUIET_NAN_MAX32 MKINT(0x7FFFFFFF) + +/* 64-bit special value ranges */ + +#define NEG_QUIET_NAN_MIN64 MKINT64(0xFFF8000000000001) +#define NEG_QUIET_NAN_MAX64 MKINT64(0xFFFFFFFFFFFFFFFF) + +#define INDETERMINATE_MIN64 MKINT64(0xFFF8000000000000) +#define INDETERMINATE_MAX64 MKINT64(0xFFF8000000000000) + +#define NEG_SIGNAL_NAN_MIN64 MKINT64(0xFFF7FFFFFFFFFFFF) +#define NEG_SIGNAL_NAN_MAX64 MKINT64(0xFFF0000000000001) + +#define NEG_INFINITY_MIN64 MKINT64(0xFFF0000000000000) + +#define NEG_NORMALIZED_MIN64 MKINT64(0xFFEFFFFFFFFFFFFF) +#define NEG_NORMALIZED_MAX64 MKINT64(0x8010000000000000) + +#define NEG_DENORMALIZED_MIN64 MKINT64(0x800FFFFFFFFFFFFF) +#define NEG_DENORMALIZED_MAX64 MKINT64(0x8000000000000001) + +#define NEG_ZERO_MIN64 MKINT64(0x8000000000000000) +#define NEG_ZERO_MAX64 MKINT64(0x8000000000000000) + +#define POS_ZERO_MIN64 MKINT64(0x0000000000000000) +#define POS_ZERO_MAX64 MKINT64(0x0000000000000000) + +#define POS_DENORMALIZED_MIN64 MKINT64(0x0000000000000001) +#define POS_DENORMALIZED_MAX64 MKINT64(0x000FFFFFFFFFFFFF) + +#define POS_NORMALIZED_MIN64 MKINT64(0x0010000000000000) +#define POS_NORMALIZED_MAX64 MKINT64(0x7FEFFFFFFFFFFFFF) + +#define POS_INFINITY_MIN64 MKINT64(0x7FF0000000000000) +#define POS_INFINITY_MAX64 MKINT64(0x7FF0000000000000) + +#define POS_SIGNAL_NAN_MIN64 MKINT64(0x7FF0000000000001) +#define POS_SIGNAL_NAN_MAX64 MKINT64(0x7FF7FFFFFFFFFFFF) + +#define POS_QUIET_NAN_MIN64 MKINT64(0x7FF8000000000000) +#define POS_QUIET_NAN_MAX64 MKINT64(0x7FFFFFFFFFFFFFFF) + +typedef enum +{ + POS_QNAN_BIT, + NEG_QNAN_BIT, + POS_SNAN_BIT, + NEG_SNAN_BIT, + POS_INF_BIT, + NEG_INF_BIT, + POS_DEN_BIT, + NEG_DEN_BIT, + POS_NOR_BIT, + NEG_NOR_BIT, + POS_ZERO_BIT, + NEG_ZERO_BIT, + INDETERM_BIT, + BUG_BIT +} ieee_selects; + +#define MSK_POS_QNAN BIT(POS_QNAN_BIT) +#define MSK_POS_SNAN BIT(POS_SNAN_BIT) +#define MSK_POS_INF BIT(POS_INF_BIT) +#define MSK_POS_DEN BIT(POS_DEN_BIT) +#define MSK_POS_NOR BIT(POS_NOR_BIT) +#define MSK_POS_ZERO BIT(POS_ZERO_BIT) +#define MSK_NEG_QNAN BIT(NEG_QNAN_BIT) +#define MSK_NEG_SNAN BIT(NEG_SNAN_BIT) +#define MSK_NEG_INF BIT(NEG_INF_BIT) +#define MSK_NEG_DEN BIT(NEG_DEN_BIT) +#define MSK_NEG_NOR BIT(NEG_NOR_BIT) +#define MSK_NEG_ZERO BIT(NEG_ZERO_BIT) +#define MSK_INDETERM BIT(INDETERM_BIT) +#define MSK_BUG BIT(BUG_BIT) + diff --git a/numpy/numarray/numpy/libnumarray.h b/numpy/numarray/numpy/libnumarray.h new file mode 100644 index 000000000..f23a07d7a --- /dev/null +++ b/numpy/numarray/numpy/libnumarray.h @@ -0,0 +1,611 @@ +/* Compatibility with numarray. Do not use in new code. + */ + +#ifndef NUMPY_LIBNUMARRAY_H +#define NUMPY_LIBNUMARRAY_H + +#include "numpy/arrayobject.h" +#include "arraybase.h" +#include "nummacro.h" +#include "numcomplex.h" +#include "ieeespecial.h" +#include "cfunc.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* Header file for libnumarray */ + +#if !defined(_libnumarray_MODULE) + +/* +Extensions constructed from seperate compilation units can access the +C-API defined here by defining "libnumarray_UNIQUE_SYMBOL" to a global +name unique to the extension. Doing this circumvents the requirement +to import libnumarray into each compilation unit, but is nevertheless +mildly discouraged as "outside the Python norm" and potentially +leading to problems. Looking around at "existing Python art", most +extension modules are monolithic C files, and likely for good reason. +*/ + +/* C API address pointer */ +#if defined(NO_IMPORT) || defined(NO_IMPORT_ARRAY) +extern void **libnumarray_API; +#else +#if defined(libnumarray_UNIQUE_SYMBOL) +void **libnumarray_API; +#else +static void **libnumarray_API; +#endif +#endif + +#define _import_libnumarray() \ + { \ + PyObject *module = PyImport_ImportModule("numpy.numarray._capi"); \ + if (module != NULL) { \ + PyObject *module_dict = PyModule_GetDict(module); \ + PyObject *c_api_object = \ + PyDict_GetItemString(module_dict, "_C_API"); \ + if (c_api_object && PyCObject_Check(c_api_object)) { \ + libnumarray_API = (void **)PyCObject_AsVoidPtr(c_api_object); \ + } else { \ + PyErr_Format(PyExc_ImportError, \ + "Can't get API for module 'numpy.numarray._capi'"); \ + } \ + } \ + } + +#define import_libnumarray() _import_libnumarray(); if (PyErr_Occurred()) { PyErr_Print(); PyErr_SetString(PyExc_ImportError, "numpy.numarray._capi failed to import.\n"); return; } + +#endif + + +#define libnumarray_FatalApiError (Py_FatalError("Call to API function without first calling import_libnumarray() in " __FILE__), NULL) + + +/* Macros defining components of function prototypes */ + +#ifdef _libnumarray_MODULE + /* This section is used when compiling libnumarray */ + +static PyObject *_Error; + +static PyObject* getBuffer (PyObject*o); + +static int isBuffer (PyObject*o); + +static int getWriteBufferDataPtr (PyObject*o,void**p); + +static int isBufferWriteable (PyObject*o); + +static int getReadBufferDataPtr (PyObject*o,void**p); + +static int getBufferSize (PyObject*o); + +static double num_log (double x); + +static double num_log10 (double x); + +static double num_pow (double x, double y); + +static double num_acosh (double x); + +static double num_asinh (double x); + +static double num_atanh (double x); + +static double num_round (double x); + +static int int_dividebyzero_error (long value, long unused); + +static int int_overflow_error (Float64 value); + +static int umult64_overflow (UInt64 a, UInt64 b); + +static int smult64_overflow (Int64 a0, Int64 b0); + +static void NA_Done (void); + +static PyArrayObject* NA_NewAll (int ndim, maybelong* shape, NumarrayType type, void* buffer, maybelong byteoffset, maybelong bytestride, int byteorder, int aligned, int writeable); + +static PyArrayObject* NA_NewAllStrides (int ndim, maybelong* shape, maybelong* strides, NumarrayType type, void* buffer, maybelong byteoffset, int byteorder, int aligned, int writeable); + +static PyArrayObject* NA_New (void* buffer, NumarrayType type, int ndim,...); + +static PyArrayObject* NA_Empty (int ndim, maybelong* shape, NumarrayType type); + +static PyArrayObject* NA_NewArray (void* buffer, NumarrayType type, int ndim, ...); + +static PyArrayObject* NA_vNewArray (void* buffer, NumarrayType type, int ndim, maybelong *shape); + +static PyObject* NA_ReturnOutput (PyObject*,PyArrayObject*); + +static long NA_getBufferPtrAndSize (PyObject*,int,void**); + +static int NA_checkIo (char*,int,int,int,int); + +static int NA_checkOneCBuffer (char*,long,void*,long,size_t); + +static int NA_checkNCBuffers (char*,int,long,void**,long*,Int8*,Int8*); + +static int NA_checkOneStriding (char*,long,maybelong*,long,maybelong*,long,long,int); + +static PyObject* NA_new_cfunc (CfuncDescriptor*); + +static int NA_add_cfunc (PyObject*,char*,CfuncDescriptor*); + +static PyArrayObject* NA_InputArray (PyObject*,NumarrayType,int); + +static PyArrayObject* NA_OutputArray (PyObject*,NumarrayType,int); + +static PyArrayObject* NA_IoArray (PyObject*,NumarrayType,int); + +static PyArrayObject* NA_OptionalOutputArray (PyObject*,NumarrayType,int,PyArrayObject*); + +static long NA_get_offset (PyArrayObject*,int,...); + +static Float64 NA_get_Float64 (PyArrayObject*,long); + +static void NA_set_Float64 (PyArrayObject*,long,Float64); + +static Complex64 NA_get_Complex64 (PyArrayObject*,long); + +static void NA_set_Complex64 (PyArrayObject*,long,Complex64); + +static Int64 NA_get_Int64 (PyArrayObject*,long); + +static void NA_set_Int64 (PyArrayObject*,long,Int64); + +static Float64 NA_get1_Float64 (PyArrayObject*,long); + +static Float64 NA_get2_Float64 (PyArrayObject*,long,long); + +static Float64 NA_get3_Float64 (PyArrayObject*,long,long,long); + +static void NA_set1_Float64 (PyArrayObject*,long,Float64); + +static void NA_set2_Float64 (PyArrayObject*,long,long,Float64); + +static void NA_set3_Float64 (PyArrayObject*,long,long,long,Float64); + +static Complex64 NA_get1_Complex64 (PyArrayObject*,long); + +static Complex64 NA_get2_Complex64 (PyArrayObject*,long,long); + +static Complex64 NA_get3_Complex64 (PyArrayObject*,long,long,long); + +static void NA_set1_Complex64 (PyArrayObject*,long,Complex64); + +static void NA_set2_Complex64 (PyArrayObject*,long,long,Complex64); + +static void NA_set3_Complex64 (PyArrayObject*,long,long,long,Complex64); + +static Int64 NA_get1_Int64 (PyArrayObject*,long); + +static Int64 NA_get2_Int64 (PyArrayObject*,long,long); + +static Int64 NA_get3_Int64 (PyArrayObject*,long,long,long); + +static void NA_set1_Int64 (PyArrayObject*,long,Int64); + +static void NA_set2_Int64 (PyArrayObject*,long,long,Int64); + +static void NA_set3_Int64 (PyArrayObject*,long,long,long,Int64); + +static int NA_get1D_Float64 (PyArrayObject*,long,int,Float64*); + +static int NA_set1D_Float64 (PyArrayObject*,long,int,Float64*); + +static int NA_get1D_Int64 (PyArrayObject*,long,int,Int64*); + +static int NA_set1D_Int64 (PyArrayObject*,long,int,Int64*); + +static int NA_get1D_Complex64 (PyArrayObject*,long,int,Complex64*); + +static int NA_set1D_Complex64 (PyArrayObject*,long,int,Complex64*); + +static int NA_ShapeEqual (PyArrayObject*,PyArrayObject*); + +static int NA_ShapeLessThan (PyArrayObject*,PyArrayObject*); + +static int NA_ByteOrder (void); + +static Bool NA_IeeeSpecial32 (Float32*,Int32*); + +static Bool NA_IeeeSpecial64 (Float64*,Int32*); + +static PyArrayObject* NA_updateDataPtr (PyArrayObject*); + +static char* NA_typeNoToName (int); + +static int NA_nameToTypeNo (char*); + +static PyObject* NA_typeNoToTypeObject (int); + +static PyObject* NA_intTupleFromMaybeLongs (int,maybelong*); + +static long NA_maybeLongsFromIntTuple (int,maybelong*,PyObject*); + +static int NA_intTupleProduct (PyObject *obj, long *product); + +static long NA_isIntegerSequence (PyObject*); + +static PyObject* NA_setArrayFromSequence (PyArrayObject*,PyObject*); + +static int NA_maxType (PyObject*); + +static int NA_isPythonScalar (PyObject *obj); + +static PyObject* NA_getPythonScalar (PyArrayObject*,long); + +static int NA_setFromPythonScalar (PyArrayObject*,long,PyObject*); + +static int NA_NDArrayCheck (PyObject*); + +static int NA_NumArrayCheck (PyObject*); + +static int NA_ComplexArrayCheck (PyObject*); + +static unsigned long NA_elements (PyArrayObject*); + +static int NA_typeObjectToTypeNo (PyObject*); + +static int NA_copyArray (PyArrayObject* to, const PyArrayObject* from); + +static PyArrayObject* NA_copy (PyArrayObject*); + +static PyObject* NA_getType (PyObject *typeobj_or_name); + +static PyObject * NA_callCUFuncCore (PyObject *cfunc, long niter, long ninargs, long noutargs, PyObject **BufferObj, long *offset); + +static PyObject * NA_callStrideConvCFuncCore (PyObject *cfunc, int nshape, maybelong *shape, PyObject *inbuffObj, long inboffset, int nstrides0, maybelong *inbstrides, PyObject *outbuffObj, long outboffset, int nstrides1, maybelong *outbstrides, long nbytes); + +static void NA_stridesFromShape (int nshape, maybelong *shape, maybelong bytestride, maybelong *strides); + +static int NA_OperatorCheck (PyObject *obj); + +static int NA_ConverterCheck (PyObject *obj); + +static int NA_UfuncCheck (PyObject *obj); + +static int NA_CfuncCheck (PyObject *obj); + +static int NA_getByteOffset (PyArrayObject *array, int nindices, maybelong *indices, long *offset); + +static int NA_swapAxes (PyArrayObject *array, int x, int y); + +static PyObject * NA_initModuleGlobal (char *module, char *global); + +static NumarrayType NA_NumarrayType (PyObject *seq); + +static PyArrayObject * NA_NewAllFromBuffer (int ndim, maybelong *shape, NumarrayType type, PyObject *bufferObject, maybelong byteoffset, maybelong bytestride, int byteorder, int aligned, int writeable); + +static Float64 * NA_alloc1D_Float64 (PyArrayObject *a, long offset, int cnt); + +static Int64 * NA_alloc1D_Int64 (PyArrayObject *a, long offset, int cnt); + +static void NA_updateAlignment (PyArrayObject *self); + +static void NA_updateContiguous (PyArrayObject *self); + +static void NA_updateStatus (PyArrayObject *self); + +static int NA_NumArrayCheckExact (PyObject *op); + +static int NA_NDArrayCheckExact (PyObject *op); + +static int NA_OperatorCheckExact (PyObject *op); + +static int NA_ConverterCheckExact (PyObject *op); + +static int NA_UfuncCheckExact (PyObject *op); + +static int NA_CfuncCheckExact (PyObject *op); + +static char * NA_getArrayData (PyArrayObject *ap); + +static void NA_updateByteswap (PyArrayObject *ap); + +static PyArray_Descr * NA_DescrFromType (int type); + +static PyObject * NA_Cast (PyArrayObject *a, int type); + +static int NA_checkFPErrors (void); + +static void NA_clearFPErrors (void); + +static int NA_checkAndReportFPErrors (char *name); + +static Bool NA_IeeeMask32 (Float32,Int32); + +static Bool NA_IeeeMask64 (Float64,Int32); + +static int _NA_callStridingHelper (PyObject *aux, long dim, long nnumarray, PyArrayObject *numarray[], char *data[], CFUNC_STRIDED_FUNC f); + +static PyArrayObject * NA_FromDimsStridesDescrAndData (int nd, maybelong *dims, maybelong *strides, PyArray_Descr *descr, char *data); + +static PyArrayObject * NA_FromDimsTypeAndData (int nd, maybelong *dims, int type, char *data); + +static PyArrayObject * NA_FromDimsStridesTypeAndData (int nd, maybelong *dims, maybelong *strides, int type, char *data); + +static int NA_scipy_typestr (NumarrayType t, int byteorder, char *typestr); + +static PyArrayObject * NA_FromArrayStruct (PyObject *a); + + +#else + /* This section is used in modules that use libnumarray */ + +#define getBuffer (libnumarray_API ? (*(PyObject* (*) (PyObject*o) ) libnumarray_API[ 0 ]) : (*(PyObject* (*) (PyObject*o) ) libnumarray_FatalApiError)) + +#define isBuffer (libnumarray_API ? (*(int (*) (PyObject*o) ) libnumarray_API[ 1 ]) : (*(int (*) (PyObject*o) ) libnumarray_FatalApiError)) + +#define getWriteBufferDataPtr (libnumarray_API ? (*(int (*) (PyObject*o,void**p) ) libnumarray_API[ 2 ]) : (*(int (*) (PyObject*o,void**p) ) libnumarray_FatalApiError)) + +#define isBufferWriteable (libnumarray_API ? (*(int (*) (PyObject*o) ) libnumarray_API[ 3 ]) : (*(int (*) (PyObject*o) ) libnumarray_FatalApiError)) + +#define getReadBufferDataPtr (libnumarray_API ? (*(int (*) (PyObject*o,void**p) ) libnumarray_API[ 4 ]) : (*(int (*) (PyObject*o,void**p) ) libnumarray_FatalApiError)) + +#define getBufferSize (libnumarray_API ? (*(int (*) (PyObject*o) ) libnumarray_API[ 5 ]) : (*(int (*) (PyObject*o) ) libnumarray_FatalApiError)) + +#define num_log (libnumarray_API ? (*(double (*) (double x) ) libnumarray_API[ 6 ]) : (*(double (*) (double x) ) libnumarray_FatalApiError)) + +#define num_log10 (libnumarray_API ? (*(double (*) (double x) ) libnumarray_API[ 7 ]) : (*(double (*) (double x) ) libnumarray_FatalApiError)) + +#define num_pow (libnumarray_API ? (*(double (*) (double x, double y) ) libnumarray_API[ 8 ]) : (*(double (*) (double x, double y) ) libnumarray_FatalApiError)) + +#define num_acosh (libnumarray_API ? (*(double (*) (double x) ) libnumarray_API[ 9 ]) : (*(double (*) (double x) ) libnumarray_FatalApiError)) + +#define num_asinh (libnumarray_API ? (*(double (*) (double x) ) libnumarray_API[ 10 ]) : (*(double (*) (double x) ) libnumarray_FatalApiError)) + +#define num_atanh (libnumarray_API ? (*(double (*) (double x) ) libnumarray_API[ 11 ]) : (*(double (*) (double x) ) libnumarray_FatalApiError)) + +#define num_round (libnumarray_API ? (*(double (*) (double x) ) libnumarray_API[ 12 ]) : (*(double (*) (double x) ) libnumarray_FatalApiError)) + +#define int_dividebyzero_error (libnumarray_API ? (*(int (*) (long value, long unused) ) libnumarray_API[ 13 ]) : (*(int (*) (long value, long unused) ) libnumarray_FatalApiError)) + +#define int_overflow_error (libnumarray_API ? (*(int (*) (Float64 value) ) libnumarray_API[ 14 ]) : (*(int (*) (Float64 value) ) libnumarray_FatalApiError)) + +#define umult64_overflow (libnumarray_API ? (*(int (*) (UInt64 a, UInt64 b) ) libnumarray_API[ 15 ]) : (*(int (*) (UInt64 a, UInt64 b) ) libnumarray_FatalApiError)) + +#define smult64_overflow (libnumarray_API ? (*(int (*) (Int64 a0, Int64 b0) ) libnumarray_API[ 16 ]) : (*(int (*) (Int64 a0, Int64 b0) ) libnumarray_FatalApiError)) + +#define NA_Done (libnumarray_API ? (*(void (*) (void) ) libnumarray_API[ 17 ]) : (*(void (*) (void) ) libnumarray_FatalApiError)) + +#define NA_NewAll (libnumarray_API ? (*(PyArrayObject* (*) (int ndim, maybelong* shape, NumarrayType type, void* buffer, maybelong byteoffset, maybelong bytestride, int byteorder, int aligned, int writeable) ) libnumarray_API[ 18 ]) : (*(PyArrayObject* (*) (int ndim, maybelong* shape, NumarrayType type, void* buffer, maybelong byteoffset, maybelong bytestride, int byteorder, int aligned, int writeable) ) libnumarray_FatalApiError)) + +#define NA_NewAllStrides (libnumarray_API ? (*(PyArrayObject* (*) (int ndim, maybelong* shape, maybelong* strides, NumarrayType type, void* buffer, maybelong byteoffset, int byteorder, int aligned, int writeable) ) libnumarray_API[ 19 ]) : (*(PyArrayObject* (*) (int ndim, maybelong* shape, maybelong* strides, NumarrayType type, void* buffer, maybelong byteoffset, int byteorder, int aligned, int writeable) ) libnumarray_FatalApiError)) + +#define NA_New (libnumarray_API ? (*(PyArrayObject* (*) (void* buffer, NumarrayType type, int ndim,...) ) libnumarray_API[ 20 ]) : (*(PyArrayObject* (*) (void* buffer, NumarrayType type, int ndim,...) ) libnumarray_FatalApiError)) + +#define NA_Empty (libnumarray_API ? (*(PyArrayObject* (*) (int ndim, maybelong* shape, NumarrayType type) ) libnumarray_API[ 21 ]) : (*(PyArrayObject* (*) (int ndim, maybelong* shape, NumarrayType type) ) libnumarray_FatalApiError)) + +#define NA_NewArray (libnumarray_API ? (*(PyArrayObject* (*) (void* buffer, NumarrayType type, int ndim, ...) ) libnumarray_API[ 22 ]) : (*(PyArrayObject* (*) (void* buffer, NumarrayType type, int ndim, ...) ) libnumarray_FatalApiError)) + +#define NA_vNewArray (libnumarray_API ? (*(PyArrayObject* (*) (void* buffer, NumarrayType type, int ndim, maybelong *shape) ) libnumarray_API[ 23 ]) : (*(PyArrayObject* (*) (void* buffer, NumarrayType type, int ndim, maybelong *shape) ) libnumarray_FatalApiError)) + +#define NA_ReturnOutput (libnumarray_API ? (*(PyObject* (*) (PyObject*,PyArrayObject*) ) libnumarray_API[ 24 ]) : (*(PyObject* (*) (PyObject*,PyArrayObject*) ) libnumarray_FatalApiError)) + +#define NA_getBufferPtrAndSize (libnumarray_API ? (*(long (*) (PyObject*,int,void**) ) libnumarray_API[ 25 ]) : (*(long (*) (PyObject*,int,void**) ) libnumarray_FatalApiError)) + +#define NA_checkIo (libnumarray_API ? (*(int (*) (char*,int,int,int,int) ) libnumarray_API[ 26 ]) : (*(int (*) (char*,int,int,int,int) ) libnumarray_FatalApiError)) + +#define NA_checkOneCBuffer (libnumarray_API ? (*(int (*) (char*,long,void*,long,size_t) ) libnumarray_API[ 27 ]) : (*(int (*) (char*,long,void*,long,size_t) ) libnumarray_FatalApiError)) + +#define NA_checkNCBuffers (libnumarray_API ? (*(int (*) (char*,int,long,void**,long*,Int8*,Int8*) ) libnumarray_API[ 28 ]) : (*(int (*) (char*,int,long,void**,long*,Int8*,Int8*) ) libnumarray_FatalApiError)) + +#define NA_checkOneStriding (libnumarray_API ? (*(int (*) (char*,long,maybelong*,long,maybelong*,long,long,int) ) libnumarray_API[ 29 ]) : (*(int (*) (char*,long,maybelong*,long,maybelong*,long,long,int) ) libnumarray_FatalApiError)) + +#define NA_new_cfunc (libnumarray_API ? (*(PyObject* (*) (CfuncDescriptor*) ) libnumarray_API[ 30 ]) : (*(PyObject* (*) (CfuncDescriptor*) ) libnumarray_FatalApiError)) + +#define NA_add_cfunc (libnumarray_API ? (*(int (*) (PyObject*,char*,CfuncDescriptor*) ) libnumarray_API[ 31 ]) : (*(int (*) (PyObject*,char*,CfuncDescriptor*) ) libnumarray_FatalApiError)) + +#define NA_InputArray (libnumarray_API ? (*(PyArrayObject* (*) (PyObject*,NumarrayType,int) ) libnumarray_API[ 32 ]) : (*(PyArrayObject* (*) (PyObject*,NumarrayType,int) ) libnumarray_FatalApiError)) + +#define NA_OutputArray (libnumarray_API ? (*(PyArrayObject* (*) (PyObject*,NumarrayType,int) ) libnumarray_API[ 33 ]) : (*(PyArrayObject* (*) (PyObject*,NumarrayType,int) ) libnumarray_FatalApiError)) + +#define NA_IoArray (libnumarray_API ? (*(PyArrayObject* (*) (PyObject*,NumarrayType,int) ) libnumarray_API[ 34 ]) : (*(PyArrayObject* (*) (PyObject*,NumarrayType,int) ) libnumarray_FatalApiError)) + +#define NA_OptionalOutputArray (libnumarray_API ? (*(PyArrayObject* (*) (PyObject*,NumarrayType,int,PyArrayObject*) ) libnumarray_API[ 35 ]) : (*(PyArrayObject* (*) (PyObject*,NumarrayType,int,PyArrayObject*) ) libnumarray_FatalApiError)) + +#define NA_get_offset (libnumarray_API ? (*(long (*) (PyArrayObject*,int,...) ) libnumarray_API[ 36 ]) : (*(long (*) (PyArrayObject*,int,...) ) libnumarray_FatalApiError)) + +#define NA_get_Float64 (libnumarray_API ? (*(Float64 (*) (PyArrayObject*,long) ) libnumarray_API[ 37 ]) : (*(Float64 (*) (PyArrayObject*,long) ) libnumarray_FatalApiError)) + +#define NA_set_Float64 (libnumarray_API ? (*(void (*) (PyArrayObject*,long,Float64) ) libnumarray_API[ 38 ]) : (*(void (*) (PyArrayObject*,long,Float64) ) libnumarray_FatalApiError)) + +#define NA_get_Complex64 (libnumarray_API ? (*(Complex64 (*) (PyArrayObject*,long) ) libnumarray_API[ 39 ]) : (*(Complex64 (*) (PyArrayObject*,long) ) libnumarray_FatalApiError)) + +#define NA_set_Complex64 (libnumarray_API ? (*(void (*) (PyArrayObject*,long,Complex64) ) libnumarray_API[ 40 ]) : (*(void (*) (PyArrayObject*,long,Complex64) ) libnumarray_FatalApiError)) + +#define NA_get_Int64 (libnumarray_API ? (*(Int64 (*) (PyArrayObject*,long) ) libnumarray_API[ 41 ]) : (*(Int64 (*) (PyArrayObject*,long) ) libnumarray_FatalApiError)) + +#define NA_set_Int64 (libnumarray_API ? (*(void (*) (PyArrayObject*,long,Int64) ) libnumarray_API[ 42 ]) : (*(void (*) (PyArrayObject*,long,Int64) ) libnumarray_FatalApiError)) + +#define NA_get1_Float64 (libnumarray_API ? (*(Float64 (*) (PyArrayObject*,long) ) libnumarray_API[ 43 ]) : (*(Float64 (*) (PyArrayObject*,long) ) libnumarray_FatalApiError)) + +#define NA_get2_Float64 (libnumarray_API ? (*(Float64 (*) (PyArrayObject*,long,long) ) libnumarray_API[ 44 ]) : (*(Float64 (*) (PyArrayObject*,long,long) ) libnumarray_FatalApiError)) + +#define NA_get3_Float64 (libnumarray_API ? (*(Float64 (*) (PyArrayObject*,long,long,long) ) libnumarray_API[ 45 ]) : (*(Float64 (*) (PyArrayObject*,long,long,long) ) libnumarray_FatalApiError)) + +#define NA_set1_Float64 (libnumarray_API ? (*(void (*) (PyArrayObject*,long,Float64) ) libnumarray_API[ 46 ]) : (*(void (*) (PyArrayObject*,long,Float64) ) libnumarray_FatalApiError)) + +#define NA_set2_Float64 (libnumarray_API ? (*(void (*) (PyArrayObject*,long,long,Float64) ) libnumarray_API[ 47 ]) : (*(void (*) (PyArrayObject*,long,long,Float64) ) libnumarray_FatalApiError)) + +#define NA_set3_Float64 (libnumarray_API ? (*(void (*) (PyArrayObject*,long,long,long,Float64) ) libnumarray_API[ 48 ]) : (*(void (*) (PyArrayObject*,long,long,long,Float64) ) libnumarray_FatalApiError)) + +#define NA_get1_Complex64 (libnumarray_API ? (*(Complex64 (*) (PyArrayObject*,long) ) libnumarray_API[ 49 ]) : (*(Complex64 (*) (PyArrayObject*,long) ) libnumarray_FatalApiError)) + +#define NA_get2_Complex64 (libnumarray_API ? (*(Complex64 (*) (PyArrayObject*,long,long) ) libnumarray_API[ 50 ]) : (*(Complex64 (*) (PyArrayObject*,long,long) ) libnumarray_FatalApiError)) + +#define NA_get3_Complex64 (libnumarray_API ? (*(Complex64 (*) (PyArrayObject*,long,long,long) ) libnumarray_API[ 51 ]) : (*(Complex64 (*) (PyArrayObject*,long,long,long) ) libnumarray_FatalApiError)) + +#define NA_set1_Complex64 (libnumarray_API ? (*(void (*) (PyArrayObject*,long,Complex64) ) libnumarray_API[ 52 ]) : (*(void (*) (PyArrayObject*,long,Complex64) ) libnumarray_FatalApiError)) + +#define NA_set2_Complex64 (libnumarray_API ? (*(void (*) (PyArrayObject*,long,long,Complex64) ) libnumarray_API[ 53 ]) : (*(void (*) (PyArrayObject*,long,long,Complex64) ) libnumarray_FatalApiError)) + +#define NA_set3_Complex64 (libnumarray_API ? (*(void (*) (PyArrayObject*,long,long,long,Complex64) ) libnumarray_API[ 54 ]) : (*(void (*) (PyArrayObject*,long,long,long,Complex64) ) libnumarray_FatalApiError)) + +#define NA_get1_Int64 (libnumarray_API ? (*(Int64 (*) (PyArrayObject*,long) ) libnumarray_API[ 55 ]) : (*(Int64 (*) (PyArrayObject*,long) ) libnumarray_FatalApiError)) + +#define NA_get2_Int64 (libnumarray_API ? (*(Int64 (*) (PyArrayObject*,long,long) ) libnumarray_API[ 56 ]) : (*(Int64 (*) (PyArrayObject*,long,long) ) libnumarray_FatalApiError)) + +#define NA_get3_Int64 (libnumarray_API ? (*(Int64 (*) (PyArrayObject*,long,long,long) ) libnumarray_API[ 57 ]) : (*(Int64 (*) (PyArrayObject*,long,long,long) ) libnumarray_FatalApiError)) + +#define NA_set1_Int64 (libnumarray_API ? (*(void (*) (PyArrayObject*,long,Int64) ) libnumarray_API[ 58 ]) : (*(void (*) (PyArrayObject*,long,Int64) ) libnumarray_FatalApiError)) + +#define NA_set2_Int64 (libnumarray_API ? (*(void (*) (PyArrayObject*,long,long,Int64) ) libnumarray_API[ 59 ]) : (*(void (*) (PyArrayObject*,long,long,Int64) ) libnumarray_FatalApiError)) + +#define NA_set3_Int64 (libnumarray_API ? (*(void (*) (PyArrayObject*,long,long,long,Int64) ) libnumarray_API[ 60 ]) : (*(void (*) (PyArrayObject*,long,long,long,Int64) ) libnumarray_FatalApiError)) + +#define NA_get1D_Float64 (libnumarray_API ? (*(int (*) (PyArrayObject*,long,int,Float64*) ) libnumarray_API[ 61 ]) : (*(int (*) (PyArrayObject*,long,int,Float64*) ) libnumarray_FatalApiError)) + +#define NA_set1D_Float64 (libnumarray_API ? (*(int (*) (PyArrayObject*,long,int,Float64*) ) libnumarray_API[ 62 ]) : (*(int (*) (PyArrayObject*,long,int,Float64*) ) libnumarray_FatalApiError)) + +#define NA_get1D_Int64 (libnumarray_API ? (*(int (*) (PyArrayObject*,long,int,Int64*) ) libnumarray_API[ 63 ]) : (*(int (*) (PyArrayObject*,long,int,Int64*) ) libnumarray_FatalApiError)) + +#define NA_set1D_Int64 (libnumarray_API ? (*(int (*) (PyArrayObject*,long,int,Int64*) ) libnumarray_API[ 64 ]) : (*(int (*) (PyArrayObject*,long,int,Int64*) ) libnumarray_FatalApiError)) + +#define NA_get1D_Complex64 (libnumarray_API ? (*(int (*) (PyArrayObject*,long,int,Complex64*) ) libnumarray_API[ 65 ]) : (*(int (*) (PyArrayObject*,long,int,Complex64*) ) libnumarray_FatalApiError)) + +#define NA_set1D_Complex64 (libnumarray_API ? (*(int (*) (PyArrayObject*,long,int,Complex64*) ) libnumarray_API[ 66 ]) : (*(int (*) (PyArrayObject*,long,int,Complex64*) ) libnumarray_FatalApiError)) + +#define NA_ShapeEqual (libnumarray_API ? (*(int (*) (PyArrayObject*,PyArrayObject*) ) libnumarray_API[ 67 ]) : (*(int (*) (PyArrayObject*,PyArrayObject*) ) libnumarray_FatalApiError)) + +#define NA_ShapeLessThan (libnumarray_API ? (*(int (*) (PyArrayObject*,PyArrayObject*) ) libnumarray_API[ 68 ]) : (*(int (*) (PyArrayObject*,PyArrayObject*) ) libnumarray_FatalApiError)) + +#define NA_ByteOrder (libnumarray_API ? (*(int (*) (void) ) libnumarray_API[ 69 ]) : (*(int (*) (void) ) libnumarray_FatalApiError)) + +#define NA_IeeeSpecial32 (libnumarray_API ? (*(Bool (*) (Float32*,Int32*) ) libnumarray_API[ 70 ]) : (*(Bool (*) (Float32*,Int32*) ) libnumarray_FatalApiError)) + +#define NA_IeeeSpecial64 (libnumarray_API ? (*(Bool (*) (Float64*,Int32*) ) libnumarray_API[ 71 ]) : (*(Bool (*) (Float64*,Int32*) ) libnumarray_FatalApiError)) + +#define NA_updateDataPtr (libnumarray_API ? (*(PyArrayObject* (*) (PyArrayObject*) ) libnumarray_API[ 72 ]) : (*(PyArrayObject* (*) (PyArrayObject*) ) libnumarray_FatalApiError)) + +#define NA_typeNoToName (libnumarray_API ? (*(char* (*) (int) ) libnumarray_API[ 73 ]) : (*(char* (*) (int) ) libnumarray_FatalApiError)) + +#define NA_nameToTypeNo (libnumarray_API ? (*(int (*) (char*) ) libnumarray_API[ 74 ]) : (*(int (*) (char*) ) libnumarray_FatalApiError)) + +#define NA_typeNoToTypeObject (libnumarray_API ? (*(PyObject* (*) (int) ) libnumarray_API[ 75 ]) : (*(PyObject* (*) (int) ) libnumarray_FatalApiError)) + +#define NA_intTupleFromMaybeLongs (libnumarray_API ? (*(PyObject* (*) (int,maybelong*) ) libnumarray_API[ 76 ]) : (*(PyObject* (*) (int,maybelong*) ) libnumarray_FatalApiError)) + +#define NA_maybeLongsFromIntTuple (libnumarray_API ? (*(long (*) (int,maybelong*,PyObject*) ) libnumarray_API[ 77 ]) : (*(long (*) (int,maybelong*,PyObject*) ) libnumarray_FatalApiError)) + +#define NA_intTupleProduct (libnumarray_API ? (*(int (*) (PyObject *obj, long *product) ) libnumarray_API[ 78 ]) : (*(int (*) (PyObject *obj, long *product) ) libnumarray_FatalApiError)) + +#define NA_isIntegerSequence (libnumarray_API ? (*(long (*) (PyObject*) ) libnumarray_API[ 79 ]) : (*(long (*) (PyObject*) ) libnumarray_FatalApiError)) + +#define NA_setArrayFromSequence (libnumarray_API ? (*(PyObject* (*) (PyArrayObject*,PyObject*) ) libnumarray_API[ 80 ]) : (*(PyObject* (*) (PyArrayObject*,PyObject*) ) libnumarray_FatalApiError)) + +#define NA_maxType (libnumarray_API ? (*(int (*) (PyObject*) ) libnumarray_API[ 81 ]) : (*(int (*) (PyObject*) ) libnumarray_FatalApiError)) + +#define NA_isPythonScalar (libnumarray_API ? (*(int (*) (PyObject *obj) ) libnumarray_API[ 82 ]) : (*(int (*) (PyObject *obj) ) libnumarray_FatalApiError)) + +#define NA_getPythonScalar (libnumarray_API ? (*(PyObject* (*) (PyArrayObject*,long) ) libnumarray_API[ 83 ]) : (*(PyObject* (*) (PyArrayObject*,long) ) libnumarray_FatalApiError)) + +#define NA_setFromPythonScalar (libnumarray_API ? (*(int (*) (PyArrayObject*,long,PyObject*) ) libnumarray_API[ 84 ]) : (*(int (*) (PyArrayObject*,long,PyObject*) ) libnumarray_FatalApiError)) + +#define NA_NDArrayCheck (libnumarray_API ? (*(int (*) (PyObject*) ) libnumarray_API[ 85 ]) : (*(int (*) (PyObject*) ) libnumarray_FatalApiError)) + +#define NA_NumArrayCheck (libnumarray_API ? (*(int (*) (PyObject*) ) libnumarray_API[ 86 ]) : (*(int (*) (PyObject*) ) libnumarray_FatalApiError)) + +#define NA_ComplexArrayCheck (libnumarray_API ? (*(int (*) (PyObject*) ) libnumarray_API[ 87 ]) : (*(int (*) (PyObject*) ) libnumarray_FatalApiError)) + +#define NA_elements (libnumarray_API ? (*(unsigned long (*) (PyArrayObject*) ) libnumarray_API[ 88 ]) : (*(unsigned long (*) (PyArrayObject*) ) libnumarray_FatalApiError)) + +#define NA_typeObjectToTypeNo (libnumarray_API ? (*(int (*) (PyObject*) ) libnumarray_API[ 89 ]) : (*(int (*) (PyObject*) ) libnumarray_FatalApiError)) + +#define NA_copyArray (libnumarray_API ? (*(int (*) (PyArrayObject* to, const PyArrayObject* from) ) libnumarray_API[ 90 ]) : (*(int (*) (PyArrayObject* to, const PyArrayObject* from) ) libnumarray_FatalApiError)) + +#define NA_copy (libnumarray_API ? (*(PyArrayObject* (*) (PyArrayObject*) ) libnumarray_API[ 91 ]) : (*(PyArrayObject* (*) (PyArrayObject*) ) libnumarray_FatalApiError)) + +#define NA_getType (libnumarray_API ? (*(PyObject* (*) (PyObject *typeobj_or_name) ) libnumarray_API[ 92 ]) : (*(PyObject* (*) (PyObject *typeobj_or_name) ) libnumarray_FatalApiError)) + +#define NA_callCUFuncCore (libnumarray_API ? (*(PyObject * (*) (PyObject *cfunc, long niter, long ninargs, long noutargs, PyObject **BufferObj, long *offset) ) libnumarray_API[ 93 ]) : (*(PyObject * (*) (PyObject *cfunc, long niter, long ninargs, long noutargs, PyObject **BufferObj, long *offset) ) libnumarray_FatalApiError)) + +#define NA_callStrideConvCFuncCore (libnumarray_API ? (*(PyObject * (*) (PyObject *cfunc, int nshape, maybelong *shape, PyObject *inbuffObj, long inboffset, int nstrides0, maybelong *inbstrides, PyObject *outbuffObj, long outboffset, int nstrides1, maybelong *outbstrides, long nbytes) ) libnumarray_API[ 94 ]) : (*(PyObject * (*) (PyObject *cfunc, int nshape, maybelong *shape, PyObject *inbuffObj, long inboffset, int nstrides0, maybelong *inbstrides, PyObject *outbuffObj, long outboffset, int nstrides1, maybelong *outbstrides, long nbytes) ) libnumarray_FatalApiError)) + +#define NA_stridesFromShape (libnumarray_API ? (*(void (*) (int nshape, maybelong *shape, maybelong bytestride, maybelong *strides) ) libnumarray_API[ 95 ]) : (*(void (*) (int nshape, maybelong *shape, maybelong bytestride, maybelong *strides) ) libnumarray_FatalApiError)) + +#define NA_OperatorCheck (libnumarray_API ? (*(int (*) (PyObject *obj) ) libnumarray_API[ 96 ]) : (*(int (*) (PyObject *obj) ) libnumarray_FatalApiError)) + +#define NA_ConverterCheck (libnumarray_API ? (*(int (*) (PyObject *obj) ) libnumarray_API[ 97 ]) : (*(int (*) (PyObject *obj) ) libnumarray_FatalApiError)) + +#define NA_UfuncCheck (libnumarray_API ? (*(int (*) (PyObject *obj) ) libnumarray_API[ 98 ]) : (*(int (*) (PyObject *obj) ) libnumarray_FatalApiError)) + +#define NA_CfuncCheck (libnumarray_API ? (*(int (*) (PyObject *obj) ) libnumarray_API[ 99 ]) : (*(int (*) (PyObject *obj) ) libnumarray_FatalApiError)) + +#define NA_getByteOffset (libnumarray_API ? (*(int (*) (PyArrayObject *array, int nindices, maybelong *indices, long *offset) ) libnumarray_API[ 100 ]) : (*(int (*) (PyArrayObject *array, int nindices, maybelong *indices, long *offset) ) libnumarray_FatalApiError)) + +#define NA_swapAxes (libnumarray_API ? (*(int (*) (PyArrayObject *array, int x, int y) ) libnumarray_API[ 101 ]) : (*(int (*) (PyArrayObject *array, int x, int y) ) libnumarray_FatalApiError)) + +#define NA_initModuleGlobal (libnumarray_API ? (*(PyObject * (*) (char *module, char *global) ) libnumarray_API[ 102 ]) : (*(PyObject * (*) (char *module, char *global) ) libnumarray_FatalApiError)) + +#define NA_NumarrayType (libnumarray_API ? (*(NumarrayType (*) (PyObject *seq) ) libnumarray_API[ 103 ]) : (*(NumarrayType (*) (PyObject *seq) ) libnumarray_FatalApiError)) + +#define NA_NewAllFromBuffer (libnumarray_API ? (*(PyArrayObject * (*) (int ndim, maybelong *shape, NumarrayType type, PyObject *bufferObject, maybelong byteoffset, maybelong bytestride, int byteorder, int aligned, int writeable) ) libnumarray_API[ 104 ]) : (*(PyArrayObject * (*) (int ndim, maybelong *shape, NumarrayType type, PyObject *bufferObject, maybelong byteoffset, maybelong bytestride, int byteorder, int aligned, int writeable) ) libnumarray_FatalApiError)) + +#define NA_alloc1D_Float64 (libnumarray_API ? (*(Float64 * (*) (PyArrayObject *a, long offset, int cnt) ) libnumarray_API[ 105 ]) : (*(Float64 * (*) (PyArrayObject *a, long offset, int cnt) ) libnumarray_FatalApiError)) + +#define NA_alloc1D_Int64 (libnumarray_API ? (*(Int64 * (*) (PyArrayObject *a, long offset, int cnt) ) libnumarray_API[ 106 ]) : (*(Int64 * (*) (PyArrayObject *a, long offset, int cnt) ) libnumarray_FatalApiError)) + +#define NA_updateAlignment (libnumarray_API ? (*(void (*) (PyArrayObject *self) ) libnumarray_API[ 107 ]) : (*(void (*) (PyArrayObject *self) ) libnumarray_FatalApiError)) + +#define NA_updateContiguous (libnumarray_API ? (*(void (*) (PyArrayObject *self) ) libnumarray_API[ 108 ]) : (*(void (*) (PyArrayObject *self) ) libnumarray_FatalApiError)) + +#define NA_updateStatus (libnumarray_API ? (*(void (*) (PyArrayObject *self) ) libnumarray_API[ 109 ]) : (*(void (*) (PyArrayObject *self) ) libnumarray_FatalApiError)) + +#define NA_NumArrayCheckExact (libnumarray_API ? (*(int (*) (PyObject *op) ) libnumarray_API[ 110 ]) : (*(int (*) (PyObject *op) ) libnumarray_FatalApiError)) + +#define NA_NDArrayCheckExact (libnumarray_API ? (*(int (*) (PyObject *op) ) libnumarray_API[ 111 ]) : (*(int (*) (PyObject *op) ) libnumarray_FatalApiError)) + +#define NA_OperatorCheckExact (libnumarray_API ? (*(int (*) (PyObject *op) ) libnumarray_API[ 112 ]) : (*(int (*) (PyObject *op) ) libnumarray_FatalApiError)) + +#define NA_ConverterCheckExact (libnumarray_API ? (*(int (*) (PyObject *op) ) libnumarray_API[ 113 ]) : (*(int (*) (PyObject *op) ) libnumarray_FatalApiError)) + +#define NA_UfuncCheckExact (libnumarray_API ? (*(int (*) (PyObject *op) ) libnumarray_API[ 114 ]) : (*(int (*) (PyObject *op) ) libnumarray_FatalApiError)) + +#define NA_CfuncCheckExact (libnumarray_API ? (*(int (*) (PyObject *op) ) libnumarray_API[ 115 ]) : (*(int (*) (PyObject *op) ) libnumarray_FatalApiError)) + +#define NA_getArrayData (libnumarray_API ? (*(char * (*) (PyArrayObject *ap) ) libnumarray_API[ 116 ]) : (*(char * (*) (PyArrayObject *ap) ) libnumarray_FatalApiError)) + +#define NA_updateByteswap (libnumarray_API ? (*(void (*) (PyArrayObject *ap) ) libnumarray_API[ 117 ]) : (*(void (*) (PyArrayObject *ap) ) libnumarray_FatalApiError)) + +#define NA_DescrFromType (libnumarray_API ? (*(PyArray_Descr * (*) (int type) ) libnumarray_API[ 118 ]) : (*(PyArray_Descr * (*) (int type) ) libnumarray_FatalApiError)) + +#define NA_Cast (libnumarray_API ? (*(PyObject * (*) (PyArrayObject *a, int type) ) libnumarray_API[ 119 ]) : (*(PyObject * (*) (PyArrayObject *a, int type) ) libnumarray_FatalApiError)) + +#define NA_checkFPErrors (libnumarray_API ? (*(int (*) (void) ) libnumarray_API[ 120 ]) : (*(int (*) (void) ) libnumarray_FatalApiError)) + +#define NA_clearFPErrors (libnumarray_API ? (*(void (*) (void) ) libnumarray_API[ 121 ]) : (*(void (*) (void) ) libnumarray_FatalApiError)) + +#define NA_checkAndReportFPErrors (libnumarray_API ? (*(int (*) (char *name) ) libnumarray_API[ 122 ]) : (*(int (*) (char *name) ) libnumarray_FatalApiError)) + +#define NA_IeeeMask32 (libnumarray_API ? (*(Bool (*) (Float32,Int32) ) libnumarray_API[ 123 ]) : (*(Bool (*) (Float32,Int32) ) libnumarray_FatalApiError)) + +#define NA_IeeeMask64 (libnumarray_API ? (*(Bool (*) (Float64,Int32) ) libnumarray_API[ 124 ]) : (*(Bool (*) (Float64,Int32) ) libnumarray_FatalApiError)) + +#define _NA_callStridingHelper (libnumarray_API ? (*(int (*) (PyObject *aux, long dim, long nnumarray, PyArrayObject *numarray[], char *data[], CFUNC_STRIDED_FUNC f) ) libnumarray_API[ 125 ]) : (*(int (*) (PyObject *aux, long dim, long nnumarray, PyArrayObject *numarray[], char *data[], CFUNC_STRIDED_FUNC f) ) libnumarray_FatalApiError)) + +#define NA_FromDimsStridesDescrAndData (libnumarray_API ? (*(PyArrayObject * (*) (int nd, maybelong *dims, maybelong *strides, PyArray_Descr *descr, char *data) ) libnumarray_API[ 126 ]) : (*(PyArrayObject * (*) (int nd, maybelong *dims, maybelong *strides, PyArray_Descr *descr, char *data) ) libnumarray_FatalApiError)) + +#define NA_FromDimsTypeAndData (libnumarray_API ? (*(PyArrayObject * (*) (int nd, maybelong *dims, int type, char *data) ) libnumarray_API[ 127 ]) : (*(PyArrayObject * (*) (int nd, maybelong *dims, int type, char *data) ) libnumarray_FatalApiError)) + +#define NA_FromDimsStridesTypeAndData (libnumarray_API ? (*(PyArrayObject * (*) (int nd, maybelong *dims, maybelong *strides, int type, char *data) ) libnumarray_API[ 128 ]) : (*(PyArrayObject * (*) (int nd, maybelong *dims, maybelong *strides, int type, char *data) ) libnumarray_FatalApiError)) + +#define NA_scipy_typestr (libnumarray_API ? (*(int (*) (NumarrayType t, int byteorder, char *typestr) ) libnumarray_API[ 129 ]) : (*(int (*) (NumarrayType t, int byteorder, char *typestr) ) libnumarray_FatalApiError)) + +#define NA_FromArrayStruct (libnumarray_API ? (*(PyArrayObject * (*) (PyObject *a) ) libnumarray_API[ 130 ]) : (*(PyArrayObject * (*) (PyObject *a) ) libnumarray_FatalApiError)) + +#endif + + /* Total number of C API pointers */ +#define libnumarray_API_pointers 131 + +#ifdef __cplusplus +} +#endif + +#endif /* NUMPY_LIBNUMARRAY_H */ diff --git a/numpy/numarray/numpy/numcomplex.h b/numpy/numarray/numpy/numcomplex.h new file mode 100644 index 000000000..9ed4198c7 --- /dev/null +++ b/numpy/numarray/numpy/numcomplex.h @@ -0,0 +1,252 @@ +/* See numarray.h for Complex32, Complex64: + +typedef struct { Float32 r, i; } Complex32; +typedef struct { Float64 r, i; } Complex64; + +*/ +typedef struct { Float32 a, theta; } PolarComplex32; +typedef struct { Float64 a, theta; } PolarComplex64; + +#define NUM_SQ(x) ((x)*(x)) + +#define NUM_CABSSQ(p) (NUM_SQ((p).r) + NUM_SQ((p).i)) + +#define NUM_CABS(p) sqrt(NUM_CABSSQ(p)) + +#define NUM_C_TO_P(c, p) (p).a = NUM_CABS(c); \ + (p).theta = atan2((c).i, (c).r); + +#define NUM_P_TO_C(p, c) (c).r = (p).a*cos((p).theta); \ + (c).i = (p).a*sin((p).theta); + +#define NUM_CASS(p, q) (q).r = (p).r, (q).i = (p).i + +#define NUM_CADD(p, q, s) (s).r = (p).r + (q).r, \ + (s).i = (p).i + (q).i + +#define NUM_CSUB(p, q, s) (s).r = (p).r - (q).r, \ + (s).i = (p).i - (q).i + +#define NUM_CMUL(p, q, s) \ + { Float64 rp = (p).r; \ + Float64 rq = (q).r; \ + (s).r = rp*rq - (p).i*(q).i; \ + (s).i = rp*(q).i + rq*(p).i; \ + } + +#define NUM_CDIV(p, q, s) \ + { \ + Float64 rp = (p).r; \ + Float64 ip = (p).i; \ + Float64 rq = (q).r; \ + if ((q).i != 0) { \ + Float64 temp = NUM_CABSSQ(q); \ + (s).r = (rp*rq+(p).i*(q).i)/temp; \ + (s).i = (rq*(p).i-(q).i*rp)/temp; \ + } else { \ + (s).r = rp/rq; \ + (s).i = ip/rq; \ + } \ + } + +#define NUM_CREM(p, q, s) \ + { Complex64 r; \ + NUM_CDIV(p, q, r); \ + r.r = floor(r.r); \ + r.i = 0; \ + NUM_CMUL(r, q, r); \ + NUM_CSUB(p, r, s); \ + } + +#define NUM_CMINUS(p, s) (s).r = -(p).r; (s).i = -(p).i; +#define NUM_CNEG NUM_CMINUS + +#define NUM_CEQ(p, q) (((p).r == (q).r) && ((p).i == (q).i)) +#define NUM_CNE(p, q) (((p).r != (q).r) || ((p).i != (q).i)) +#define NUM_CLT(p, q) ((p).r < (q).r) +#define NUM_CGT(p, q) ((p).r > (q).r) +#define NUM_CLE(p, q) ((p).r <= (q).r) +#define NUM_CGE(p, q) ((p).r >= (q).r) + +/* e**z = e**x * (cos(y)+ i*sin(y)) where z = x + i*y + so e**z = e**x * cos(y) + i * e**x * sin(y) +*/ +#define NUM_CEXP(p, s) \ + { Float64 ex = exp((p).r); \ + (s).r = ex * cos((p).i); \ + (s).i = ex * sin((p).i); \ + } + +/* e**w = z; w = u + i*v; z = r * e**(i*theta); + +e**u * e**(i*v) = r * e**(i*theta); + +log(z) = w; log(z) = log(r) + i*theta; + */ +#define NUM_CLOG(p, s) \ + { PolarComplex64 temp; NUM_C_TO_P(p, temp); \ + (s).r = num_log(temp.a); \ + (s).i = temp.theta; \ + } + +#define NUM_LOG10_E 0.43429448190325182 + +#define NUM_CLOG10(p, s) \ + { NUM_CLOG(p, s); \ + (s).r *= NUM_LOG10_E; \ + (s).i *= NUM_LOG10_E; \ + } + +/* s = p ** q */ +#define NUM_CPOW(p, q, s) { if (NUM_CABSSQ(p) == 0) { \ + if ((q).r == 0 && (q).i == 0) { \ + (s).r = (s).i = 1; \ + } else { \ + (s).r = (s).i = 0; \ + } \ + } else { \ + NUM_CLOG(p, s); \ + NUM_CMUL(s, q, s); \ + NUM_CEXP(s, s); \ + } \ + } + +#define NUM_CSQRT(p, s) { Complex64 temp; temp.r = 0.5; temp.i=0; \ + NUM_CPOW(p, temp, s); \ + } + +#define NUM_CSQR(p, s) { Complex64 temp; temp.r = 2.0; temp.i=0; \ + NUM_CPOW(p, temp, s); \ + } + +#define NUM_CSIN(p, s) { Float64 sp = sin((p).r); \ + Float64 cp = cos((p).r); \ + (s).r = cosh((p).i) * sp; \ + (s).i = sinh((p).i) * cp; \ + } + +#define NUM_CCOS(p, s) { Float64 sp = sin((p).r); \ + Float64 cp = cos((p).r); \ + (s).r = cosh((p).i) * cp; \ + (s).i = -sinh((p).i) * sp; \ + } + +#define NUM_CTAN(p, s) { Complex64 ss, cs; \ + NUM_CSIN(p, ss); \ + NUM_CCOS(p, cs); \ + NUM_CDIV(ss, cs, s); \ + } + +#define NUM_CSINH(p, s) { Float64 sp = sin((p).i); \ + Float64 cp = cos((p).i); \ + (s).r = sinh((p).r) * cp; \ + (s).i = cosh((p).r) * sp; \ + } + +#define NUM_CCOSH(p, s) { Float64 sp = sin((p).i); \ + Float64 cp = cos((p).i); \ + (s).r = cosh((p).r) * cp; \ + (s).i = sinh((p).r) * sp; \ + } + +#define NUM_CTANH(p, s) { Complex64 ss, cs; \ + NUM_CSINH(p, ss); \ + NUM_CCOSH(p, cs); \ + NUM_CDIV(ss, cs, s); \ + } + +#define NUM_CRPOW(p, v, s) { Complex64 cr; cr.r = v; cr.i = 0; \ + NUM_CPOW(p,cr,s); \ + } + +#define NUM_CRMUL(p, v, s) (s).r = (p).r * v; (s).i = (p).i * v; + +#define NUM_CIMUL(p, s) { Float64 temp = (s).r; \ + (s).r = -(p).i; (s).i = temp; \ + } + +/* asin(z) = -i * log(i*z + (1 - z**2)**0.5) */ +#define NUM_CASIN(p, s) { Complex64 p1; NUM_CASS(p, p1); \ + NUM_CIMUL(p, p1); \ + NUM_CMUL(p, p, s); \ + NUM_CNEG(s, s); \ + (s).r += 1; \ + NUM_CRPOW(s, 0.5, s); \ + NUM_CADD(p1, s, s); \ + NUM_CLOG(s, s); \ + NUM_CIMUL(s, s); \ + NUM_CNEG(s, s); \ + } + +/* acos(z) = -i * log(z + i*(1 - z**2)**0.5) */ +#define NUM_CACOS(p, s) { Complex64 p1; NUM_CASS(p, p1); \ + NUM_CMUL(p, p, s); \ + NUM_CNEG(s, s); \ + (s).r += 1; \ + NUM_CRPOW(s, 0.5, s); \ + NUM_CIMUL(s, s); \ + NUM_CADD(p1, s, s); \ + NUM_CLOG(s, s); \ + NUM_CIMUL(s, s); \ + NUM_CNEG(s, s); \ + } + +/* atan(z) = i/2 * log( (i+z) / (i - z) ) */ +#define NUM_CATAN(p, s) { Complex64 p1, p2; \ + NUM_CASS(p, p1); NUM_CNEG(p, p2); \ + p1.i += 1; \ + p2.i += 1; \ + NUM_CDIV(p1, p2, s); \ + NUM_CLOG(s, s); \ + NUM_CIMUL(s, s); \ + NUM_CRMUL(s, 0.5, s); \ + } + +/* asinh(z) = log( z + (z**2 + 1)**0.5 ) */ +#define NUM_CASINH(p, s) { Complex64 p1; NUM_CASS(p, p1); \ + NUM_CMUL(p, p, s); \ + (s).r += 1; \ + NUM_CRPOW(s, 0.5, s); \ + NUM_CADD(p1, s, s); \ + NUM_CLOG(s, s); \ + } + +/* acosh(z) = log( z + (z**2 - 1)**0.5 ) */ +#define NUM_CACOSH(p, s) { Complex64 p1; NUM_CASS(p, p1); \ + NUM_CMUL(p, p, s); \ + (s).r -= 1; \ + NUM_CRPOW(s, 0.5, s); \ + NUM_CADD(p1, s, s); \ + NUM_CLOG(s, s); \ + } + +/* atanh(z) = 1/2 * log( (1+z)/(1-z) ) */ +#define NUM_CATANH(p, s) { Complex64 p1, p2; \ + NUM_CASS(p, p1); NUM_CNEG(p, p2); \ + p1.r += 1; \ + p2.r += 1; \ + NUM_CDIV(p1, p2, s); \ + NUM_CLOG(s, s); \ + NUM_CRMUL(s, 0.5, s); \ + } + + +#define NUM_CMIN(p, q) (NUM_CLE(p, q) ? p : q) +#define NUM_CMAX(p, q) (NUM_CGE(p, q) ? p : q) + +#define NUM_CNZ(p) (((p).r != 0) || ((p).i != 0)) +#define NUM_CLAND(p, q) (NUM_CNZ(p) & NUM_CNZ(q)) +#define NUM_CLOR(p, q) (NUM_CNZ(p) | NUM_CNZ(q)) +#define NUM_CLXOR(p, q) (NUM_CNZ(p) ^ NUM_CNZ(q)) +#define NUM_CLNOT(p) (!NUM_CNZ(p)) + +#define NUM_CFLOOR(p, s) (s).r = floor((p).r); (s).i = floor((p).i); +#define NUM_CCEIL(p, s) (s).r = ceil((p).r); (s).i = ceil((p).i); + +#define NUM_CFABS(p, s) (s).r = fabs((p).r); (s).i = fabs((p).i); +#define NUM_CROUND(p, s) (s).r = num_round((p).r); (s).i = num_round((p).i); +#define NUM_CHYPOT(p, q, s) { Complex64 t; \ + NUM_CSQR(p, s); NUM_CSQR(q, t); \ + NUM_CADD(s, t, s); \ + NUM_CSQRT(s, s); \ + } diff --git a/numpy/numarray/numpy/nummacro.h b/numpy/numarray/numpy/nummacro.h new file mode 100644 index 000000000..e9acd6e31 --- /dev/null +++ b/numpy/numarray/numpy/nummacro.h @@ -0,0 +1,447 @@ +/* Primarily for compatibility with numarray C-API */ + +#if !defined(_ndarraymacro) +#define _ndarraymacro + +/* The structs defined here are private implementation details of numarray +which are subject to change w/o notice. +*/ + +#define PY_BOOL_CHAR "b" +#define PY_INT8_CHAR "b" +#define PY_INT16_CHAR "h" +#define PY_INT32_CHAR "i" +#define PY_FLOAT32_CHAR "f" +#define PY_FLOAT64_CHAR "d" +#define PY_UINT8_CHAR "h" +#define PY_UINT16_CHAR "i" +#define PY_UINT32_CHAR "i" /* Unless longer int available */ +#define PY_COMPLEX64_CHAR "D" +#define PY_COMPLEX128_CHAR "D" + +#define PY_LONG_CHAR "l" +#define PY_LONG_LONG_CHAR "L" + +#define pyFPE_DIVIDE_BY_ZERO 1 +#define pyFPE_OVERFLOW 2 +#define pyFPE_UNDERFLOW 4 +#define pyFPE_INVALID 8 + +#define isNonZERO(x) (x != 0) /* to convert values to boolean 1's or 0's */ + +typedef enum +{ + NUM_CONTIGUOUS=1, + NUM_NOTSWAPPED=0x0200, + NUM_ALIGNED=0x0100, + NUM_WRITABLE=0x0400, + NUM_COPY=0x0020, + + NUM_C_ARRAY = (NUM_CONTIGUOUS | NUM_ALIGNED | NUM_NOTSWAPPED), + NUM_UNCONVERTED = 0 +} NumRequirements; + +#define UNCONVERTED 0 +#define C_ARRAY (NUM_CONTIGUOUS | NUM_NOTSWAPPED | NUM_ALIGNED) + +#define MUST_BE_COMPUTED 2 + +#define NUM_FLOORDIVIDE(a,b,out) (out) = floor((a)/(b)) + +#define NA_Begin() Py_Initialize(); import_libnumarray(); +#define NA_End() NA_Done(); Py_Finalize(); + +#define NA_OFFSETDATA(num) ((void *) PyArray_DATA(num)) + +/* unaligned NA_COPY functions */ +#define NA_COPY1(i, o) (*(o) = *(i)) +#define NA_COPY2(i, o) NA_COPY1(i, o), NA_COPY1(i+1, o+1) +#define NA_COPY4(i, o) NA_COPY2(i, o), NA_COPY2(i+2, o+2) +#define NA_COPY8(i, o) NA_COPY4(i, o), NA_COPY4(i+4, o+4) +#define NA_COPY16(i, o) NA_COPY8(i, o), NA_COPY8(i+8, o+8) + +/* byteswapping macros: these fail if i==o */ +#define NA_SWAP1(i, o) NA_COPY1(i, o) +#define NA_SWAP2(i, o) NA_SWAP1(i, o+1), NA_SWAP1(i+1, o) +#define NA_SWAP4(i, o) NA_SWAP2(i, o+2), NA_SWAP2(i+2, o) +#define NA_SWAP8(i, o) NA_SWAP4(i, o+4), NA_SWAP4(i+4, o) +#define NA_SWAP16(i, o) NA_SWAP8(i, o+8), NA_SWAP8(i+8, o) + +/* complex byteswaps must swap each part (real, imag) independently */ +#define NA_COMPLEX_SWAP8(i, o) NA_SWAP4(i, o), NA_SWAP4(i+4, o+4) +#define NA_COMPLEX_SWAP16(i, o) NA_SWAP8(i, o), NA_SWAP8(i+8, o+8) + +/* byteswapping macros: these work even if i == o */ +#define NA_TSWAP1(i, o, t) NA_COPY1(i, t), NA_SWAP1(t, o) +#define NA_TSWAP2(i, o, t) NA_COPY2(i, t), NA_SWAP2(t, o) +#define NA_TSWAP4(i, o, t) NA_COPY4(i, t), NA_SWAP4(t, o) +#define NA_TSWAP8(i, o, t) NA_COPY8(i, t), NA_SWAP8(t, o) + +/* fast copy functions for %N aligned i and o */ +#define NA_ACOPY1(i, o) (((Int8 *)o)[0] = ((Int8 *)i)[0]) +#define NA_ACOPY2(i, o) (((Int16 *)o)[0] = ((Int16 *)i)[0]) +#define NA_ACOPY4(i, o) (((Int32 *)o)[0] = ((Int32 *)i)[0]) +#define NA_ACOPY8(i, o) (((Float64 *)o)[0] = ((Float64 *)i)[0]) +#define NA_ACOPY16(i, o) (((Complex64 *)o)[0] = ((Complex64 *)i)[0]) + +/* from here down, type("ai") is NDInfo* */ + +#define NA_PTR(ai) ((char *) NA_OFFSETDATA((ai))) +#define NA_PTR1(ai, i) (NA_PTR(ai) + \ + (i)*(ai)->strides[0]) +#define NA_PTR2(ai, i, j) (NA_PTR(ai) + \ + (i)*(ai)->strides[0] + \ + (j)*(ai)->strides[1]) +#define NA_PTR3(ai, i, j, k) (NA_PTR(ai) + \ + (i)*(ai)->strides[0] + \ + (j)*(ai)->strides[1] + \ + (k)*(ai)->strides[2]) + +#define NA_SET_TEMP(ai, type, v) (((type *) &__temp__)[0] = v) + +#define NA_SWAPComplex64 NA_COMPLEX_SWAP16 +#define NA_SWAPComplex32 NA_COMPLEX_SWAP8 +#define NA_SWAPFloat64 NA_SWAP8 +#define NA_SWAPFloat32 NA_SWAP4 +#define NA_SWAPInt64 NA_SWAP8 +#define NA_SWAPUInt64 NA_SWAP8 +#define NA_SWAPInt32 NA_SWAP4 +#define NA_SWAPUInt32 NA_SWAP4 +#define NA_SWAPInt16 NA_SWAP2 +#define NA_SWAPUInt16 NA_SWAP2 +#define NA_SWAPInt8 NA_SWAP1 +#define NA_SWAPUInt8 NA_SWAP1 +#define NA_SWAPBool NA_SWAP1 + +#define NA_COPYComplex64 NA_COPY16 +#define NA_COPYComplex32 NA_COPY8 +#define NA_COPYFloat64 NA_COPY8 +#define NA_COPYFloat32 NA_COPY4 +#define NA_COPYInt64 NA_COPY8 +#define NA_COPYUInt64 NA_COPY8 +#define NA_COPYInt32 NA_COPY4 +#define NA_COPYUInt32 NA_COPY4 +#define NA_COPYInt16 NA_COPY2 +#define NA_COPYUInt16 NA_COPY2 +#define NA_COPYInt8 NA_COPY1 +#define NA_COPYUInt8 NA_COPY1 +#define NA_COPYBool NA_COPY1 + +#ifdef __cplusplus +extern "C" { +#endif + +#define _makeGetPb(type) \ +static type _NA_GETPb_##type(char *ptr) \ +{ \ + type temp; \ + NA_SWAP##type(ptr, (char *)&temp); \ + return temp; \ +} + +#define _makeGetPa(type) \ +static type _NA_GETPa_##type(char *ptr) \ +{ \ + type temp; \ + NA_COPY##type(ptr, (char *)&temp); \ + return temp; \ +} + +_makeGetPb(Complex64) +_makeGetPb(Complex32) +_makeGetPb(Float64) +_makeGetPb(Float32) +_makeGetPb(Int64) +_makeGetPb(UInt64) +_makeGetPb(Int32) +_makeGetPb(UInt32) +_makeGetPb(Int16) +_makeGetPb(UInt16) +_makeGetPb(Int8) +_makeGetPb(UInt8) +_makeGetPb(Bool) + +_makeGetPa(Complex64) +_makeGetPa(Complex32) +_makeGetPa(Float64) +_makeGetPa(Float32) +_makeGetPa(Int64) +_makeGetPa(UInt64) +_makeGetPa(Int32) +_makeGetPa(UInt32) +_makeGetPa(Int16) +_makeGetPa(UInt16) +_makeGetPa(Int8) +_makeGetPa(UInt8) +_makeGetPa(Bool) + +#undef _makeGetPb +#undef _makeGetPa + +#define _makeSetPb(type) \ +static void _NA_SETPb_##type(char *ptr, type v) \ +{ \ + NA_SWAP##type(((char *)&v), ptr); \ + return; \ +} + +#define _makeSetPa(type) \ +static void _NA_SETPa_##type(char *ptr, type v) \ +{ \ + NA_COPY##type(((char *)&v), ptr); \ + return; \ +} + +_makeSetPb(Complex64) +_makeSetPb(Complex32) +_makeSetPb(Float64) +_makeSetPb(Float32) +_makeSetPb(Int64) +_makeSetPb(UInt64) +_makeSetPb(Int32) +_makeSetPb(UInt32) +_makeSetPb(Int16) +_makeSetPb(UInt16) +_makeSetPb(Int8) +_makeSetPb(UInt8) +_makeSetPb(Bool) + +_makeSetPa(Complex64) +_makeSetPa(Complex32) +_makeSetPa(Float64) +_makeSetPa(Float32) +_makeSetPa(Int64) +_makeSetPa(UInt64) +_makeSetPa(Int32) +_makeSetPa(UInt32) +_makeSetPa(Int16) +_makeSetPa(UInt16) +_makeSetPa(Int8) +_makeSetPa(UInt8) +_makeSetPa(Bool) + +#undef _makeSetPb +#undef _makeSetPa + +#ifdef __cplusplus + } +#endif + +/* ========================== ptr get/set ================================ */ + +/* byteswapping */ +#define NA_GETPb(ai, type, ptr) _NA_GETPb_##type(ptr) + +/* aligning */ +#define NA_GETPa(ai, type, ptr) _NA_GETPa_##type(ptr) + +/* fast (aligned, !byteswapped) */ +#define NA_GETPf(ai, type, ptr) (*((type *) (ptr))) + +#define NA_GETP(ai, type, ptr) \ + (PyArray_ISCARRAY(ai) ? NA_GETPf(ai, type, ptr) \ + : (PyArray_ISBYTESWAPPED(ai) ? \ + NA_GETPb(ai, type, ptr) \ + : NA_GETPa(ai, type, ptr))) + +/* NOTE: NA_SET* macros cannot be used as values. */ + +/* byteswapping */ +#define NA_SETPb(ai, type, ptr, v) _NA_SETPb_##type(ptr, v) + +/* aligning */ +#define NA_SETPa(ai, type, ptr, v) _NA_SETPa_##type(ptr, v) + +/* fast (aligned, !byteswapped) */ +#define NA_SETPf(ai, type, ptr, v) ((*((type *) ptr)) = (v)) + +#define NA_SETP(ai, type, ptr, v) \ + if (PyArray_ISCARRAY(ai)) { \ + NA_SETPf((ai), type, (ptr), (v)); \ + } else if (PyArray_ISBYTESWAPPED(ai)) { \ + NA_SETPb((ai), type, (ptr), (v)); \ + } else \ + NA_SETPa((ai), type, (ptr), (v)) + +/* ========================== 1 index get/set ============================ */ + +/* byteswapping */ +#define NA_GET1b(ai, type, i) NA_GETPb(ai, type, NA_PTR1(ai, i)) +/* aligning */ +#define NA_GET1a(ai, type, i) NA_GETPa(ai, type, NA_PTR1(ai, i)) +/* fast (aligned, !byteswapped) */ +#define NA_GET1f(ai, type, i) NA_GETPf(ai, type, NA_PTR1(ai, i)) +/* testing */ +#define NA_GET1(ai, type, i) NA_GETP(ai, type, NA_PTR1(ai, i)) + +/* byteswapping */ +#define NA_SET1b(ai, type, i, v) NA_SETPb(ai, type, NA_PTR1(ai, i), v) +/* aligning */ +#define NA_SET1a(ai, type, i, v) NA_SETPa(ai, type, NA_PTR1(ai, i), v) +/* fast (aligned, !byteswapped) */ +#define NA_SET1f(ai, type, i, v) NA_SETPf(ai, type, NA_PTR1(ai, i), v) +/* testing */ +#define NA_SET1(ai, type, i, v) NA_SETP(ai, type, NA_PTR1(ai, i), v) + +/* ========================== 2 index get/set ============================= */ + +/* byteswapping */ +#define NA_GET2b(ai, type, i, j) NA_GETPb(ai, type, NA_PTR2(ai, i, j)) +/* aligning */ +#define NA_GET2a(ai, type, i, j) NA_GETPa(ai, type, NA_PTR2(ai, i, j)) +/* fast (aligned, !byteswapped) */ +#define NA_GET2f(ai, type, i, j) NA_GETPf(ai, type, NA_PTR2(ai, i, j)) +/* testing */ +#define NA_GET2(ai, type, i, j) NA_GETP(ai, type, NA_PTR2(ai, i, j)) + +/* byteswapping */ +#define NA_SET2b(ai, type, i, j, v) NA_SETPb(ai, type, NA_PTR2(ai, i, j), v) +/* aligning */ +#define NA_SET2a(ai, type, i, j, v) NA_SETPa(ai, type, NA_PTR2(ai, i, j), v) +/* fast (aligned, !byteswapped) */ +#define NA_SET2f(ai, type, i, j, v) NA_SETPf(ai, type, NA_PTR2(ai, i, j), v) + +#define NA_SET2(ai, type, i, j, v) NA_SETP(ai, type, NA_PTR2(ai, i, j), v) + +/* ========================== 3 index get/set ============================= */ + +/* byteswapping */ +#define NA_GET3b(ai, type, i, j, k) NA_GETPb(ai, type, NA_PTR3(ai, i, j, k)) +/* aligning */ +#define NA_GET3a(ai, type, i, j, k) NA_GETPa(ai, type, NA_PTR3(ai, i, j, k)) +/* fast (aligned, !byteswapped) */ +#define NA_GET3f(ai, type, i, j, k) NA_GETPf(ai, type, NA_PTR3(ai, i, j, k)) +/* testing */ +#define NA_GET3(ai, type, i, j, k) NA_GETP(ai, type, NA_PTR3(ai, i, j, k)) + +/* byteswapping */ +#define NA_SET3b(ai, type, i, j, k, v) \ + NA_SETPb(ai, type, NA_PTR3(ai, i, j, k), v) +/* aligning */ +#define NA_SET3a(ai, type, i, j, k, v) \ + NA_SETPa(ai, type, NA_PTR3(ai, i, j, k), v) +/* fast (aligned, !byteswapped) */ +#define NA_SET3f(ai, type, i, j, k, v) \ + NA_SETPf(ai, type, NA_PTR3(ai, i, j, k), v) +#define NA_SET3(ai, type, i, j, k, v) \ + NA_SETP(ai, type, NA_PTR3(ai, i, j, k), v) + +/* ========================== 1D get/set ================================== */ + +#define NA_GET1Db(ai, type, base, cnt, out) \ + { int i, stride = ai->strides[ai->nd-1]; \ + for(i=0; i<cnt; i++) { \ + out[i] = NA_GETPb(ai, type, base); \ + base += stride; \ + } \ + } + +#define NA_GET1Da(ai, type, base, cnt, out) \ + { int i, stride = ai->strides[ai->nd-1]; \ + for(i=0; i<cnt; i++) { \ + out[i] = NA_GETPa(ai, type, base); \ + base += stride; \ + } \ + } + +#define NA_GET1Df(ai, type, base, cnt, out) \ + { int i, stride = ai->strides[ai->nd-1]; \ + for(i=0; i<cnt; i++) { \ + out[i] = NA_GETPf(ai, type, base); \ + base += stride; \ + } \ + } + +#define NA_GET1D(ai, type, base, cnt, out) \ + if (PyArray_ISCARRAY(ai)) { \ + NA_GET1Df(ai, type, base, cnt, out); \ + } else if (PyArray_ISBYTESWAPPED(ai)) { \ + NA_GET1Db(ai, type, base, cnt, out); \ + } else { \ + NA_GET1Da(ai, type, base, cnt, out); \ + } + +#define NA_SET1Db(ai, type, base, cnt, in) \ + { int i, stride = ai->strides[ai->nd-1]; \ + for(i=0; i<cnt; i++) { \ + NA_SETPb(ai, type, base, in[i]); \ + base += stride; \ + } \ + } + +#define NA_SET1Da(ai, type, base, cnt, in) \ + { int i, stride = ai->strides[ai->nd-1]; \ + for(i=0; i<cnt; i++) { \ + NA_SETPa(ai, type, base, in[i]); \ + base += stride; \ + } \ + } + +#define NA_SET1Df(ai, type, base, cnt, in) \ + { int i, stride = ai->strides[ai->nd-1]; \ + for(i=0; i<cnt; i++) { \ + NA_SETPf(ai, type, base, in[i]); \ + base += stride; \ + } \ + } + +#define NA_SET1D(ai, type, base, cnt, out) \ + if (PyArray_ISCARRAY(ai)) { \ + NA_SET1Df(ai, type, base, cnt, out); \ + } else if (PyArray_ISBYTESWAPPED(ai)) { \ + NA_SET1Db(ai, type, base, cnt, out); \ + } else { \ + NA_SET1Da(ai, type, base, cnt, out); \ + } + +/* ========================== utilities ================================== */ + +#if !defined(MIN) +#define MIN(x,y) (((x)<=(y)) ? (x) : (y)) +#endif + +#if !defined(MAX) +#define MAX(x,y) (((x)>=(y)) ? (x) : (y)) +#endif + +#if !defined(ABS) +#define ABS(x) (((x) >= 0) ? (x) : -(x)) +#endif + +#define ELEM(x) (sizeof(x)/sizeof(x[0])) + +#define BOOLEAN_BITWISE_NOT(x) ((x) ^ 1) + +#define NA_NBYTES(a) (a->descr->elsize * NA_elements(a)) + +#if defined(NA_SMP) +#define BEGIN_THREADS Py_BEGIN_ALLOW_THREADS +#define END_THREADS Py_END_ALLOW_THREADS +#else +#define BEGIN_THREADS +#define END_THREADS +#endif + +#if !defined(NA_isnan) + +#define U32(u) (* (Int32 *) &(u) ) +#define U64(u) (* (Int64 *) &(u) ) + +#define NA_isnan32(u) \ + ( (( U32(u) & 0x7f800000) == 0x7f800000) && ((U32(u) & 0x007fffff) != 0)) ? 1:0 + +#if !defined(_MSC_VER) +#define NA_isnan64(u) \ + ( (( U64(u) & 0x7ff0000000000000LL) == 0x7ff0000000000000LL) && ((U64(u) & 0x000fffffffffffffLL) != 0)) ? 1:0 +#else +#define NA_isnan64(u) \ + ( (( U64(u) & 0x7ff0000000000000i64) == 0x7ff0000000000000i64) && ((U64(u) & 0x000fffffffffffffi64) != 0)) ? 1:0 +#endif + +#define NA_isnanC32(u) (NA_isnan32(((Complex32 *)&(u))->r) || NA_isnan32(((Complex32 *)&(u))->i)) +#define NA_isnanC64(u) (NA_isnan64(((Complex64 *)&(u))->r) || NA_isnan64(((Complex64 *)&(u))->i)) + +#endif /* NA_isnan */ + + +#endif /* _ndarraymacro */ diff --git a/numpy/numarray/random_array.py b/numpy/numarray/random_array.py new file mode 100644 index 000000000..d70e2694a --- /dev/null +++ b/numpy/numarray/random_array.py @@ -0,0 +1,9 @@ + +__all__ = ['ArgumentError', 'F', 'beta', 'binomial', 'chi_square', + 'exponential', 'gamma', 'get_seed', 'multinomial', + 'multivariate_normal', 'negative_binomial', 'noncentral_F', + 'noncentral_chi_square', 'normal', 'permutation', 'poisson', + 'randint', 'random', 'random_integers', 'standard_normal', + 'uniform', 'seed'] + +from numpy.oldnumeric.random_array import * diff --git a/numpy/numarray/session.py b/numpy/numarray/session.py new file mode 100644 index 000000000..ee155f9dc --- /dev/null +++ b/numpy/numarray/session.py @@ -0,0 +1,348 @@ +""" This module contains a "session saver" which saves the state of a +NumPy session to a file. At a later time, a different Python +process can be started and the saved session can be restored using +load(). + +The session saver relies on the Python pickle protocol to save and +restore objects. Objects which are not themselves picklable (e.g. +modules) can sometimes be saved by "proxy", particularly when they +are global constants of some kind. If it's not known that proxying +will work, a warning is issued at save time. If a proxy fails to +reload properly (e.g. because it's not a global constant), a warning +is issued at reload time and that name is bound to a _ProxyFailure +instance which tries to identify what should have been restored. + +First, some unfortunate (probably unnecessary) concessions to doctest +to keep the test run free of warnings. + +>>> del _PROXY_ALLOWED +>>> del copy +>>> del __builtins__ + +By default, save() stores every variable in the caller's namespace: + +>>> import numpy as na +>>> a = na.arange(10) +>>> save() + +Alternately, save() can be passed a comma seperated string of variables: + +>>> save("a,na") + +Alternately, save() can be passed a dictionary, typically one you already +have lying around somewhere rather than created inline as shown here: + +>>> save(dictionary={"a":a,"na":na}) + +If both variables and a dictionary are specified, the variables to be +saved are taken from the dictionary. + +>>> save(variables="a,na",dictionary={"a":a,"na":na}) + +Remove names from the session namespace + +>>> del a, na + +By default, load() restores every variable/object in the session file +to the caller's namespace. + +>>> load() + +load() can be passed a comma seperated string of variables to be +restored from the session file to the caller's namespace: + +>>> load("a,na") + +load() can also be passed a dictionary to *restore to*: + +>>> d = {} +>>> load(dictionary=d) + +load can be passed both a list variables of variables to restore and a +dictionary to restore to: + +>>> load(variables="a,na", dictionary=d) + +>>> na.all(a == na.arange(10)) +1 +>>> na.__name__ +'numpy' + +NOTE: session saving is faked for modules using module proxy objects. +Saved modules are re-imported at load time but any "state" in the module +which is not restored by a simple import is lost. + +""" + +__all__ = ['load', 'save'] + +import copy +import sys +import pickle + +SAVEFILE="session.dat" +VERBOSE = False # global import-time override + +def _foo(): pass + +_PROXY_ALLOWED = (type(sys), # module + type(_foo), # function + type(None)) # None + +def _update_proxy_types(): + """Suppress warnings for known un-picklables with working proxies.""" + pass + +def _unknown(_type): + """returns True iff _type isn't known as OK to proxy""" + return (_type is not None) and (_type not in _PROXY_ALLOWED) + +# caller() from the following article with one extra f_back added. +# from http://www.python.org/search/hypermail/python-1994q1/0506.html +# SUBJECT: import ( how to put a symbol into caller's namespace ) +# SENDER: Steven D. Majewski (sdm7g@elvis.med.virginia.edu) +# DATE: Thu, 24 Mar 1994 15:38:53 -0500 + +def _caller(): + """caller() returns the frame object of the function's caller.""" + try: + 1 + '' # make an error happen + except: # and return the caller's caller's frame + return sys.exc_traceback.tb_frame.f_back.f_back.f_back + +def _callers_globals(): + """callers_globals() returns the global dictionary of the caller.""" + frame = _caller() + return frame.f_globals + +def _callers_modules(): + """returns a list containing the names of all the modules in the caller's + global namespace.""" + g = _callers_globals() + mods = [] + for k,v in g.items(): + if type(v) == type(sys): + mods.append(getattr(v,"__name__")) + return mods + +def _errout(*args): + for a in args: + print >>sys.stderr, a, + print >>sys.stderr + +def _verbose(*args): + if VERBOSE: + _errout(*args) + +class _ProxyingFailure: + """Object which is bound to a variable for a proxy pickle which failed to reload""" + def __init__(self, module, name, type=None): + self.module = module + self.name = name + self.type = type + def __repr__(self): + return "ProxyingFailure('%s','%s','%s')" % (self.module, self.name, self.type) + +class _ModuleProxy(object): + """Proxy object which fakes pickling a module""" + def __new__(_type, name, save=False): + if save: + _verbose("proxying module", name) + self = object.__new__(_type) + self.name = name + else: + _verbose("loading module proxy", name) + try: + self = _loadmodule(name) + except ImportError: + _errout("warning: module", name,"import failed.") + return self + + def __getnewargs__(self): + return (self.name,) + + def __getstate__(self): + return False + +def _loadmodule(module): + if not sys.modules.has_key(module): + modules = module.split(".") + s = "" + for i in range(len(modules)): + s = ".".join(modules[:i+1]) + exec "import " + s + return sys.modules[module] + +class _ObjectProxy(object): + """Proxy object which fakes pickling an arbitrary object. Only global + constants can really be proxied.""" + def __new__(_type, module, name, _type2, save=False): + if save: + if _unknown(_type2): + _errout("warning: proxying object", module + "." + name, + "of type", _type2, "because it wouldn't pickle...", + "it may not reload later.") + else: + _verbose("proxying object", module, name) + self = object.__new__(_type) + self.module, self.name, self.type = module, name, str(_type2) + else: + _verbose("loading object proxy", module, name) + try: + m = _loadmodule(module) + except (ImportError, KeyError): + _errout("warning: loading object proxy", module + "." + name, + "module import failed.") + return _ProxyingFailure(module,name,_type2) + try: + self = getattr(m, name) + except AttributeError: + _errout("warning: object proxy", module + "." + name, + "wouldn't reload from", m) + return _ProxyingFailure(module,name,_type2) + return self + + def __getnewargs__(self): + return (self.module, self.name, self.type) + + def __getstate__(self): + return False + + +class _SaveSession(object): + """Tag object which marks the end of a save session and holds the + saved session variable names as a list of strings in the same + order as the session pickles.""" + def __new__(_type, keys, save=False): + if save: + _verbose("saving session", keys) + else: + _verbose("loading session", keys) + self = object.__new__(_type) + self.keys = keys + return self + + def __getnewargs__(self): + return (self.keys,) + + def __getstate__(self): + return False + +class ObjectNotFound(RuntimeError): + pass + +def _locate(modules, object): + for mname in modules: + m = sys.modules[mname] + if m: + for k,v in m.__dict__.items(): + if v is object: + return m.__name__, k + else: + raise ObjectNotFound(k) + +def save(variables=None, file=SAVEFILE, dictionary=None, verbose=False): + + """saves variables from a numpy session to a file. Variables + which won't pickle are "proxied" if possible. + + 'variables' a string of comma seperated variables: e.g. "a,b,c" + Defaults to dictionary.keys(). + + 'file' a filename or file object for the session file. + + 'dictionary' the dictionary in which to look up the variables. + Defaults to the caller's globals() + + 'verbose' print additional debug output when True. + """ + + global VERBOSE + VERBOSE = verbose + + _update_proxy_types() + + if isinstance(file, str): + file = open(file, "wb") + + if dictionary is None: + dictionary = _callers_globals() + + if variables is None: + keys = dictionary.keys() + else: + keys = variables.split(",") + + source_modules = _callers_modules() + sys.modules.keys() + + p = pickle.Pickler(file, protocol=2) + + _verbose("variables:",keys) + for k in keys: + v = dictionary[k] + _verbose("saving", k, type(v)) + try: # Try to write an ordinary pickle + p.dump(v) + _verbose("pickled", k) + except (pickle.PicklingError, TypeError, SystemError): + # Use proxies for stuff that won't pickle + if isinstance(v, type(sys)): # module + proxy = _ModuleProxy(v.__name__, save=True) + else: + try: + module, name = _locate(source_modules, v) + except ObjectNotFound: + _errout("warning: couldn't find object",k, + "in any module... skipping.") + continue + else: + proxy = _ObjectProxy(module, name, type(v), save=True) + p.dump(proxy) + o = _SaveSession(keys, save=True) + p.dump(o) + file.close() + +def load(variables=None, file=SAVEFILE, dictionary=None, verbose=False): + + """load a numpy session from a file and store the specified + 'variables' into 'dictionary'. + + 'variables' a string of comma seperated variables: e.g. "a,b,c" + Defaults to dictionary.keys(). + + 'file' a filename or file object for the session file. + + 'dictionary' the dictionary in which to look up the variables. + Defaults to the caller's globals() + + 'verbose' print additional debug output when True. + """ + + global VERBOSE + VERBOSE = verbose + + if isinstance(file, str): + file = open(file, "rb") + if dictionary is None: + dictionary = _callers_globals() + values = [] + p = pickle.Unpickler(file) + while 1: + o = p.load() + if isinstance(o, _SaveSession): + session = dict(zip(o.keys, values)) + _verbose("updating dictionary with session variables.") + if variables is None: + keys = session.keys() + else: + keys = variables.split(",") + for k in keys: + dictionary[k] = session[k] + return None + else: + _verbose("unpickled object", str(o)) + values.append(o) + +def test(): + import doctest, numpy.numarray.session + return doctest.testmod(numpy.numarray.session) diff --git a/numpy/numarray/setup.py b/numpy/numarray/setup.py new file mode 100644 index 000000000..69cd6bea1 --- /dev/null +++ b/numpy/numarray/setup.py @@ -0,0 +1,17 @@ +from os.path import join + +def configuration(parent_package='',top_path=None): + from numpy.distutils.misc_util import Configuration + config = Configuration('numarray',parent_package,top_path) + + config.add_data_files('numpy/') + + config.add_extension('_capi', + sources=['_capi.c'], + ) + + return config + +if __name__ == '__main__': + from numpy.distutils.core import setup + setup(configuration=configuration) diff --git a/numpy/numarray/ufuncs.py b/numpy/numarray/ufuncs.py new file mode 100644 index 000000000..3fb5671ce --- /dev/null +++ b/numpy/numarray/ufuncs.py @@ -0,0 +1,22 @@ + +__all__ = ['abs', 'absolute', 'add', 'arccos', 'arccosh', 'arcsin', 'arcsinh', + 'arctan', 'arctan2', 'arctanh', 'bitwise_and', 'bitwise_not', + 'bitwise_or', 'bitwise_xor', 'ceil', 'cos', 'cosh', 'divide', + 'equal', 'exp', 'fabs', 'floor', 'floor_divide', + 'fmod', 'greater', 'greater_equal', 'hypot', 'isnan', + 'less', 'less_equal', 'log', 'log10', 'logical_and', 'logical_not', + 'logical_or', 'logical_xor', 'lshift', 'maximum', 'minimum', + 'minus', 'multiply', 'negative', 'not_equal', + 'power', 'product', 'remainder', 'rshift', 'sin', 'sinh', 'sqrt', + 'subtract', 'sum', 'tan', 'tanh', 'true_divide', + 'conjugate', 'sign'] + +from numpy import absolute as abs, absolute, add, arccos, arccosh, arcsin, \ + arcsinh, arctan, arctan2, arctanh, bitwise_and, invert as bitwise_not, \ + bitwise_or, bitwise_xor, ceil, cos, cosh, divide, \ + equal, exp, fabs, floor, floor_divide, fmod, greater, greater_equal, \ + hypot, isnan, less, less_equal, log, log10, logical_and, \ + logical_not, logical_or, logical_xor, left_shift as lshift, \ + maximum, minimum, negative as minus, multiply, negative, \ + not_equal, power, product, remainder, right_shift as rshift, sin, \ + sinh, sqrt, subtract, sum, tan, tanh, true_divide, conjugate, sign diff --git a/numpy/numarray/util.py b/numpy/numarray/util.py new file mode 100644 index 000000000..2a7efb60d --- /dev/null +++ b/numpy/numarray/util.py @@ -0,0 +1,40 @@ +from numpy import geterr + +__all__ = ['MathDomainError', 'UnderflowError', 'NumOverflowError', 'handleError', + 'get_numarray_include_dirs'] + +class MathDomainError(ArithmeticError): pass +class UnderflowError(ArithmeticError): pass +class NumOverflowError(OverflowError, ArithmeticError): pass + +def handleError(errorStatus, sourcemsg): + """Take error status and use error mode to handle it.""" + modes = geterr() + if errorStatus & FPE_INVALID: + if modes['invalid'] == "warn": + print "Warning: Encountered invalid numeric result(s)", sourcemsg + if modes['invalid'] == "raise": + raise MathDomainError(sourcemsg) + if errorStatus & FPE_DIVIDEBYZERO: + if modes['dividebyzero'] == "warn": + print "Warning: Encountered divide by zero(s)", sourcemsg + if modes['dividebyzero'] == "raise": + raise ZeroDivisionError(sourcemsg) + if errorStatus & FPE_OVERFLOW: + if modes['overflow'] == "warn": + print "Warning: Encountered overflow(s)", sourcemsg + if modes['overflow'] == "raise": + raise NumOverflowError(sourcemsg) + if errorStatus & FPE_UNDERFLOW: + if modes['underflow'] == "warn": + print "Warning: Encountered underflow(s)", sourcemsg + if modes['underflow'] == "raise": + raise UnderflowError(sourcemsg) + + +import os +import numpy +def get_numarray_include_dirs(): + base = os.path.dirname(numpy.__file__) + newdirs = [os.path.join(base, 'numarray')] + return newdirs |