diff options
Diffstat (limited to 'numpy/lib/src')
-rw-r--r-- | numpy/lib/src/_compiled_base.c | 860 |
1 files changed, 860 insertions, 0 deletions
diff --git a/numpy/lib/src/_compiled_base.c b/numpy/lib/src/_compiled_base.c new file mode 100644 index 000000000..654e7d95b --- /dev/null +++ b/numpy/lib/src/_compiled_base.c @@ -0,0 +1,860 @@ +#include "Python.h" +#include "structmember.h" +#include "numpy/noprefix.h" + +static PyObject *ErrorObject; +#define Py_Try(BOOLEAN) {if (!(BOOLEAN)) goto fail;} +#define Py_Assert(BOOLEAN,MESS) {if (!(BOOLEAN)) { \ + PyErr_SetString(ErrorObject, (MESS)); \ + goto fail;} \ + } + +#define PYSETERROR(message) \ +{ PyErr_SetString(ErrorObject, message); goto fail; } + +static intp +incr_slot_ (double x, double *bins, intp lbins) +{ + intp i ; + for ( i = 0 ; i < lbins ; i ++ ) + if ( x < bins [i] ) + return i ; + return lbins ; +} + +static intp +decr_slot_ (double x, double * bins, intp lbins) +{ + intp i ; + for ( i = lbins - 1 ; i >= 0; i -- ) + if (x < bins [i]) + return i + 1 ; + return 0 ; +} + +static int +monotonic_ (double * a, int lena) +{ + int i; + if (a [0] <= a [1]) /* possibly monotonic increasing */ + { + for (i = 1 ; i < lena - 1; i ++) + if (a [i] > a [i + 1]) return 0 ; + return 1 ; + } + else /* possibly monotonic decreasing */ + { + for (i = 1 ; i < lena - 1; i ++) + if (a [i] < a [i + 1]) return 0 ; + return -1 ; + } +} + + + +static intp +mxx (intp *i , intp len) +{ + /* find the index of the maximum element of an integer array */ + intp mx = 0, max = i[0] ; + intp j ; + for ( j = 1 ; j < len; j ++ ) + if ( i [j] > max ) + {max = i [j] ; + mx = j ;} + return mx; +} + +static intp +mnx (intp *i , intp len) +{ + /* find the index of the minimum element of an integer array */ + intp mn = 0, min = i [0] ; + intp j ; + for ( j = 1 ; j < len; j ++ ) + if ( i [j] < min ) + {min = i [j] ; + mn = j ;} + return mn; +} + + +static PyObject * +arr_bincount(PyObject *self, PyObject *args, PyObject *kwds) +{ + /* histogram accepts one or two arguments. The first is an array + * of non-negative integers and the second, if present, is an + * array of weights, which must be promotable to double. + * Call these arguments list and weight. Both must be one- + * dimensional. len (weight) == len(list) + * If weight is not present: + * histogram (list) [i] is the number of occurrences of i in list. + * If weight is present: + * histogram (list, weight) [i] is the sum of all weight [j] + * where list [j] == i. */ + /* self is not used */ + PyArray_Descr *type; + PyObject *list = NULL, *weight=Py_None ; + PyObject *lst=NULL, *ans=NULL, *wts=NULL; + intp *numbers, *ians, len , mxi, mni, ans_size; + int i; + double *weights , *dans; + static char *kwlist[] = {"list", "weights", NULL}; + + + Py_Try(PyArg_ParseTupleAndKeywords(args, kwds, "O|O", kwlist, + &list, &weight)); + Py_Try(lst = PyArray_ContiguousFromAny(list, PyArray_INTP, 1, 1)); + len = PyArray_SIZE(lst); + numbers = (intp *) PyArray_DATA(lst); + mxi = mxx (numbers, len) ; + mni = mnx (numbers, len) ; + Py_Assert(numbers[mni] >= 0, + "irst argument of bincount must be non-negative"); + ans_size = numbers [mxi] + 1 ; + type = PyArray_DescrFromType(PyArray_INTP); + if (weight == Py_None) { + Py_Try(ans = PyArray_Zeros(1, &ans_size, type, 0)); + ians = (intp *)(PyArray_DATA(ans)); + for (i = 0 ; i < len ; i++) + ians [numbers [i]] += 1 ; + Py_DECREF(lst); + } + else { + Py_Try(wts = PyArray_ContiguousFromAny(weight, + PyArray_DOUBLE, 1, 1)); + weights = (double *)PyArray_DATA (wts); + Py_Assert(PyArray_SIZE(wts) == len, "bincount: length of weights " \ + "does not match that of list"); + type = PyArray_DescrFromType(PyArray_DOUBLE); + Py_Try(ans = PyArray_Zeros(1, &ans_size, type, 0)); + dans = (double *)PyArray_DATA (ans); + for (i = 0 ; i < len ; i++) { + dans[numbers[i]] += weights[i]; + } + Py_DECREF(lst); + Py_DECREF(wts); + } + return ans; + + fail: + Py_XDECREF(lst); + Py_XDECREF(wts); + Py_XDECREF(ans); + return NULL; +} + + +static PyObject * +arr_digitize(PyObject *self, PyObject *args, PyObject *kwds) +{ + /* digitize (x, bins) returns an array of python integers the same + length of x. The values i returned are such that + bins [i - 1] <= x < bins [i] if bins is monotonically increasing, + or bins [i - 1] > x >= bins [i] if bins is monotonically decreasing. + Beyond the bounds of bins, returns either i = 0 or i = len (bins) + as appropriate. */ + /* self is not used */ + PyObject *ox, *obins ; + PyObject *ax=NULL, *abins=NULL, *aret=NULL; + double *dx, *dbins ; + intp lbins, lx ; /* lengths */ + intp *iret; + int m, i ; + static char *kwlist[] = {"x", "bins", NULL}; + PyArray_Descr *type; + + Py_Try(PyArg_ParseTupleAndKeywords(args, kwds, "OO", kwlist, + &ox, &obins)); + + type = PyArray_DescrFromType(PyArray_DOUBLE); + Py_Try(ax=PyArray_FromAny(ox, type, 1, 1, CARRAY, NULL)); + Py_INCREF(type); + Py_Try(abins = PyArray_FromAny(obins, type, 1, 1, CARRAY, NULL)); + + lx = PyArray_SIZE(ax); + dx = (double *)PyArray_DATA(ax); + lbins = PyArray_SIZE(abins); + dbins = (double *)PyArray_DATA(abins); + Py_Try(aret = PyArray_SimpleNew(1, &lx, PyArray_INTP)); + iret = (intp *)PyArray_DATA(aret); + + Py_Assert(lx > 0 && lbins > 0, + "x and bins both must have non-zero length"); + + if (lbins == 1) { + for (i=0 ; i<lx ; i++) + if (dx [i] >= dbins[0]) + iret[i] = 1; + else + iret[i] = 0; + } + else { + m = monotonic_ (dbins, lbins) ; + if ( m == -1 ) { + for ( i = 0 ; i < lx ; i ++ ) + iret [i] = decr_slot_ ((double)dx [i], dbins, lbins) ; + } + else if ( m == 1 ) { + for ( i = 0 ; i < lx ; i ++ ) + iret [i] = incr_slot_ ((double)dx [i], dbins, lbins) ; + } + else Py_Assert(0, "bins must be montonically increasing or decreasing"); + } + + Py_DECREF(ax); + Py_DECREF(abins); + return aret; + + fail: + Py_XDECREF(ax); + Py_XDECREF(abins); + Py_XDECREF(aret); + return NULL; +} + + + +static char arr_insert__doc__[] = "Insert vals sequentially into equivalent 1-d positions indicated by mask."; + +static PyObject * +arr_insert(PyObject *self, PyObject *args, PyObject *kwdict) +{ + /* Returns input array with values inserted sequentially into places + indicated by the mask + */ + PyObject *mask=NULL, *vals=NULL; + PyArrayObject *ainput=NULL, *amask=NULL, *avals=NULL, + *tmp=NULL; + int numvals, totmask, sameshape; + char *input_data, *mptr, *vptr, *zero=NULL; + int melsize, delsize, copied, nd; + intp *instrides, *inshape; + int mindx, rem_indx, indx, i, k, objarray; + + static char *kwlist[] = {"input","mask","vals",NULL}; + + if (!PyArg_ParseTupleAndKeywords(args, kwdict, "O&OO", kwlist, + PyArray_Converter, &ainput, + &mask, &vals)) + goto fail; + + amask = (PyArrayObject *) PyArray_FROM_OF(mask, CARRAY); + if (amask == NULL) goto fail; + /* Cast an object array */ + if (amask->descr->type_num == PyArray_OBJECT) { + tmp = (PyArrayObject *)PyArray_Cast(amask, PyArray_INTP); + if (tmp == NULL) goto fail; + Py_DECREF(amask); + amask = tmp; + } + + sameshape = 1; + if (amask->nd == ainput->nd) { + for (k=0; k < amask->nd; k++) + if (amask->dimensions[k] != ainput->dimensions[k]) + sameshape = 0; + } + else { /* Test to see if amask is 1d */ + if (amask->nd != 1) sameshape = 0; + else if ((PyArray_SIZE(ainput)) != PyArray_SIZE(amask)) sameshape = 0; + } + if (!sameshape) { + PyErr_SetString(PyExc_TypeError, + "mask array must be 1-d or same shape as input array"); + goto fail; + } + + avals = (PyArrayObject *)PyArray_FromObject(vals, ainput->descr->type_num, 0, 1); + if (avals == NULL) goto fail; + + numvals = PyArray_SIZE(avals); + nd = ainput->nd; + input_data = ainput->data; + mptr = amask->data; + melsize = amask->descr->elsize; + vptr = avals->data; + delsize = avals->descr->elsize; + zero = PyArray_Zero(amask); + if (zero == NULL) + goto fail; + objarray = (ainput->descr->type_num == PyArray_OBJECT); + + /* Handle zero-dimensional case separately */ + if (nd == 0) { + if (memcmp(mptr,zero,melsize) != 0) { + /* Copy value element over to input array */ + memcpy(input_data,vptr,delsize); + if (objarray) Py_INCREF(*((PyObject **)vptr)); + } + Py_DECREF(amask); + Py_DECREF(avals); + PyDataMem_FREE(zero); + Py_DECREF(ainput); + Py_INCREF(Py_None); + return Py_None; + } + + /* Walk through mask array, when non-zero is encountered + copy next value in the vals array to the input array. + If we get through the value array, repeat it as necessary. + */ + totmask = (int) PyArray_SIZE(amask); + copied = 0; + instrides = ainput->strides; + inshape = ainput->dimensions; + for (mindx = 0; mindx < totmask; mindx++) { + if (memcmp(mptr,zero,melsize) != 0) { + /* compute indx into input array + */ + rem_indx = mindx; + indx = 0; + for(i=nd-1; i > 0; --i) { + indx += (rem_indx % inshape[i]) * instrides[i]; + rem_indx /= inshape[i]; + } + indx += rem_indx * instrides[0]; + /* fprintf(stderr, "mindx = %d, indx=%d\n", mindx, indx); */ + /* Copy value element over to input array */ + memcpy(input_data+indx,vptr,delsize); + if (objarray) Py_INCREF(*((PyObject **)vptr)); + vptr += delsize; + copied += 1; + /* If we move past value data. Reset */ + if (copied >= numvals) vptr = avals->data; + } + mptr += melsize; + } + + Py_DECREF(amask); + Py_DECREF(avals); + PyDataMem_FREE(zero); + Py_DECREF(ainput); + Py_INCREF(Py_None); + return Py_None; + + fail: + PyDataMem_FREE(zero); + Py_XDECREF(ainput); + Py_XDECREF(amask); + Py_XDECREF(avals); + return NULL; +} + +static npy_intp +binary_search(double dval, double dlist [], npy_intp len) +{ + /* binary_search accepts three arguments: a numeric value and + * a numeric array and its length. It assumes that the array is sorted in + * increasing order. It returns the index of the array's + * largest element which is <= the value. It will return -1 if + * the value is less than the least element of the array. */ + /* self is not used */ + npy_intp bottom , top , middle, result; + + if (dval < dlist [0]) + result = -1 ; + else { + bottom = 0; + top = len - 1; + while (bottom < top) { + middle = (top + bottom) / 2 ; + if (dlist [middle] < dval) + bottom = middle + 1 ; + else if (dlist [middle] > dval) + top = middle - 1 ; + else + return middle ; + } + if (dlist [bottom] > dval) + result = bottom - 1 ; + else + result = bottom ; + } + + return result ; +} + +static PyObject * +arr_interp(PyObject *self, PyObject *args, PyObject *kwdict) +{ + + PyObject *fp, *xp, *x; + PyObject *left=NULL, *right=NULL; + PyArrayObject *afp=NULL, *axp=NULL, *ax=NULL, *af=NULL; + npy_intp i, lenx, lenxp, indx; + double lval, rval; + double *dy, *dx, *dz, *dres, *slopes; + + static char *kwlist[] = {"x", "xp", "fp", "left", "right", NULL}; + + if (!PyArg_ParseTupleAndKeywords(args, kwdict, "OOO|OO", kwlist, + &x, &xp, &fp, &left, &right)) + return NULL; + + + afp = (NPY_AO*)PyArray_ContiguousFromAny(fp, NPY_DOUBLE, 1, 1); + if (afp == NULL) return NULL; + axp = (NPY_AO*)PyArray_ContiguousFromAny(xp, NPY_DOUBLE, 1, 1); + if (axp == NULL) goto fail; + ax = (NPY_AO*)PyArray_ContiguousFromAny(x, NPY_DOUBLE, 1, 0); + if (ax == NULL) goto fail; + + lenxp = axp->dimensions[0]; + if (afp->dimensions[0] != lenxp) { + PyErr_SetString(PyExc_ValueError, "interp: fp and xp are not the same length."); + goto fail; + } + + af = (NPY_AO*)PyArray_SimpleNew(ax->nd, ax->dimensions, NPY_DOUBLE); + if (af == NULL) goto fail; + + lenx = PyArray_SIZE(ax); + + dy = (double *)PyArray_DATA(afp); + dx = (double *)PyArray_DATA(axp); + dz = (double *)PyArray_DATA(ax); + dres = (double *)PyArray_DATA(af); + + /* Get left and right fill values. */ + if ((left == NULL) || (left == Py_None)) { + lval = dy[0]; + } + else { + lval = PyFloat_AsDouble(left); + if ((lval==-1) && PyErr_Occurred()) + goto fail; + } + if ((right == NULL) || (right == Py_None)) { + rval = dy[lenxp-1]; + } + else { + rval = PyFloat_AsDouble(right); + if ((rval==-1) && PyErr_Occurred()) + goto fail; + } + + slopes = (double *) PyDataMem_NEW((lenxp-1)*sizeof(double)); + for (i=0; i < lenxp-1; i++) { + slopes[i] = (dy[i+1] - dy[i])/(dx[i+1]-dx[i]); + } + for (i=0; i<lenx; i++) { + indx = binary_search(dz[i], dx, lenxp); + if (indx < 0) + dres[i] = lval; + else if (indx >= lenxp - 1) + dres[i] = rval; + else + dres[i] = slopes[indx]*(dz[i]-dx[indx]) + dy[indx]; + } + + PyDataMem_FREE(slopes); + Py_DECREF(afp); + Py_DECREF(axp); + Py_DECREF(ax); + return (PyObject *)af; + + fail: + Py_XDECREF(afp); + Py_XDECREF(axp); + Py_XDECREF(ax); + Py_XDECREF(af); + return NULL; +} + + + +static PyTypeObject *PyMemberDescr_TypePtr=NULL; +static PyTypeObject *PyGetSetDescr_TypePtr=NULL; +static PyTypeObject *PyMethodDescr_TypePtr=NULL; + +/* Can only be called if doc is currently NULL + */ +static PyObject * +arr_add_docstring(PyObject *dummy, PyObject *args) +{ + PyObject *obj; + PyObject *str; + char *docstr; + static char *msg = "already has a docstring"; + + /* Don't add docstrings */ + if (Py_OptimizeFlag > 1) { + Py_INCREF(Py_None); + return Py_None; + } + + if (!PyArg_ParseTuple(args, "OO!", &obj, &PyString_Type, &str)) + return NULL; + + docstr = PyString_AS_STRING(str); + +#define _TESTDOC1(typebase) (obj->ob_type == &Py##typebase##_Type) +#define _TESTDOC2(typebase) (obj->ob_type == Py##typebase##_TypePtr) +#define _ADDDOC(typebase, doc, name) { \ + Py##typebase##Object *new = (Py##typebase##Object *)obj; \ + if (!(doc)) { \ + doc = docstr; \ + } \ + else { \ + PyErr_Format(PyExc_RuntimeError, \ + "%s method %s",name, msg); \ + return NULL; \ + } \ + } + + if _TESTDOC1(CFunction) + _ADDDOC(CFunction, new->m_ml->ml_doc, new->m_ml->ml_name) + else if _TESTDOC1(Type) + _ADDDOC(Type, new->tp_doc, new->tp_name) + else if _TESTDOC2(MemberDescr) + _ADDDOC(MemberDescr, new->d_member->doc, new->d_member->name) + else if _TESTDOC2(GetSetDescr) + _ADDDOC(GetSetDescr, new->d_getset->doc, new->d_getset->name) + else if _TESTDOC2(MethodDescr) + _ADDDOC(MethodDescr, new->d_method->ml_doc, + new->d_method->ml_name) + else { + PyErr_SetString(PyExc_TypeError, + "Cannot set a docstring for that object"); + return NULL; + } + +#undef _TESTDOC1 +#undef _TESTDOC2 +#undef _ADDDOC + + Py_INCREF(str); + Py_INCREF(Py_None); + return Py_None; +} + + +static char packbits_doc[] = + "out = numpy.packbits(myarray, axis=None)\n\n" + " myarray : an integer type array whose elements should be packed to bits\n\n" + " This routine packs the elements of a binary-valued dataset into a\n" + " NumPy array of type uint8 ('B') whose bits correspond to\n" + " the logical (0 or nonzero) value of the input elements.\n" + " The dimension over-which bit-packing is done is given by axis.\n" + " The shape of the output has the same number of dimensions as the input\n" + " (unless axis is None, in which case the output is 1-d).\n" + "\n" + " Example:\n" + " >>> a = array([[[1,0,1],\n" + " ... [0,1,0]],\n" + " ... [[1,1,0],\n" + " ... [0,0,1]]])\n" + " >>> b = numpy.packbits(a,axis=-1)\n" + " >>> b\n" + " array([[[160],[64]],[[192],[32]]], dtype=uint8)\n\n" + " Note that 160 = 128 + 32\n" + " 192 = 128 + 64\n"; + +static char unpackbits_doc[] = + "out = numpy.unpackbits(myarray, axis=None)\n\n" + " myarray - array of uint8 type where each element represents a bit-field\n" + " that should be unpacked into a boolean output array\n\n" + " The shape of the output array is either 1-d (if axis is None) or\n" + " the same shape as the input array with unpacking done along the\n" + " axis specified."; + +/* PACKBITS + + This function packs binary (0 or 1) 1-bit per pixel arrays + into contiguous bytes. + +*/ + +static void +_packbits( + void *In, + int element_size, /* in bytes */ + npy_intp in_N, + npy_intp in_stride, + void *Out, + npy_intp out_N, + npy_intp out_stride + ) +{ + char build; + int i, index; + npy_intp out_Nm1; + int maxi, remain, nonzero, j; + char *outptr,*inptr; + + outptr = Out; /* pointer to output buffer */ + inptr = In; /* pointer to input buffer */ + + /* Loop through the elements of In */ + /* Determine whether or not it is nonzero. + Yes: set correspdoning bit (and adjust build value) + No: move on + /* Every 8th value, set the value of build and increment the outptr */ + + remain = in_N % 8; /* uneven bits */ + if (remain == 0) remain = 8; + out_Nm1 = out_N - 1; + for (index = 0; index < out_N; index++) { + build = 0; + maxi = (index != out_Nm1 ? 8 : remain); + for (i = 0; i < maxi ; i++) { + build <<= 1; /* shift bits left one bit */ + nonzero = 0; + for (j = 0; j < element_size; j++) /* determine if this number is non-zero */ + nonzero += (*(inptr++) != 0); + inptr += (in_stride - element_size); /* advance to next input */ + build += (nonzero != 0); /* add to this bit if the input value is non-zero */ + } + if (index == out_Nm1) build <<= (8-remain); + /* printf("Here: %d %d %d %d\n",build,slice,index,maxi); + */ + *outptr = build; + outptr += out_stride; + } + return; +} + + +static void +_unpackbits( + void *In, + int el_size, /* unused */ + npy_intp in_N, + npy_intp in_stride, + void *Out, + npy_intp out_N, + npy_intp out_stride + ) +{ + unsigned char mask; + int i,index; + char *inptr, *outptr; + + /* Loop through the elements of out + */ + outptr = Out; + inptr = In; + for (index = 0; index < in_N; index++) { + mask = 128; + for (i = 0; i < 8 ; i++) { + *outptr = ((mask & (unsigned char)(*inptr)) != 0); + outptr += out_stride; + mask >>= 1; + } + inptr += in_stride; + } + return; +} + +static PyObject * +pack_or_unpack_bits(PyObject *input, int axis, int unpack) +{ + PyArrayObject *inp; + PyObject *new=NULL; + PyObject *out=NULL; + npy_intp outdims[MAX_DIMS]; + int i; + void (*thefunc)(void *, int, npy_intp, npy_intp, void *, npy_intp, npy_intp); + PyArrayIterObject *it, *ot; + + inp = (PyArrayObject *)PyArray_FROM_O(input); + + if (inp == NULL) return NULL; + + if (unpack) { + if (PyArray_TYPE(inp) != NPY_UBYTE) + PYSETERROR("Expecting an input array of unsigned byte data type"); + } + else { + if (!PyArray_ISINTEGER(inp)) + PYSETERROR("Expecting an input array of integer data type"); + } + + new = PyArray_CheckAxis(inp, &axis, 0); + Py_DECREF(inp); + if (new == NULL) return NULL; + + /* Handle zero-dim array separately */ + if (PyArray_SIZE(new) == 0) { + return PyArray_Copy((PyArrayObject *)new); + } + + if (PyArray_NDIM(new) == 0) { + if (unpack) { + /* Handle 0-d array by converting it to a 1-d array */ + PyObject *temp; + PyArray_Dims newdim = {NULL, 1}; + npy_intp shape=1; + newdim.ptr = &shape; + temp = PyArray_Newshape((PyArrayObject *)new, &newdim, NPY_CORDER); + if (temp == NULL) goto fail; + Py_DECREF(new); + new = temp; + } + else { + ubyte *optr, *iptr; + out = PyArray_New(new->ob_type, 0, NULL, NPY_UBYTE, + NULL, NULL, 0, 0, NULL); + if (out == NULL) goto fail; + optr = PyArray_DATA(out); + iptr = PyArray_DATA(new); + *optr = 0; + for (i=0; i<PyArray_ITEMSIZE(new); i++) { + if (*iptr != 0) { + *optr = 1; + break; + } + iptr++; + } + goto finish; + } + } + + + /* Setup output shape */ + for (i=0; i<PyArray_NDIM(new); i++) { + outdims[i] = PyArray_DIM(new, i); + } + + if (unpack) { + /* Multiply axis dimension by 8 */ + outdims[axis] <<= 3; + thefunc = _unpackbits; + } + else { + /* Divide axis dimension by 8 */ + /* 8 -> 1, 9 -> 2, 16 -> 2, 17 -> 3 etc.. */ + outdims[axis] = ((outdims[axis] - 1) >> 3) + 1; + thefunc = _packbits; + } + + /* Create output array */ + out = PyArray_New(new->ob_type, PyArray_NDIM(new), outdims, PyArray_UBYTE, + NULL, NULL, 0, PyArray_ISFORTRAN(new), NULL); + if (out == NULL) goto fail; + + /* Setup iterators to iterate over all but given axis */ + it = (PyArrayIterObject *)PyArray_IterAllButAxis((PyObject *)new, &axis); + ot = (PyArrayIterObject *)PyArray_IterAllButAxis((PyObject *)out, &axis); + if (it == NULL || ot == NULL) { + Py_XDECREF(it); + Py_XDECREF(ot); + goto fail; + } + + while(PyArray_ITER_NOTDONE(it)) { + thefunc(PyArray_ITER_DATA(it), PyArray_ITEMSIZE(new), + PyArray_DIM(new, axis), PyArray_STRIDE(new, axis), + PyArray_ITER_DATA(ot), PyArray_DIM(out, axis), + PyArray_STRIDE(out, axis)); + PyArray_ITER_NEXT(it); + PyArray_ITER_NEXT(ot); + } + Py_DECREF(it); + Py_DECREF(ot); + + finish: + Py_DECREF(new); + return out; + + fail: + Py_XDECREF(new); + Py_XDECREF(out); + return NULL; +} + + + +static PyObject * +io_pack(PyObject *self, PyObject *args, PyObject *kwds) +{ + PyObject *obj; + int axis=NPY_MAXDIMS; + static char *kwlist[] = {"in", "axis", NULL}; + + if (!PyArg_ParseTupleAndKeywords( args, kwds, "O|O&" , kwlist, + &obj, PyArray_AxisConverter, &axis)) + return NULL; + return pack_or_unpack_bits(obj, axis, 0); +} + +static PyObject * +io_unpack(PyObject *self, PyObject *args, PyObject *kwds) +{ + PyObject *obj; + int axis=NPY_MAXDIMS; + static char *kwlist[] = {"in", "axis", NULL}; + + if (!PyArg_ParseTupleAndKeywords( args, kwds, "O|O&" , kwlist, + &obj, PyArray_AxisConverter, &axis)) + return NULL; + return pack_or_unpack_bits(obj, axis, 1); +} + +static struct PyMethodDef methods[] = { + {"_insert", (PyCFunction)arr_insert, METH_VARARGS | METH_KEYWORDS, + arr_insert__doc__}, + {"bincount", (PyCFunction)arr_bincount, + METH_VARARGS | METH_KEYWORDS, NULL}, + {"digitize", (PyCFunction)arr_digitize, METH_VARARGS | METH_KEYWORDS, + NULL}, + {"interp", (PyCFunction)arr_interp, METH_VARARGS | METH_KEYWORDS, + NULL}, + {"add_docstring", (PyCFunction)arr_add_docstring, METH_VARARGS, + NULL}, + {"packbits", (PyCFunction)io_pack, METH_VARARGS | METH_KEYWORDS, + packbits_doc}, + {"unpackbits", (PyCFunction)io_unpack, METH_VARARGS | METH_KEYWORDS, + unpackbits_doc}, + {NULL, NULL} /* sentinel */ +}; + +static void +define_types(void) +{ + PyObject *tp_dict; + PyObject *myobj; + + tp_dict = PyArrayDescr_Type.tp_dict; + /* Get "subdescr" */ + myobj = PyDict_GetItemString(tp_dict, "fields"); + if (myobj == NULL) return; + PyGetSetDescr_TypePtr = myobj->ob_type; + myobj = PyDict_GetItemString(tp_dict, "alignment"); + if (myobj == NULL) return; + PyMemberDescr_TypePtr = myobj->ob_type; + myobj = PyDict_GetItemString(tp_dict, "newbyteorder"); + if (myobj == NULL) return; + PyMethodDescr_TypePtr = myobj->ob_type; + return; +} + +/* Initialization function for the module (*must* be called init<name>) */ + +PyMODINIT_FUNC init_compiled_base(void) { + PyObject *m, *d, *s; + + /* Create the module and add the functions */ + m = Py_InitModule("_compiled_base", methods); + + /* Import the array objects */ + import_array(); + + /* Add some symbolic constants to the module */ + d = PyModule_GetDict(m); + + s = PyString_FromString("0.5"); + PyDict_SetItemString(d, "__version__", s); + Py_DECREF(s); + + ErrorObject = PyString_FromString("numpy.lib.error"); + PyDict_SetItemString(d, "error", ErrorObject); + Py_DECREF(ErrorObject); + + + /* define PyGetSetDescr_Type and PyMemberDescr_Type */ + define_types(); + + return; +} |