static PyArrayObject *mx2numeric(const mxArray *pArray) { //current function returns PyArrayObject in c order currently mwSize nd; npy_intp pydims[NPY_MAXDIMS]; PyArrayObject *lRetval = NULL,*t=NULL; const double *lPR; const double *lPI; pyassert(PyArray_API, "Unable to perform this function without NumPy installed"); nd = mxGetNumberOfDimensions(pArray); { const mwSize *dims; dims = mxGetDimensions(pArray); for (mwSize i=0; i != nd; i++){ pydims[i] = static_cast<npy_intp>(dims[i]); } } //this function creates a fortran array t = (PyArrayObject *) PyArray_New(&PyArray_Type,static_cast<npy_intp>(nd), pydims, mxIsComplex(pArray) ? PyArray_CDOUBLE : PyArray_DOUBLE, NULL, // strides NULL, // data 0, //(ignored itemsize), NPY_F_CONTIGUOUS, NULL); // obj if (t == NULL) return NULL; lPR = mxGetPr(pArray); if (mxIsComplex(pArray)) { double *lDst = (double *)PyArray_DATA(t); // AWMS unsigned int almost certainly can overflow on some platforms! npy_intp numberOfElements = PyArray_SIZE(t); lPI = mxGetPi(pArray); for (mwIndex i = 0; i != numberOfElements; i++) { *lDst++ = *lPR++; *lDst++ = *lPI++; } } else { double *lDst = (double *)PyArray_DATA(t); npy_intp numberOfElements = PyArray_SIZE(t); for (mwIndex i = 0; i != numberOfElements; i++) { *lDst++ = *lPR++; } } lRetval = (PyArrayObject *)PyArray_FromArray(t,NULL,NPY_C_CONTIGUOUS|NPY_ALIGNED|NPY_WRITEABLE); Py_DECREF(t); return lRetval; error_return: return NULL; }
/* * Returns input array with values inserted sequentially into places * indicated by the mask */ NPY_NO_EXPORT PyObject * arr_insert(PyObject *NPY_UNUSED(self), PyObject *args, PyObject *kwdict) { char *src, *dest; npy_bool *mask_data; PyArray_Descr *dtype; PyArray_CopySwapFunc *copyswap; PyObject *array0, *mask0, *values0; PyArrayObject *array, *mask, *values; npy_intp i, j, chunk, nm, ni, nv; static char *kwlist[] = {"input", "mask", "vals", NULL}; NPY_BEGIN_THREADS_DEF; values = mask = NULL; if (!PyArg_ParseTupleAndKeywords(args, kwdict, "O!OO:place", kwlist, &PyArray_Type, &array0, &mask0, &values0)) { return NULL; } array = (PyArrayObject *)PyArray_FromArray((PyArrayObject *)array0, NULL, NPY_ARRAY_CARRAY | NPY_ARRAY_UPDATEIFCOPY); if (array == NULL) { goto fail; } ni = PyArray_SIZE(array); dest = PyArray_DATA(array); chunk = PyArray_DESCR(array)->elsize; mask = (PyArrayObject *)PyArray_FROM_OTF(mask0, NPY_BOOL, NPY_ARRAY_CARRAY | NPY_ARRAY_FORCECAST); if (mask == NULL) { goto fail; } nm = PyArray_SIZE(mask); if (nm != ni) { PyErr_SetString(PyExc_ValueError, "place: mask and data must be " "the same size"); goto fail; } mask_data = PyArray_DATA(mask); dtype = PyArray_DESCR(array); Py_INCREF(dtype); values = (PyArrayObject *)PyArray_FromAny(values0, dtype, 0, 0, NPY_ARRAY_CARRAY, NULL); if (values == NULL) { goto fail; } nv = PyArray_SIZE(values); /* zero if null array */ if (nv <= 0) { npy_bool allFalse = 1; i = 0; while (allFalse && i < ni) { if (mask_data[i]) { allFalse = 0; } else { i++; } } if (!allFalse) { PyErr_SetString(PyExc_ValueError, "Cannot insert from an empty array!"); goto fail; } else { Py_XDECREF(values); Py_XDECREF(mask); Py_RETURN_NONE; } } src = PyArray_DATA(values); j = 0; copyswap = PyArray_DESCR(array)->f->copyswap; NPY_BEGIN_THREADS_DESCR(PyArray_DESCR(array)); for (i = 0; i < ni; i++) { if (mask_data[i]) { if (j >= nv) { j = 0; } copyswap(dest + i*chunk, src + j*chunk, 0, array); j++; } } NPY_END_THREADS; Py_XDECREF(values); Py_XDECREF(mask); Py_DECREF(array); Py_RETURN_NONE; fail: Py_XDECREF(mask); Py_XDECREF(array); Py_XDECREF(values); return NULL; }
static mxArray *makeMxFromNumeric(const PyArrayObject *pSrc) { npy_intp lRows=0, lCols=0; bool lIsComplex; bool lIsNotAMatrix = false; double *lR = NULL; double *lI = NULL; mxArray *lRetval = NULL; mwSize dims[NPY_MAXDIMS]; mwSize nDims = pSrc->nd; const PyArrayObject *ap=NULL; switch (pSrc->nd) { case 0: // XXX the evil 0D lRows = 1; lCols = 1; lIsNotAMatrix = true; break; case 1: lRows = pSrc->dimensions[0]; lCols = min(1, lRows); // for array([]): to avoid zeros((0,1)) ! lIsNotAMatrix = true; break; default: for (mwSize i = 0;i != nDims; i++) { dims[i]=(mwSize)pSrc->dimensions[i]; } break; } switch (pSrc->descr->type_num) { case PyArray_OBJECT: PyErr_SetString(PyExc_TypeError, "Non-numeric array types not supported"); return NULL; case PyArray_CFLOAT: case PyArray_CDOUBLE: lIsComplex = true; break; default: lIsComplex = false; } // converts to fortran order if not already if(!PyArray_ISFORTRAN(pSrc)){ ap = (PyArrayObject * const)PyArray_FromArray((PyArrayObject*)pSrc,NULL,NPY_ALIGNED|NPY_F_CONTIGUOUS); } else{ ap = pSrc; } if(lIsNotAMatrix) lRetval = mxCreateDoubleMatrix(lRows, lCols, lIsComplex ? mxCOMPLEX : mxREAL); else lRetval = mxCreateNumericArray(nDims,dims,mxDOUBLE_CLASS,lIsComplex ? mxCOMPLEX : mxREAL); if (lRetval == NULL) return NULL; lR = mxGetPr(lRetval); lI = mxGetPi(lRetval); if (lIsNotAMatrix) { void *p = PyArray_DATA(ap); switch (ap->descr->type_num) { case PyArray_CHAR: copyNumericVector2Mx((char *)(p), lRows, lR, pSrc->strides); break; case PyArray_UBYTE: copyNumericVector2Mx((unsigned char *)(p), lRows, lR, pSrc->strides); break; case PyArray_SBYTE: copyNumericVector2Mx((signed char *)(p), lRows, lR, pSrc->strides); break; case PyArray_SHORT: copyNumericVector2Mx((short *)(p), lRows, lR, pSrc->strides); break; case PyArray_INT: copyNumericVector2Mx((int *)(p), lRows, lR, pSrc->strides); break; case PyArray_LONG: copyNumericVector2Mx((long *)(p), lRows, lR, pSrc->strides); break; case PyArray_FLOAT: copyNumericVector2Mx((float *)(p), lRows, lR, pSrc->strides); break; case PyArray_DOUBLE: copyNumericVector2Mx((double *)(p), lRows, lR, pSrc->strides); break; case PyArray_CFLOAT: copyCplxNumericVector2Mx((float *)(p), lRows, lR, lI, pSrc->strides); break; case PyArray_CDOUBLE: copyCplxNumericVector2Mx((double *)(p), lRows, lR, lI, pSrc->strides); break; } } else { void *p = PyArray_DATA(ap); npy_intp size = PyArray_SIZE(pSrc); switch (pSrc->descr->type_num) { case PyArray_CHAR: copyNumeric2Mx((char *)p,size,lR); break; case PyArray_UBYTE: copyNumeric2Mx((unsigned char *)p,size,lR); break; case PyArray_SBYTE: copyNumeric2Mx((signed char *)p,size,lR); break; case PyArray_SHORT: copyNumeric2Mx((short *)p,size,lR); break; case PyArray_INT: copyNumeric2Mx((int *)p,size,lR); break; case PyArray_LONG: copyNumeric2Mx((long *)p,size,lR); break; case PyArray_FLOAT: copyNumeric2Mx((float *)p,size,lR); break; case PyArray_DOUBLE: copyNumeric2Mx((double *)p,size,lR); break; case PyArray_CFLOAT: copyCplxNumeric2Mx((float *)p,size,lR,lI); break; case PyArray_CDOUBLE: copyCplxNumeric2Mx((double *)p,size,lR,lI); break; } } if(ap != pSrc){ Py_DECREF(const_cast<PyArrayObject *>(ap)); } return lRetval; }
/*NUMPY_API * ArgMax */ NPY_NO_EXPORT PyObject * PyArray_ArgMax(PyArrayObject *op, int axis, PyArrayObject *out) { PyArrayObject *ap = NULL, *rp = NULL; PyArray_ArgFunc* arg_func; char *ip; intp *rptr; intp i, n, m; int elsize; int copyret = 0; NPY_BEGIN_THREADS_DEF; if ((ap=(PyAO *)_check_axis(op, &axis, 0)) == NULL) { return NULL; } /* * We need to permute the array so that axis is placed at the end. * And all other dimensions are shifted left. */ if (axis != ap->nd-1) { PyArray_Dims newaxes; intp dims[MAX_DIMS]; int i; newaxes.ptr = dims; newaxes.len = ap->nd; for (i = 0; i < axis; i++) dims[i] = i; for (i = axis; i < ap->nd - 1; i++) dims[i] = i + 1; dims[ap->nd - 1] = axis; op = (PyAO *)PyArray_Transpose(ap, &newaxes); Py_DECREF(ap); if (op == NULL) { return NULL; } } else { op = ap; } /* Will get native-byte order contiguous copy. */ ap = (PyArrayObject *) PyArray_ContiguousFromAny((PyObject *)op, op->descr->type_num, 1, 0); Py_DECREF(op); if (ap == NULL) { return NULL; } arg_func = ap->descr->f->argmax; if (arg_func == NULL) { PyErr_SetString(PyExc_TypeError, "data type not ordered"); goto fail; } elsize = ap->descr->elsize; m = ap->dimensions[ap->nd-1]; if (m == 0) { PyErr_SetString(PyExc_ValueError, "attempt to get argmax/argmin "\ "of an empty sequence"); goto fail; } if (!out) { rp = (PyArrayObject *)PyArray_New(ap->ob_type, ap->nd-1, ap->dimensions, PyArray_INTP, NULL, NULL, 0, 0, (PyObject *)ap); if (rp == NULL) { goto fail; } } else { if (PyArray_SIZE(out) != PyArray_MultiplyList(ap->dimensions, ap->nd - 1)) { PyErr_SetString(PyExc_TypeError, "invalid shape for output array."); } rp = (PyArrayObject *)\ PyArray_FromArray(out, PyArray_DescrFromType(PyArray_INTP), NPY_CARRAY | NPY_UPDATEIFCOPY); if (rp == NULL) { goto fail; } if (rp != out) { copyret = 1; } } NPY_BEGIN_THREADS_DESCR(ap->descr); n = PyArray_SIZE(ap)/m; rptr = (intp *)rp->data; for (ip = ap->data, i = 0; i < n; i++, ip += elsize*m) { arg_func(ip, m, rptr, ap); rptr += 1; } NPY_END_THREADS_DESCR(ap->descr); Py_DECREF(ap); if (copyret) { PyArrayObject *obj; obj = (PyArrayObject *)rp->base; Py_INCREF(obj); Py_DECREF(rp); rp = obj; } return (PyObject *)rp; fail: Py_DECREF(ap); Py_XDECREF(rp); return NULL; }
static mxArray *makeMxFromNumeric(const PyArrayObject *pSrc, bool &is_reference) { npy_intp lRows=0, lCols=0; bool lIsComplex; bool lIsNotAMatrix = false; double *lR = NULL; double *lI = NULL; mxArray *lRetval = NULL; mwSize dims[NPY_MAXDIMS]; mwSize dimsEmpty [2]; memset(&dimsEmpty, 0, 2 * sizeof(mwSize)); mwSize nDims = pSrc->nd; const PyArrayObject *ap=NULL; mxClassID classID = mxUNKNOWN_CLASS; switch (pSrc->nd) { case 0: // XXX the evil 0D lRows = 1; lCols = 1; lIsNotAMatrix = true; break; case 1: lRows = pSrc->dimensions[0]; lCols = min(1, lRows); // for array([]): to avoid zeros((0,1)) ! lIsNotAMatrix = true; break; default: for (mwSize i = 0;i != nDims; i++) { dims[i]=(mwSize)pSrc->dimensions[i]; } break; } switch (pSrc->descr->type_num) { case PyArray_OBJECT: PyErr_SetString(PyExc_TypeError, "Non-numeric array types not supported"); return NULL; case PyArray_CFLOAT: case PyArray_CDOUBLE: lIsComplex = true; break; default: lIsComplex = false; } // converts to fortran order if not already if(!PyArray_ISFORTRAN(pSrc)){ ap = (PyArrayObject * const)PyArray_FromArray((PyArrayObject*)pSrc,NULL,NPY_ALIGNED|NPY_F_CONTIGUOUS); } else{ ap = pSrc; } if(lIsNotAMatrix) lRetval = mxCreateDoubleMatrix(lRows, lCols, lIsComplex ? mxCOMPLEX : mxREAL); else { switch (ap->descr->type_num) { case PyArray_CFLOAT: case PyArray_CDOUBLE: classID = mxDOUBLE_CLASS; is_reference = false; break; case PyArray_BOOL: classID = mxLOGICAL_CLASS; is_reference = true; break; case PyArray_CHAR: classID = mxCHAR_CLASS; is_reference = true; break; case PyArray_DOUBLE: classID = mxDOUBLE_CLASS; is_reference = true; break; case PyArray_FLOAT: classID = mxSINGLE_CLASS; is_reference = true; break; case PyArray_INT8: classID = mxINT8_CLASS; is_reference = true; break; case PyArray_UINT8: classID = mxUINT8_CLASS; is_reference = true; break; case PyArray_INT16: classID = mxINT16_CLASS; is_reference = true; break; case PyArray_UINT16: classID = mxUINT16_CLASS; is_reference = true; break; case PyArray_INT32: classID = mxINT32_CLASS; is_reference = true; break; case PyArray_UINT32: classID = mxUINT32_CLASS; is_reference = true; break; #ifdef NPY_INT64 case PyArray_INT64: classID = mxINT64_CLASS; is_reference = true; break; case PyArray_UINT64: classID = mxUINT64_CLASS; is_reference = true; break; #endif } if (!is_reference) { lRetval = mxCreateNumericArray(nDims,dims,classID,lIsComplex ? mxCOMPLEX : mxREAL); } else { /* // code for create and mxArray ref on the numpy object lRetval = mxCreateNumericArray(2, dimsEmpty, classID, lIsComplex ? mxCOMPLEX : mxREAL); if (mxSetDimensions(lRetval, dims, nDims) == 1) { // failed to reset the dimensions mxDestroyArray(lRetval); lRetval = NULL; } else { mxSetData(lRetval, PyArray_DATA(ap)); } */ // uses memcopy for faster copying is_reference = false; lRetval = mxCreateNumericArray(nDims, dims, classID, lIsComplex ? mxCOMPLEX : mxREAL); // this is a sanity check, it should not fail int matlab_nbytes = mxGetNumberOfElements(lRetval) * mxGetElementSize(lRetval); if (matlab_nbytes == PyArray_NBYTES(pSrc)) { memcpy(mxGetData(lRetval), PyArray_DATA(ap), PyArray_NBYTES(pSrc)); } else { PyErr_SetString(PyExc_TypeError, "Number of bytes do not match"); } } } if (lRetval == NULL) return NULL; lR = mxGetPr(lRetval); lI = mxGetPi(lRetval); if (lIsNotAMatrix) { void *p = PyArray_DATA(ap); switch (ap->descr->type_num) { case PyArray_CHAR: copyNumericVector2Mx((char *)(p), lRows, lR, pSrc->strides); break; case PyArray_UBYTE: copyNumericVector2Mx((unsigned char *)(p), lRows, lR, pSrc->strides); break; case PyArray_SBYTE: copyNumericVector2Mx((signed char *)(p), lRows, lR, pSrc->strides); break; case PyArray_SHORT: copyNumericVector2Mx((short *)(p), lRows, lR, pSrc->strides); break; case PyArray_INT: copyNumericVector2Mx((int *)(p), lRows, lR, pSrc->strides); break; case PyArray_LONG: copyNumericVector2Mx((long *)(p), lRows, lR, pSrc->strides); break; case PyArray_FLOAT: copyNumericVector2Mx((float *)(p), lRows, lR, pSrc->strides); break; case PyArray_DOUBLE: copyNumericVector2Mx((double *)(p), lRows, lR, pSrc->strides); break; case PyArray_CFLOAT: copyCplxNumericVector2Mx((float *)(p), lRows, lR, lI, pSrc->strides); break; case PyArray_CDOUBLE: copyCplxNumericVector2Mx((double *)(p), lRows, lR, lI, pSrc->strides); break; } } else { void *p = PyArray_DATA(ap); npy_intp size = PyArray_SIZE(pSrc); switch (pSrc->descr->type_num) { case PyArray_CFLOAT: copyCplxNumeric2Mx((float *)p,size,lR,lI); break; case PyArray_CDOUBLE: copyCplxNumeric2Mx((double *)p,size,lR,lI); break; } } if(ap != pSrc){ Py_DECREF(const_cast<PyArrayObject *>(ap)); } return lRetval; }
/*NUMPY_API * Clip */ NPY_NO_EXPORT PyObject * PyArray_Clip(PyArrayObject *self, PyObject *min, PyObject *max, PyArrayObject *out) { PyArray_FastClipFunc *func; int outgood = 0, ingood = 0; PyArrayObject *maxa = NULL; PyArrayObject *mina = NULL; PyArrayObject *newout = NULL, *newin = NULL; PyArray_Descr *indescr = NULL, *newdescr = NULL; char *max_data, *min_data; PyObject *zero; /* Treat None the same as NULL */ if (min == Py_None) { min = NULL; } if (max == Py_None) { max = NULL; } if ((max == NULL) && (min == NULL)) { PyErr_SetString(PyExc_ValueError, "array_clip: must set either max or min"); return NULL; } func = PyArray_DESCR(self)->f->fastclip; if (func == NULL || (min != NULL && !PyArray_CheckAnyScalar(min)) || (max != NULL && !PyArray_CheckAnyScalar(max)) || PyArray_ISBYTESWAPPED(self) || (out && PyArray_ISBYTESWAPPED(out))) { return _slow_array_clip(self, min, max, out); } /* Use the fast scalar clip function */ /* First we need to figure out the correct type */ if (min != NULL) { indescr = PyArray_DescrFromObject(min, NULL); if (indescr == NULL) { goto fail; } } if (max != NULL) { newdescr = PyArray_DescrFromObject(max, indescr); Py_XDECREF(indescr); indescr = NULL; if (newdescr == NULL) { goto fail; } } else { /* Steal the reference */ newdescr = indescr; indescr = NULL; } /* * Use the scalar descriptor only if it is of a bigger * KIND than the input array (and then find the * type that matches both). */ if (PyArray_ScalarKind(newdescr->type_num, NULL) > PyArray_ScalarKind(PyArray_DESCR(self)->type_num, NULL)) { indescr = PyArray_PromoteTypes(newdescr, PyArray_DESCR(self)); if (indescr == NULL) { goto fail; } func = indescr->f->fastclip; if (func == NULL) { Py_DECREF(indescr); return _slow_array_clip(self, min, max, out); } } else { indescr = PyArray_DESCR(self); Py_INCREF(indescr); } Py_DECREF(newdescr); newdescr = NULL; if (!PyDataType_ISNOTSWAPPED(indescr)) { PyArray_Descr *descr2; descr2 = PyArray_DescrNewByteorder(indescr, '='); Py_DECREF(indescr); indescr = NULL; if (descr2 == NULL) { goto fail; } indescr = descr2; } /* Convert max to an array */ if (max != NULL) { Py_INCREF(indescr); maxa = (PyArrayObject *)PyArray_FromAny(max, indescr, 0, 0, NPY_ARRAY_DEFAULT, NULL); if (maxa == NULL) { goto fail; } } /* * If we are unsigned, then make sure min is not < 0 * This is to match the behavior of _slow_array_clip * * We allow min and max to go beyond the limits * for other data-types in which case they * are interpreted as their modular counterparts. */ if (min != NULL) { if (PyArray_ISUNSIGNED(self)) { int cmp; zero = PyInt_FromLong(0); cmp = PyObject_RichCompareBool(min, zero, Py_LT); if (cmp == -1) { Py_DECREF(zero); goto fail; } if (cmp == 1) { min = zero; } else { Py_DECREF(zero); Py_INCREF(min); } } else { Py_INCREF(min); } /* Convert min to an array */ Py_INCREF(indescr); mina = (PyArrayObject *)PyArray_FromAny(min, indescr, 0, 0, NPY_ARRAY_DEFAULT, NULL); Py_DECREF(min); if (mina == NULL) { goto fail; } } /* * Check to see if input is single-segment, aligned, * and in native byteorder */ if (PyArray_ISONESEGMENT(self) && PyArray_CHKFLAGS(self, NPY_ARRAY_ALIGNED) && PyArray_ISNOTSWAPPED(self) && (PyArray_DESCR(self) == indescr)) { ingood = 1; } if (!ingood) { int flags; if (PyArray_ISFORTRAN(self)) { flags = NPY_ARRAY_FARRAY; } else { flags = NPY_ARRAY_CARRAY; } Py_INCREF(indescr); newin = (PyArrayObject *)PyArray_FromArray(self, indescr, flags); if (newin == NULL) { goto fail; } } else { newin = self; Py_INCREF(newin); } /* * At this point, newin is a single-segment, aligned, and correct * byte-order array of the correct type * * if ingood == 0, then it is a copy, otherwise, * it is the original input. */ /* * If we have already made a copy of the data, then use * that as the output array */ if (out == NULL && !ingood) { out = newin; } /* * Now, we know newin is a usable array for fastclip, * we need to make sure the output array is available * and usable */ if (out == NULL) { Py_INCREF(indescr); out = (PyArrayObject*)PyArray_NewFromDescr(Py_TYPE(self), indescr, PyArray_NDIM(self), PyArray_DIMS(self), NULL, NULL, PyArray_ISFORTRAN(self), (PyObject *)self); if (out == NULL) { goto fail; } outgood = 1; } else Py_INCREF(out); /* Input is good at this point */ if (out == newin) { outgood = 1; } /* make sure the shape of the output array is the same */ if (!PyArray_SAMESHAPE(newin, out)) { PyErr_SetString(PyExc_ValueError, "clip: Output array must have the" "same shape as the input."); goto fail; } if (!outgood && PyArray_EQUIVALENTLY_ITERABLE( self, out, PyArray_TRIVIALLY_ITERABLE_OP_READ, PyArray_TRIVIALLY_ITERABLE_OP_NOREAD) && PyArray_CHKFLAGS(out, NPY_ARRAY_ALIGNED) && PyArray_ISNOTSWAPPED(out) && PyArray_EquivTypes(PyArray_DESCR(out), indescr)) { outgood = 1; } /* * Do we still not have a suitable output array? * Create one, now. No matter why the array is not suitable a copy has * to be made. This may be just to avoid memory overlap though. */ if (!outgood) { int oflags; if (PyArray_ISFORTRAN(self)) { oflags = NPY_ARRAY_FARRAY; } else { oflags = NPY_ARRAY_CARRAY; } oflags |= (NPY_ARRAY_WRITEBACKIFCOPY | NPY_ARRAY_FORCECAST | NPY_ARRAY_ENSURECOPY); Py_INCREF(indescr); newout = (PyArrayObject*)PyArray_FromArray(out, indescr, oflags); if (newout == NULL) { goto fail; } } else { newout = out; Py_INCREF(newout); } /* Now we can call the fast-clip function */ min_data = max_data = NULL; if (mina != NULL) { min_data = PyArray_DATA(mina); } if (maxa != NULL) { max_data = PyArray_DATA(maxa); } func(PyArray_DATA(newin), PyArray_SIZE(newin), min_data, max_data, PyArray_DATA(newout)); /* Clean up temporary variables */ Py_XDECREF(indescr); Py_XDECREF(newdescr); Py_XDECREF(mina); Py_XDECREF(maxa); Py_DECREF(newin); /* Copy back into out if out was not already a nice array. */ PyArray_ResolveWritebackIfCopy(newout); Py_DECREF(newout); return (PyObject *)out; fail: Py_XDECREF(indescr); Py_XDECREF(newdescr); Py_XDECREF(maxa); Py_XDECREF(mina); Py_XDECREF(newin); PyArray_DiscardWritebackIfCopy(newout); Py_XDECREF(newout); return NULL; }
/*NUMPY_API * ArgMax */ NPY_NO_EXPORT PyObject * PyArray_ArgMax(PyArrayObject *op, int axis, PyArrayObject *out) { PyArrayObject *ap = NULL, *rp = NULL; PyArray_ArgFunc* arg_func; char *ip; npy_intp *rptr; npy_intp i, n, m; int elsize; NPY_BEGIN_THREADS_DEF; if ((ap = (PyArrayObject *)PyArray_CheckAxis(op, &axis, 0)) == NULL) { return NULL; } /* * We need to permute the array so that axis is placed at the end. * And all other dimensions are shifted left. */ if (axis != PyArray_NDIM(ap)-1) { PyArray_Dims newaxes; npy_intp dims[NPY_MAXDIMS]; int j; newaxes.ptr = dims; newaxes.len = PyArray_NDIM(ap); for (j = 0; j < axis; j++) { dims[j] = j; } for (j = axis; j < PyArray_NDIM(ap) - 1; j++) { dims[j] = j + 1; } dims[PyArray_NDIM(ap) - 1] = axis; op = (PyArrayObject *)PyArray_Transpose(ap, &newaxes); Py_DECREF(ap); if (op == NULL) { return NULL; } } else { op = ap; } /* Will get native-byte order contiguous copy. */ ap = (PyArrayObject *)PyArray_ContiguousFromAny((PyObject *)op, PyArray_DESCR(op)->type_num, 1, 0); Py_DECREF(op); if (ap == NULL) { return NULL; } arg_func = PyArray_DESCR(ap)->f->argmax; if (arg_func == NULL) { PyErr_SetString(PyExc_TypeError, "data type not ordered"); goto fail; } elsize = PyArray_DESCR(ap)->elsize; m = PyArray_DIMS(ap)[PyArray_NDIM(ap)-1]; if (m == 0) { PyErr_SetString(PyExc_ValueError, "attempt to get argmax of an empty sequence"); goto fail; } if (!out) { rp = (PyArrayObject *)PyArray_NewFromDescr( Py_TYPE(ap), PyArray_DescrFromType(NPY_INTP), PyArray_NDIM(ap) - 1, PyArray_DIMS(ap), NULL, NULL, 0, (PyObject *)ap); if (rp == NULL) { goto fail; } } else { if ((PyArray_NDIM(out) != PyArray_NDIM(ap) - 1) || !PyArray_CompareLists(PyArray_DIMS(out), PyArray_DIMS(ap), PyArray_NDIM(out))) { PyErr_SetString(PyExc_ValueError, "output array does not match result of np.argmax."); goto fail; } rp = (PyArrayObject *)PyArray_FromArray(out, PyArray_DescrFromType(NPY_INTP), NPY_ARRAY_CARRAY | NPY_ARRAY_WRITEBACKIFCOPY); if (rp == NULL) { goto fail; } } NPY_BEGIN_THREADS_DESCR(PyArray_DESCR(ap)); n = PyArray_SIZE(ap)/m; rptr = (npy_intp *)PyArray_DATA(rp); for (ip = PyArray_DATA(ap), i = 0; i < n; i++, ip += elsize*m) { arg_func(ip, m, rptr, ap); rptr += 1; } NPY_END_THREADS_DESCR(PyArray_DESCR(ap)); Py_DECREF(ap); /* Trigger the UPDATEIFCOPY/WRTIEBACKIFCOPY if necessary */ if (out != NULL && out != rp) { PyArray_ResolveWritebackIfCopy(rp); Py_DECREF(rp); rp = out; Py_INCREF(rp); } return (PyObject *)rp; fail: Py_DECREF(ap); Py_XDECREF(rp); return NULL; }
/*! @brief save an ANA format image to disk @param [in] filename Full path to write data to @param [in] data Data to write (numpy array) @param [in] compress Apply (Rice) compression or not @param [in] header Add a header to the file (or use default) @return number of bytes read on success, NULL pointer on failure */ static PyObject * pyana_fzwrite(PyObject *self, PyObject *args) { // Python function arguments char *filename = NULL; PyArrayObject *anadata; int compress = 1, debug=0; char *header = NULL; // Processed data goes here PyObject *anadata_align; uint8_t *anadata_bytes; // ANA file writing int type, d; // Parse arguments from Python function if (!PyArg_ParseTuple(args, "sO!|isi", &filename, &PyArray_Type, &anadata, &compress, &header, &debug)) return NULL; // Check if filename was parsed correctly (should be, otherwise // PyArg_ParseTuple should have raised an error, obsolete?) if (NULL == filename) { PyErr_SetString(PyExc_ValueError, "In pyana_fzwrite: invalid filename."); return NULL; } // If header is NULL, then set the comment to a default value if (NULL == header) { if (debug == 1) printf("pyana_fzwrite(): Setting default header\n"); struct timeval *tv_time=NULL; struct tm *tm_time=NULL; gettimeofday(tv_time, NULL); tm_time = gmtime(&(tv_time->tv_sec)); asprintf(&header, "#%-42s compress=%d date=%02d:%02d:%02d.%03ld\n", filename, compress, tm_time->tm_hour, tm_time->tm_min, tm_time->tm_sec, (long) (tv_time->tv_usec/1000)); } if (debug == 1) printf("pyana_fzwrite(): Header: '%s'\n", header); // Convert datatype from PyArray type to ANA type, and verify that ANA // supports it switch (PyArray_TYPE((PyObject *) anadata)) { case (PyArray_INT8): type = INT8; if (debug == 1) printf("pyana_fzwrite(): Found type PyArray_INT8\n"); break; case (PyArray_INT16): type = INT16; if (debug == 1) printf("pyana_fzwrite(): Found type PyArray_INT16\n"); break; case (PyArray_FLOAT32): type = FLOAT32; if (debug == 1) printf("pyana_fzwrite(): Found type PyArray_FLOAT32\n"); break; case (PyArray_FLOAT64): type = FLOAT64; if (debug == 1) printf("pyana_fzwrite(): Found type PyArray_FLOAT64\n"); break; //case (PyArray_INT64): type = INT64; break; default: PyErr_SetString(PyExc_ValueError, "In pyana_fzwrite: datatype cannot be stored as ANA file."); return NULL; break; } // Check if compression flag is sane if (compress == 1 && (type == FLOAT32 || type == FLOAT64)) { PyErr_SetString(PyExc_RuntimeError, "In pyana_fzwrite: datatype requested cannot be compressed."); return NULL; } if (debug == 1) printf("pyana_fzwrite(): pyarray datatype is %d, ana datatype is %d\n", PyArray_TYPE((PyObject *) anadata), type); // Sanitize data, make a new array from the old array and force the // NPY_CARRAY_RO requirement which ensures a C-contiguous and aligned // array will be made anadata_align = PyArray_FromArray(anadata, PyArray_DESCR((PyObject *) anadata), NPY_CARRAY_RO); // Get a pointer to the aligned data anadata_bytes = (uint8_t *) PyArray_BYTES(anadata_align); // Get the number of dimensions PyArrayObject *arrobj = (PyArrayObject*) anadata_align; int nd = arrobj->nd; int *dims = malloc(nd*sizeof(int)); // Get the dimensions and number of elements npy_intp *npy_dims = PyArray_DIMS(anadata_align); //npy_intp npy_nelem = PyArray_SIZE(anadata_align); if (debug == 1) printf("pyana_fzwrite(): Dimensions: "); for (d=0; d<nd; d++) { // ANA stores dimensions the other way around? //dims[d] = npy_dims[d]; dims[d] = npy_dims[nd-1-d]; if (debug == 1) printf(" %d", dims[d]); } if (debug == 1) printf("\npyana_fzwrite(): Total is %d-dimensional\n", nd); // Write ANA file if (debug == 1) printf("pyana_fzwrite(): Compress: %d\n", compress); if (compress == 1) ana_fcwrite(anadata_bytes, filename, dims, nd, header, type, 5); else ana_fzwrite(anadata_bytes, filename, dims, nd, header, type); free(dims); // If we didn't crash up to here, we're probably ok :P return Py_BuildValue("i", 1); }
/*NUMPY_API * ArgMin */ NPY_NO_EXPORT PyObject * PyArray_ArgMin(PyArrayObject *op, int axis, PyArrayObject *out) { PyArrayObject *ap = NULL, *rp = NULL; PyArray_ArgFunc* arg_func; char *ip; intp *rptr; intp i, n, m; int elsize; NPY_BEGIN_THREADS_DEF; if ((ap = (PyArrayObject *)PyArray_CheckAxis(op, &axis, 0)) == NULL) { return NULL; } /* * We need to permute the array so that axis is placed at the end. * And all other dimensions are shifted left. */ if (axis != PyArray_NDIM(ap)-1) { PyArray_Dims newaxes; intp dims[MAX_DIMS]; int i; newaxes.ptr = dims; newaxes.len = PyArray_NDIM(ap); for (i = 0; i < axis; i++) { dims[i] = i; } for (i = axis; i < PyArray_NDIM(ap) - 1; i++) { dims[i] = i + 1; } dims[PyArray_NDIM(ap) - 1] = axis; op = (PyArrayObject *)PyArray_Transpose(ap, &newaxes); Py_DECREF(ap); if (op == NULL) { return NULL; } } else { op = ap; } /* Will get native-byte order contiguous copy. */ ap = (PyArrayObject *)PyArray_ContiguousFromAny((PyObject *)op, PyArray_DESCR(op)->type_num, 1, 0); Py_DECREF(op); if (ap == NULL) { return NULL; } arg_func = PyArray_DESCR(ap)->f->argmin; if (arg_func == NULL) { PyErr_SetString(PyExc_TypeError, "data type not ordered"); goto fail; } elsize = PyArray_DESCR(ap)->elsize; m = PyArray_DIMS(ap)[PyArray_NDIM(ap)-1]; if (m == 0) { PyErr_SetString(PyExc_ValueError, "attempt to get argmin of an empty sequence"); goto fail; } if (!out) { rp = (PyArrayObject *)PyArray_New(Py_TYPE(ap), PyArray_NDIM(ap)-1, PyArray_DIMS(ap), PyArray_INTP, NULL, NULL, 0, 0, (PyObject *)ap); if (rp == NULL) { goto fail; } } else { if (PyArray_SIZE(out) != PyArray_MultiplyList(PyArray_DIMS(ap), PyArray_NDIM(ap) - 1)) { PyErr_SetString(PyExc_TypeError, "invalid shape for output array."); } rp = (PyArrayObject *)PyArray_FromArray(out, PyArray_DescrFromType(PyArray_INTP), NPY_ARRAY_CARRAY | NPY_ARRAY_UPDATEIFCOPY); if (rp == NULL) { goto fail; } } NPY_BEGIN_THREADS_DESCR(PyArray_DESCR(ap)); n = PyArray_SIZE(ap)/m; rptr = (intp *)PyArray_DATA(rp); for (ip = PyArray_DATA(ap), i = 0; i < n; i++, ip += elsize*m) { arg_func(ip, m, rptr, ap); rptr += 1; } NPY_END_THREADS_DESCR(PyArray_DESCR(ap)); Py_DECREF(ap); /* Trigger the UPDATEIFCOPY if necessary */ if (out != NULL && out != rp) { Py_DECREF(rp); rp = out; Py_INCREF(rp); } return (PyObject *)rp; fail: Py_DECREF(ap); Py_XDECREF(rp); return NULL; }