/*NUMPY_API * Round */ NPY_NO_EXPORT PyObject * PyArray_Round(PyArrayObject *a, int decimals, PyArrayObject *out) { PyObject *f, *ret = NULL, *tmp, *op1, *op2; int ret_int=0; PyArray_Descr *my_descr; if (out && (PyArray_SIZE(out) != PyArray_SIZE(a))) { PyErr_SetString(PyExc_ValueError, "invalid output shape"); return NULL; } if (PyArray_ISCOMPLEX(a)) { PyObject *part; PyObject *round_part; PyObject *arr; int res; if (out) { arr = (PyObject *)out; Py_INCREF(arr); } else { arr = PyArray_Copy(a); if (arr == NULL) { return NULL; } } /* arr.real = a.real.round(decimals) */ part = PyObject_GetAttrString((PyObject *)a, "real"); if (part == NULL) { Py_DECREF(arr); return NULL; } part = PyArray_EnsureAnyArray(part); round_part = PyArray_Round((PyArrayObject *)part, decimals, NULL); Py_DECREF(part); if (round_part == NULL) { Py_DECREF(arr); return NULL; } res = PyObject_SetAttrString(arr, "real", round_part); Py_DECREF(round_part); if (res < 0) { Py_DECREF(arr); return NULL; } /* arr.imag = a.imag.round(decimals) */ part = PyObject_GetAttrString((PyObject *)a, "imag"); if (part == NULL) { Py_DECREF(arr); return NULL; } part = PyArray_EnsureAnyArray(part); round_part = PyArray_Round((PyArrayObject *)part, decimals, NULL); Py_DECREF(part); if (round_part == NULL) { Py_DECREF(arr); return NULL; } res = PyObject_SetAttrString(arr, "imag", round_part); Py_DECREF(round_part); if (res < 0) { Py_DECREF(arr); return NULL; } return arr; } /* do the most common case first */ if (decimals >= 0) { if (PyArray_ISINTEGER(a)) { if (out) { if (PyArray_AssignArray(out, a, NULL, NPY_DEFAULT_ASSIGN_CASTING) < 0) { return NULL; } Py_INCREF(out); return (PyObject *)out; } else { Py_INCREF(a); return (PyObject *)a; } } if (decimals == 0) { if (out) { return PyObject_CallFunction(n_ops.rint, "OO", a, out); } return PyObject_CallFunction(n_ops.rint, "O", a); } op1 = n_ops.multiply; op2 = n_ops.true_divide; } else { op1 = n_ops.true_divide; op2 = n_ops.multiply; decimals = -decimals; } if (!out) { if (PyArray_ISINTEGER(a)) { ret_int = 1; my_descr = PyArray_DescrFromType(NPY_DOUBLE); } else { Py_INCREF(PyArray_DESCR(a)); my_descr = PyArray_DESCR(a); } out = (PyArrayObject *)PyArray_Empty(PyArray_NDIM(a), PyArray_DIMS(a), my_descr, PyArray_ISFORTRAN(a)); if (out == NULL) { return NULL; } } else { Py_INCREF(out); } f = PyFloat_FromDouble(power_of_ten(decimals)); if (f == NULL) { return NULL; } ret = PyObject_CallFunction(op1, "OOO", a, f, out); if (ret == NULL) { goto finish; } tmp = PyObject_CallFunction(n_ops.rint, "OO", ret, ret); if (tmp == NULL) { Py_DECREF(ret); ret = NULL; goto finish; } Py_DECREF(tmp); tmp = PyObject_CallFunction(op2, "OOO", ret, f, ret); if (tmp == NULL) { Py_DECREF(ret); ret = NULL; goto finish; } Py_DECREF(tmp); finish: Py_DECREF(f); Py_DECREF(out); if (ret_int) { Py_INCREF(PyArray_DESCR(a)); tmp = PyArray_CastToType((PyArrayObject *)ret, PyArray_DESCR(a), PyArray_ISFORTRAN(a)); Py_DECREF(ret); return tmp; } return ret; }
NPY_NO_EXPORT int PyArray_DTypeFromObjectHelper(PyObject *obj, int maxdims, PyArray_Descr **out_dtype, int string_type) { int i, size; PyArray_Descr *dtype = NULL; PyObject *ip; #if PY_VERSION_HEX >= 0x02060000 Py_buffer buffer_view; #endif /* Check if it's an ndarray */ if (PyArray_Check(obj)) { dtype = PyArray_DESCR((PyArrayObject *)obj); Py_INCREF(dtype); goto promote_types; } /* Check if it's a NumPy scalar */ if (PyArray_IsScalar(obj, Generic)) { if (!string_type) { dtype = PyArray_DescrFromScalar(obj); if (dtype == NULL) { goto fail; } } else { int itemsize; PyObject *temp; if (string_type == NPY_STRING) { if ((temp = PyObject_Str(obj)) == NULL) { return -1; } #if defined(NPY_PY3K) #if PY_VERSION_HEX >= 0x03030000 itemsize = PyUnicode_GetLength(temp); #else itemsize = PyUnicode_GET_SIZE(temp); #endif #else itemsize = PyString_GET_SIZE(temp); #endif } else if (string_type == NPY_UNICODE) { #if defined(NPY_PY3K) if ((temp = PyObject_Str(obj)) == NULL) { #else if ((temp = PyObject_Unicode(obj)) == NULL) { #endif return -1; } itemsize = PyUnicode_GET_DATA_SIZE(temp); #ifndef Py_UNICODE_WIDE itemsize <<= 1; #endif } else { goto fail; } Py_DECREF(temp); if (*out_dtype != NULL && (*out_dtype)->type_num == string_type && (*out_dtype)->elsize >= itemsize) { return 0; } dtype = PyArray_DescrNewFromType(string_type); if (dtype == NULL) { goto fail; } dtype->elsize = itemsize; } goto promote_types; } /* Check if it's a Python scalar */ dtype = _array_find_python_scalar_type(obj); if (dtype != NULL) { if (string_type) { int itemsize; PyObject *temp; if (string_type == NPY_STRING) { if ((temp = PyObject_Str(obj)) == NULL) { return -1; } #if defined(NPY_PY3K) #if PY_VERSION_HEX >= 0x03030000 itemsize = PyUnicode_GetLength(temp); #else itemsize = PyUnicode_GET_SIZE(temp); #endif #else itemsize = PyString_GET_SIZE(temp); #endif } else if (string_type == NPY_UNICODE) { #if defined(NPY_PY3K) if ((temp = PyObject_Str(obj)) == NULL) { #else if ((temp = PyObject_Unicode(obj)) == NULL) { #endif return -1; } itemsize = PyUnicode_GET_DATA_SIZE(temp); #ifndef Py_UNICODE_WIDE itemsize <<= 1; #endif } else { goto fail; } Py_DECREF(temp); if (*out_dtype != NULL && (*out_dtype)->type_num == string_type && (*out_dtype)->elsize >= itemsize) { return 0; } dtype = PyArray_DescrNewFromType(string_type); if (dtype == NULL) { goto fail; } dtype->elsize = itemsize; } goto promote_types; } /* Check if it's an ASCII string */ if (PyBytes_Check(obj)) { int itemsize = PyString_GET_SIZE(obj); /* If it's already a big enough string, don't bother type promoting */ if (*out_dtype != NULL && (*out_dtype)->type_num == NPY_STRING && (*out_dtype)->elsize >= itemsize) { return 0; } dtype = PyArray_DescrNewFromType(NPY_STRING); if (dtype == NULL) { goto fail; } dtype->elsize = itemsize; goto promote_types; } /* Check if it's a Unicode string */ if (PyUnicode_Check(obj)) { int itemsize = PyUnicode_GET_DATA_SIZE(obj); #ifndef Py_UNICODE_WIDE itemsize <<= 1; #endif /* * If it's already a big enough unicode object, * don't bother type promoting */ if (*out_dtype != NULL && (*out_dtype)->type_num == NPY_UNICODE && (*out_dtype)->elsize >= itemsize) { return 0; } dtype = PyArray_DescrNewFromType(NPY_UNICODE); if (dtype == NULL) { goto fail; } dtype->elsize = itemsize; goto promote_types; } #if PY_VERSION_HEX >= 0x02060000 /* PEP 3118 buffer interface */ memset(&buffer_view, 0, sizeof(Py_buffer)); if (PyObject_GetBuffer(obj, &buffer_view, PyBUF_FORMAT|PyBUF_STRIDES) == 0 || PyObject_GetBuffer(obj, &buffer_view, PyBUF_FORMAT) == 0) { PyErr_Clear(); dtype = _descriptor_from_pep3118_format(buffer_view.format); PyBuffer_Release(&buffer_view); if (dtype) { goto promote_types; } } else if (PyObject_GetBuffer(obj, &buffer_view, PyBUF_STRIDES) == 0 || PyObject_GetBuffer(obj, &buffer_view, PyBUF_SIMPLE) == 0) { PyErr_Clear(); dtype = PyArray_DescrNewFromType(NPY_VOID); dtype->elsize = buffer_view.itemsize; PyBuffer_Release(&buffer_view); goto promote_types; } else { PyErr_Clear(); } #endif /* The array interface */ ip = PyObject_GetAttrString(obj, "__array_interface__"); if (ip != NULL) { if (PyDict_Check(ip)) { PyObject *typestr; #if defined(NPY_PY3K) PyObject *tmp = NULL; #endif typestr = PyDict_GetItemString(ip, "typestr"); #if defined(NPY_PY3K) /* Allow unicode type strings */ if (PyUnicode_Check(typestr)) { tmp = PyUnicode_AsASCIIString(typestr); typestr = tmp; } #endif if (typestr && PyBytes_Check(typestr)) { dtype =_array_typedescr_fromstr(PyBytes_AS_STRING(typestr)); #if defined(NPY_PY3K) if (tmp == typestr) { Py_DECREF(tmp); } #endif Py_DECREF(ip); if (dtype == NULL) { goto fail; } goto promote_types; } } Py_DECREF(ip); } else { PyErr_Clear(); } /* The array struct interface */ ip = PyObject_GetAttrString(obj, "__array_struct__"); if (ip != NULL) { PyArrayInterface *inter; char buf[40]; if (NpyCapsule_Check(ip)) { inter = (PyArrayInterface *)NpyCapsule_AsVoidPtr(ip); if (inter->two == 2) { PyOS_snprintf(buf, sizeof(buf), "|%c%d", inter->typekind, inter->itemsize); dtype = _array_typedescr_fromstr(buf); Py_DECREF(ip); if (dtype == NULL) { goto fail; } goto promote_types; } } Py_DECREF(ip); } else { PyErr_Clear(); } /* The old buffer interface */ #if !defined(NPY_PY3K) if (PyBuffer_Check(obj)) { dtype = PyArray_DescrNewFromType(NPY_VOID); if (dtype == NULL) { goto fail; } dtype->elsize = Py_TYPE(obj)->tp_as_sequence->sq_length(obj); PyErr_Clear(); goto promote_types; } #endif /* The __array__ attribute */ if (PyObject_HasAttrString(obj, "__array__")) { ip = PyObject_CallMethod(obj, "__array__", NULL); if(ip && PyArray_Check(ip)) { dtype = PyArray_DESCR((PyArrayObject *)ip); Py_INCREF(dtype); Py_DECREF(ip); goto promote_types; } Py_XDECREF(ip); if (PyErr_Occurred()) { goto fail; } } /* Not exactly sure what this is about... */ #if !defined(NPY_PY3K) if (PyInstance_Check(obj)) { dtype = _use_default_type(obj); if (dtype == NULL) { goto fail; } else { goto promote_types; } } #endif /* * If we reached the maximum recursion depth without hitting one * of the above cases, the output dtype should be OBJECT */ if (maxdims == 0 || !PySequence_Check(obj)) { if (*out_dtype == NULL || (*out_dtype)->type_num != NPY_OBJECT) { Py_XDECREF(*out_dtype); *out_dtype = PyArray_DescrFromType(NPY_OBJECT); if (*out_dtype == NULL) { return -1; } } return 0; } /* Recursive case */ size = PySequence_Size(obj); if (size < 0) { goto fail; } /* Recursive call for each sequence item */ for (i = 0; i < size; ++i) { int res; ip = PySequence_GetItem(obj, i); if (ip == NULL) { goto fail; } res = PyArray_DTypeFromObjectHelper(ip, maxdims - 1, out_dtype, string_type); if (res < 0) { Py_DECREF(ip); goto fail; } else if (res > 0) { Py_DECREF(ip); return res; } Py_DECREF(ip); } return 0; promote_types: /* Set 'out_dtype' if it's NULL */ if (*out_dtype == NULL) { if (!string_type && dtype->type_num == NPY_STRING) { Py_DECREF(dtype); return RETRY_WITH_STRING; } if (!string_type && dtype->type_num == NPY_UNICODE) { Py_DECREF(dtype); return RETRY_WITH_UNICODE; } *out_dtype = dtype; return 0; } /* Do type promotion with 'out_dtype' */ else { PyArray_Descr *res_dtype = PyArray_PromoteTypes(dtype, *out_dtype); Py_DECREF(dtype); if (res_dtype == NULL) { return -1; } if (!string_type && res_dtype->type_num == NPY_UNICODE && (*out_dtype)->type_num != NPY_UNICODE) { Py_DECREF(res_dtype); return RETRY_WITH_UNICODE; } if (!string_type && res_dtype->type_num == NPY_STRING && (*out_dtype)->type_num != NPY_STRING) { Py_DECREF(res_dtype); return RETRY_WITH_STRING; } Py_DECREF(*out_dtype); *out_dtype = res_dtype; return 0; } fail: Py_XDECREF(*out_dtype); *out_dtype = NULL; return -1; } #undef RETRY_WITH_STRING #undef RETRY_WITH_UNICODE /* new reference */ NPY_NO_EXPORT PyArray_Descr * _array_typedescr_fromstr(char *c_str) { PyArray_Descr *descr = NULL; PyObject *stringobj = PyString_FromString(c_str); if (stringobj == NULL) { return NULL; } if (PyArray_DescrConverter(stringobj, &descr) != NPY_SUCCEED) { Py_DECREF(stringobj); return NULL; } Py_DECREF(stringobj); return descr; } NPY_NO_EXPORT int check_and_adjust_index(npy_intp *index, npy_intp max_item, int axis) { /* Check that index is valid, taking into account negative indices */ if ((*index < -max_item) || (*index >= max_item)) { /* Try to be as clear as possible about what went wrong. */ if (axis >= 0) { PyErr_Format(PyExc_IndexError, "index %"NPY_INTP_FMT" is out of bounds " "for axis %d with size %"NPY_INTP_FMT, *index, axis, max_item); } else { PyErr_Format(PyExc_IndexError, "index %"NPY_INTP_FMT" is out of bounds " "for size %"NPY_INTP_FMT, *index, max_item); } return -1; } /* adjust negative indices */ if (*index < 0) { *index += max_item; } return 0; } NPY_NO_EXPORT char * index2ptr(PyArrayObject *mp, npy_intp i) { npy_intp dim0; if (PyArray_NDIM(mp) == 0) { PyErr_SetString(PyExc_IndexError, "0-d arrays can't be indexed"); return NULL; } dim0 = PyArray_DIMS(mp)[0]; if (check_and_adjust_index(&i, dim0, 0) < 0) return NULL; if (i == 0) { return PyArray_DATA(mp); } return PyArray_BYTES(mp)+i*PyArray_STRIDES(mp)[0]; }
/* * Conforms an output parameter 'out' to have 'ndim' dimensions * with dimensions of size one added in the appropriate places * indicated by 'axis_flags'. * * The return value is a view into 'out'. */ static PyArrayObject * conform_reduce_result(int ndim, npy_bool *axis_flags, PyArrayObject *out, int keepdims, const char *funcname) { npy_intp strides[NPY_MAXDIMS], shape[NPY_MAXDIMS]; npy_intp *strides_out = PyArray_STRIDES(out); npy_intp *shape_out = PyArray_DIMS(out); int idim, idim_out, ndim_out = PyArray_NDIM(out); PyArray_Descr *dtype; PyArrayObject_fields *ret; /* * If the 'keepdims' parameter is true, do a simpler validation and * return a new reference to 'out'. */ if (keepdims) { if (PyArray_NDIM(out) != ndim) { PyErr_Format(PyExc_ValueError, "output parameter for reduction operation %s " "has the wrong number of dimensions (must match " "the operand's when keepdims=True)", funcname); return NULL; } for (idim = 0; idim < ndim; ++idim) { if (axis_flags[idim]) { if (shape_out[idim] != 1) { PyErr_Format(PyExc_ValueError, "output parameter for reduction operation %s " "has a reduction dimension not equal to one " "(required when keepdims=True)", funcname); return NULL; } } } Py_INCREF(out); return out; } /* Construct the strides and shape */ idim_out = 0; for (idim = 0; idim < ndim; ++idim) { if (axis_flags[idim]) { strides[idim] = 0; shape[idim] = 1; } else { if (idim_out >= ndim_out) { PyErr_Format(PyExc_ValueError, "output parameter for reduction operation %s " "does not have enough dimensions", funcname); return NULL; } strides[idim] = strides_out[idim_out]; shape[idim] = shape_out[idim_out]; ++idim_out; } } if (idim_out != ndim_out) { PyErr_Format(PyExc_ValueError, "output parameter for reduction operation %s " "has too many dimensions", funcname); return NULL; } /* Allocate the view */ dtype = PyArray_DESCR(out); Py_INCREF(dtype); ret = (PyArrayObject_fields *)PyArray_NewFromDescr(&PyArray_Type, dtype, ndim, shape, strides, PyArray_DATA(out), PyArray_FLAGS(out), NULL); if (ret == NULL) { return NULL; } Py_INCREF(out); if (PyArray_SetBaseObject((PyArrayObject *)ret, (PyObject *)out) < 0) { Py_DECREF(ret); return NULL; } return (PyArrayObject *)ret; }
static PyObject* gist_extract(PyObject *self, PyObject *args) { int nblocks=4; int n_scale=3; int orientations_per_scale[50]={8,8,4}; PyArrayObject *image, *descriptor; if (!PyArg_ParseTuple(args, "O", &image)) { return NULL; } if (PyArray_TYPE(image) != NPY_UINT8) { PyErr_SetString(PyExc_TypeError, "type of image must be uint8"); return NULL; } if (PyArray_NDIM(image) != 3) { PyErr_SetString(PyExc_TypeError, "dimensions of image must be 3."); return NULL; } npy_intp *dims_image = PyArray_DIMS(image); const int w = (int) *(dims_image+1); const int h = (int) *(dims_image); // Read image to color_image_t structure color_image_t *im=color_image_new(w,h); for (int y=0, i=0 ; y<h ; ++y) { for (int x=0 ; x<w ; ++x, ++i) { im->c1[i] = *(unsigned char *)PyArray_GETPTR3(image, y, x, 0); im->c2[i] = *(unsigned char *)PyArray_GETPTR3(image, y, x, 1); im->c3[i] = *(unsigned char *)PyArray_GETPTR3(image, y, x, 2); } } // Extract descriptor float *desc=color_gist_scaletab(im,nblocks,n_scale,orientations_per_scale); int descsize=0; /* compute descriptor size */ for(int i=0;i<n_scale;i++) descsize+=nblocks*nblocks*orientations_per_scale[i]; descsize*=3; /* color */ // Allocate output npy_intp dim_desc[1] = {descsize}; descriptor = (PyArrayObject *) PyArray_SimpleNew(1, dim_desc, NPY_FLOAT); // Set val for (int i=0 ; i<descsize ; ++i) { *(float *)PyArray_GETPTR1(descriptor, i) = desc[i]; } // Release memory color_image_delete(im); free(desc); return PyArray_Return(descriptor); }
Mat fromNDArrayToMat(PyObject* o) { cv::Mat m; bool allowND = true; if (!PyArray_Check(o)) { failmsg("argument is not a numpy array"); if (!m.data) m.allocator = &g_numpyAllocator; } else { PyArrayObject* oarr = (PyArrayObject*) o; bool needcopy = false, needcast = false; int typenum = PyArray_TYPE(oarr), new_typenum = typenum; int type = typenum == NPY_UBYTE ? CV_8U : typenum == NPY_BYTE ? CV_8S : typenum == NPY_USHORT ? CV_16U : typenum == NPY_SHORT ? CV_16S : typenum == NPY_INT ? CV_32S : typenum == NPY_INT32 ? CV_32S : typenum == NPY_FLOAT ? CV_32F : typenum == NPY_DOUBLE ? CV_64F : -1; if (type < 0) { if (typenum == NPY_INT64 || typenum == NPY_UINT64 || type == NPY_LONG) { needcopy = needcast = true; new_typenum = NPY_INT; type = CV_32S; } else { failmsg("Argument data type is not supported"); m.allocator = &g_numpyAllocator; return m; } } #ifndef CV_MAX_DIM const int CV_MAX_DIM = 32; #endif int ndims = PyArray_NDIM(oarr); if (ndims >= CV_MAX_DIM) { failmsg("Dimensionality of argument is too high"); if (!m.data) m.allocator = &g_numpyAllocator; return m; } int size[CV_MAX_DIM + 1]; size_t step[CV_MAX_DIM + 1]; size_t elemsize = CV_ELEM_SIZE1(type); const npy_intp* _sizes = PyArray_DIMS(oarr); const npy_intp* _strides = PyArray_STRIDES(oarr); bool ismultichannel = ndims == 3 && _sizes[2] <= CV_CN_MAX; for (int i = ndims - 1; i >= 0 && !needcopy; i--) { // these checks handle cases of // a) multi-dimensional (ndims > 2) arrays, as well as simpler 1- and 2-dimensional cases // b) transposed arrays, where _strides[] elements go in non-descending order // c) flipped arrays, where some of _strides[] elements are negative if ((i == ndims - 1 && (size_t) _strides[i] != elemsize) || (i < ndims - 1 && _strides[i] < _strides[i + 1])) needcopy = true; } if (ismultichannel && _strides[1] != (npy_intp) elemsize * _sizes[2]) needcopy = true; if (needcopy) { if (needcast) { o = PyArray_Cast(oarr, new_typenum); oarr = (PyArrayObject*) o; } else { oarr = PyArray_GETCONTIGUOUS(oarr); o = (PyObject*) oarr; } _strides = PyArray_STRIDES(oarr); } for (int i = 0; i < ndims; i++) { size[i] = (int) _sizes[i]; step[i] = (size_t) _strides[i]; } // handle degenerate case if (ndims == 0) { size[ndims] = 1; step[ndims] = elemsize; ndims++; } if (ismultichannel) { ndims--; type |= CV_MAKETYPE(0, size[2]); } if (ndims > 2 && !allowND) { failmsg("%s has more than 2 dimensions"); } else { m = Mat(ndims, size, type, PyArray_DATA(oarr), step); m.u = g_numpyAllocator.allocate(o, ndims, size, type, step); m.addref(); if (!needcopy) { Py_INCREF(o); } } m.allocator = &g_numpyAllocator; } return m; }
/*@null@*/ static PyObject* Wcs_all_pix2world( Wcs* self, PyObject* args, PyObject* kwds) { int naxis = 2; PyObject* pixcrd_obj = NULL; int origin = 1; PyArrayObject* pixcrd = NULL; PyArrayObject* world = NULL; int status = -1; const char* keywords[] = { "pixcrd", "origin", NULL }; if (!PyArg_ParseTupleAndKeywords( args, kwds, "Oi:all_pix2world", (char **)keywords, &pixcrd_obj, &origin)) { return NULL; } naxis = self->x.wcs->naxis; pixcrd = (PyArrayObject*)PyArray_ContiguousFromAny(pixcrd_obj, PyArray_DOUBLE, 2, 2); if (pixcrd == NULL) { return NULL; } if (PyArray_DIM(pixcrd, 1) < naxis) { PyErr_Format( PyExc_RuntimeError, "Input array must be 2-dimensional, where the second dimension >= %d", naxis); goto exit; } world = (PyArrayObject*)PyArray_SimpleNew(2, PyArray_DIMS(pixcrd), PyArray_DOUBLE); if (world == NULL) { goto exit; } /* Make the call */ Py_BEGIN_ALLOW_THREADS preoffset_array(pixcrd, origin); wcsprm_python2c(self->x.wcs); status = pipeline_all_pixel2world(&self->x, (unsigned int)PyArray_DIM(pixcrd, 0), (unsigned int)PyArray_DIM(pixcrd, 1), (double*)PyArray_DATA(pixcrd), (double*)PyArray_DATA(world)); wcsprm_c2python(self->x.wcs); unoffset_array(pixcrd, origin); Py_END_ALLOW_THREADS /* unoffset_array(world, origin); */ exit: Py_XDECREF(pixcrd); if (status == 0 || status == 8) { return (PyObject*)world; } else if (status == -1) { PyErr_SetString( PyExc_ValueError, "Wrong number of dimensions in input array. Expected 2."); return NULL; } else { Py_DECREF(world); if (status == -1) { /* exception already set */ return NULL; } else { wcserr_to_python_exc(self->x.err); return NULL; } } }
/*@null@*/ static PyObject* Wcs_pix2foc( Wcs* self, PyObject* args, PyObject* kwds) { PyObject* pixcrd_obj = NULL; int origin = 1; PyArrayObject* pixcrd = NULL; PyArrayObject* foccrd = NULL; int status = -1; const char* keywords[] = { "pixcrd", "origin", NULL }; if (!PyArg_ParseTupleAndKeywords(args, kwds, "Oi:pix2foc", (char **)keywords, &pixcrd_obj, &origin)) { return NULL; } pixcrd = (PyArrayObject*)PyArray_ContiguousFromAny(pixcrd_obj, PyArray_DOUBLE, 2, 2); if (pixcrd == NULL) { return NULL; } if (PyArray_DIM(pixcrd, 1) != NAXES) { PyErr_SetString(PyExc_ValueError, "Pixel array must be an Nx2 array"); goto _exit; } foccrd = (PyArrayObject*)PyArray_SimpleNew(2, PyArray_DIMS(pixcrd), PyArray_DOUBLE); if (foccrd == NULL) { goto _exit; } Py_BEGIN_ALLOW_THREADS preoffset_array(pixcrd, origin); status = pipeline_pix2foc(&self->x, (unsigned int)PyArray_DIM(pixcrd, 0), (unsigned int)PyArray_DIM(pixcrd, 1), (double*)PyArray_DATA(pixcrd), (double*)PyArray_DATA(foccrd)); unoffset_array(pixcrd, origin); unoffset_array(foccrd, origin); Py_END_ALLOW_THREADS _exit: Py_XDECREF(pixcrd); if (status == 0) { return (PyObject*)foccrd; } else { Py_XDECREF(foccrd); if (status == -1) { /* Exception already set */ return NULL; } else { wcserr_to_python_exc(self->x.err); return NULL; } } }
extern PyArrayObject* array_from_pyobj(const int type_num, npy_intp *dims, const int rank, const int intent, PyObject *obj) { /* Note about reference counting ----------------------------- If the caller returns the array to Python, it must be done with Py_BuildValue("N",arr). Otherwise, if obj!=arr then the caller must call Py_DECREF(arr). Note on intent(cache,out,..) --------------------- Don't expect correct data when returning intent(cache) array. */ char mess[200]; PyArrayObject *arr = NULL; PyArray_Descr *descr; char typechar; int elsize; if ((intent & F2PY_INTENT_HIDE) || ((intent & F2PY_INTENT_CACHE) && (obj==Py_None)) || ((intent & F2PY_OPTIONAL) && (obj==Py_None)) ) { /* intent(cache), optional, intent(hide) */ if (count_nonpos(rank,dims)) { int i; strcpy(mess, "failed to create intent(cache|hide)|optional array" "-- must have defined dimensions but got ("); for(i=0;i<rank;++i) sprintf(mess+strlen(mess),"%" NPY_INTP_FMT ",",dims[i]); strcat(mess, ")"); PyErr_SetString(PyExc_ValueError,mess); return NULL; } arr = (PyArrayObject *) PyArray_New(&PyArray_Type, rank, dims, type_num, NULL,NULL,0, !(intent&F2PY_INTENT_C), NULL); if (arr==NULL) return NULL; if (!(intent & F2PY_INTENT_CACHE)) PyArray_FILLWBYTE(arr, 0); return arr; } descr = PyArray_DescrFromType(type_num); elsize = descr->elsize; typechar = descr->type; Py_DECREF(descr); if (PyArray_Check(obj)) { arr = (PyArrayObject *)obj; if (intent & F2PY_INTENT_CACHE) { /* intent(cache) */ if (PyArray_ISONESEGMENT(arr) && PyArray_ITEMSIZE(arr)>=elsize) { if (check_and_fix_dimensions(arr,rank,dims)) { return NULL; /*XXX: set exception */ } if (intent & F2PY_INTENT_OUT) Py_INCREF(arr); return arr; } strcpy(mess, "failed to initialize intent(cache) array"); if (!PyArray_ISONESEGMENT(arr)) strcat(mess, " -- input must be in one segment"); if (PyArray_ITEMSIZE(arr)<elsize) sprintf(mess+strlen(mess), " -- expected at least elsize=%d but got %" NPY_INTP_FMT, elsize, (npy_intp)PyArray_ITEMSIZE(arr) ); PyErr_SetString(PyExc_ValueError,mess); return NULL; } /* here we have always intent(in) or intent(inout) or intent(inplace) */ if (check_and_fix_dimensions(arr,rank,dims)) { return NULL; /*XXX: set exception */ } /* printf("intent alignement=%d\n", F2PY_GET_ALIGNMENT(intent)); printf("alignement check=%d\n", F2PY_CHECK_ALIGNMENT(arr, intent)); int i; for (i=1;i<=16;i++) printf("i=%d isaligned=%d\n", i, ARRAY_ISALIGNED(arr, i)); */ if ((! (intent & F2PY_INTENT_COPY)) && PyArray_ITEMSIZE(arr)==elsize && ARRAY_ISCOMPATIBLE(arr,type_num) && F2PY_CHECK_ALIGNMENT(arr, intent) ) { if ((intent & F2PY_INTENT_C)?PyArray_ISCARRAY(arr):PyArray_ISFARRAY(arr)) { if ((intent & F2PY_INTENT_OUT)) { Py_INCREF(arr); } /* Returning input array */ return arr; } } if (intent & F2PY_INTENT_INOUT) { strcpy(mess, "failed to initialize intent(inout) array"); if ((intent & F2PY_INTENT_C) && !PyArray_ISCARRAY(arr)) strcat(mess, " -- input not contiguous"); if (!(intent & F2PY_INTENT_C) && !PyArray_ISFARRAY(arr)) strcat(mess, " -- input not fortran contiguous"); if (PyArray_ITEMSIZE(arr)!=elsize) sprintf(mess+strlen(mess), " -- expected elsize=%d but got %" NPY_INTP_FMT, elsize, (npy_intp)PyArray_ITEMSIZE(arr) ); if (!(ARRAY_ISCOMPATIBLE(arr,type_num))) sprintf(mess+strlen(mess)," -- input '%c' not compatible to '%c'", PyArray_DESCR(arr)->type,typechar); if (!(F2PY_CHECK_ALIGNMENT(arr, intent))) sprintf(mess+strlen(mess)," -- input not %d-aligned", F2PY_GET_ALIGNMENT(intent)); PyErr_SetString(PyExc_ValueError,mess); return NULL; } /* here we have always intent(in) or intent(inplace) */ { PyArrayObject *retarr = (PyArrayObject *) \ PyArray_New(&PyArray_Type, PyArray_NDIM(arr), PyArray_DIMS(arr), type_num, NULL,NULL,0, !(intent&F2PY_INTENT_C), NULL); if (retarr==NULL) return NULL; F2PY_REPORT_ON_ARRAY_COPY_FROMARR; if (PyArray_CopyInto(retarr, arr)) { Py_DECREF(retarr); return NULL; } if (intent & F2PY_INTENT_INPLACE) { if (swap_arrays(arr,retarr)) return NULL; /* XXX: set exception */ Py_XDECREF(retarr); if (intent & F2PY_INTENT_OUT) Py_INCREF(arr); } else { arr = retarr; } } return arr; } if ((intent & F2PY_INTENT_INOUT) || (intent & F2PY_INTENT_INPLACE) || (intent & F2PY_INTENT_CACHE)) { PyErr_SetString(PyExc_TypeError, "failed to initialize intent(inout|inplace|cache) " "array, input not an array"); return NULL; } { F2PY_REPORT_ON_ARRAY_COPY_FROMANY; arr = (PyArrayObject *) \ PyArray_FromAny(obj,PyArray_DescrFromType(type_num), 0,0, ((intent & F2PY_INTENT_C)?NPY_ARRAY_CARRAY:NPY_ARRAY_FARRAY) \ | NPY_ARRAY_FORCECAST, NULL); if (arr==NULL) return NULL; if (check_and_fix_dimensions(arr,rank,dims)) return NULL; /*XXX: set exception */ return arr; } }
/*@null@*/ static PyObject* PySip_foc2pix( PySip* self, PyObject* args, PyObject* kwds) { PyObject* foccrd_obj = NULL; int origin = 1; PyArrayObject* foccrd = NULL; PyArrayObject* pixcrd = NULL; int status = -1; const char* keywords[] = { "foccrd", "origin", NULL }; if (!PyArg_ParseTupleAndKeywords(args, kwds, "Oi:foc2pix", (char **)keywords, &foccrd_obj, &origin)) { return NULL; } if (self->x.ap == NULL || self->x.bp == NULL) { PyErr_SetString( PyExc_ValueError, "SIP object does not have coefficients for foc2pix transformation (AP and BP)"); return NULL; } foccrd = (PyArrayObject*)PyArray_ContiguousFromAny(foccrd_obj, PyArray_DOUBLE, 2, 2); if (foccrd == NULL) { goto exit; } if (PyArray_DIM(foccrd, 1) != 2) { PyErr_SetString(PyExc_ValueError, "Pixel array must be an Nx2 array"); goto exit; } pixcrd = (PyArrayObject*)PyArray_SimpleNew(2, PyArray_DIMS(foccrd), PyArray_DOUBLE); if (pixcrd == NULL) { status = 2; goto exit; } Py_BEGIN_ALLOW_THREADS preoffset_array(foccrd, origin); status = sip_foc2pix(&self->x, (unsigned int)PyArray_DIM(pixcrd, 1), (unsigned int)PyArray_DIM(pixcrd, 0), (double*)PyArray_DATA(foccrd), (double*)PyArray_DATA(pixcrd)); unoffset_array(foccrd, origin); unoffset_array(pixcrd, origin); Py_END_ALLOW_THREADS exit: Py_XDECREF(foccrd); if (status == 0) { return (PyObject*)pixcrd; } else { Py_XDECREF(pixcrd); if (status == -1) { /* Exception already set */ return NULL; } else { wcserr_to_python_exc(self->x.err); return NULL; } } }
int APPLY_SPECIFIC(ctc_cost_cpu)(PyArrayObject * in_activations, PyArrayObject * in_labels, PyArrayObject * in_input_lengths, PyArrayObject ** out_costs, PyArrayObject ** out_gradients) { ctc_context_t ctc_object; ctc_context_t * context = &ctc_object; ctc_context_init( context ); if ( !PyArray_IS_C_CONTIGUOUS( in_activations ) ) { PyErr_SetString( PyExc_RuntimeError, "ConnectionistTemporalClassification: activations array must be C-contiguous." ); return 1; } npy_float32 * activations = (npy_float32 *) PyArray_DATA( in_activations ); create_contiguous_input_lengths( in_input_lengths, &(context->input_lengths) ); if ( NULL == context->input_lengths ) { // Destroy previous CTC context before returning exception ctc_context_destroy( context ); PyErr_Format( PyExc_MemoryError, "ConnectionistTemporalClassification: Could not allocate memory for input lengths" ); return 1; } // flatten labels to conform with library memory layout create_flat_labels( in_labels, &(context->flat_labels), &(context->label_lengths) ); if ( ( NULL == context->label_lengths ) || ( NULL == context->flat_labels ) ) { // Destroy previous CTC context before returning exception ctc_context_destroy( context ); PyErr_Format( PyExc_MemoryError, "ConnectionistTemporalClassification: Could not allocate memory for labels and their lengths" ); return 1; } npy_int minibatch_size = PyArray_DIMS( in_activations )[1]; npy_int alphabet_size = PyArray_DIMS( in_activations )[2]; npy_float32 * costs = NULL; npy_intp cost_size = minibatch_size; if ( (*out_costs) == NULL || // Symbolic variable has no memory backing PyArray_NDIM( *out_costs ) != 1 || // or, matrix has the wrong size PyArray_DIMS( *out_costs )[0] != cost_size ) { Py_XDECREF( *out_costs ); // Allocate new matrix *out_costs = (PyArrayObject *) PyArray_ZEROS( 1, &cost_size, NPY_FLOAT32, 0 ); if ( NULL == (*out_costs) ) { // Destroy previous CTC context before returning exception ctc_context_destroy( context ); PyErr_Format( PyExc_MemoryError, "ConnectionistTemporalClassification: Could not allocate memory for CTC costs" ); return 1; } } costs = (npy_float32 *) PyArray_DATA( *out_costs ); npy_float32 * gradients = NULL; if ( NULL != out_gradients ) // If gradient computation is not disabled { if ( NULL == (*out_gradients) || // Symbolic variable has no real backing PyArray_NDIM( *out_gradients ) != 3 || PyArray_DIMS( *out_gradients )[0] != PyArray_DIMS( in_activations )[0] || PyArray_DIMS( *out_gradients )[1] != PyArray_DIMS( in_activations )[1] || PyArray_DIMS( *out_gradients )[2] != PyArray_DIMS( in_activations )[2] ) { // Existing matrix is the wrong size. Make a new one. // Decrement ref counter to existing array Py_XDECREF( *out_gradients ); // Allocate new array *out_gradients = (PyArrayObject *) PyArray_ZEROS(3, PyArray_DIMS( in_activations ), NPY_FLOAT32, 0); if ( NULL == (*out_gradients) ) { // Destroy previous CTC context before returning exception ctc_context_destroy( context ); PyErr_Format( PyExc_MemoryError, "ConnectionistTemporalClassification: Could not allocate memory for CTC gradients!" ); return 1; } } gradients = (npy_float32 *) PyArray_DATA( *out_gradients ); } size_t cpu_workspace_size; int ctc_error; ctc_error = ctc_check_result( get_workspace_size( context->label_lengths, context->input_lengths, alphabet_size, minibatch_size, context->options, &cpu_workspace_size ), "Failed to obtain CTC workspace size." ); if ( ctc_error ) // Exception is set by ctc_check_result, return error here { // Destroy previous CTC context before returning exception ctc_context_destroy( context ); return 1; } context->workspace = malloc( cpu_workspace_size ); if ( NULL == context->workspace ) { // Destroy previous CTC context before returning exception ctc_context_destroy( context ); PyErr_Format( PyExc_MemoryError, "ConnectionistTemporalClassification: Failed to allocate memory for CTC workspace." ); return 1; } ctc_error = ctc_check_result( compute_ctc_loss( activations, gradients, context->flat_labels, context->label_lengths, context->input_lengths, alphabet_size, minibatch_size, costs, context->workspace, context->options ), "Failed to compute CTC loss function." ); if ( ctc_error ) // Exception is set by ctc_check_result, return error here { ctc_context_destroy( context ); return 1; } ctc_context_destroy( context ); return 0; }
static int fortran_setattr(PyFortranObject *fp, char *name, PyObject *v) { int i,j,flag; PyArrayObject *arr = NULL; for (i=0,j=1;i<fp->len && (j=strcmp(name,fp->defs[i].name));i++); if (j==0) { if (fp->defs[i].rank==-1) { PyErr_SetString(PyExc_AttributeError,"over-writing fortran routine"); return -1; } if (fp->defs[i].func!=NULL) { /* is allocatable array */ npy_intp dims[F2PY_MAX_DIMS]; int k; save_def = &fp->defs[i]; if (v!=Py_None) { /* set new value (reallocate if needed -- see f2py generated code for more details ) */ for(k=0;k<fp->defs[i].rank;k++) dims[k]=-1; if ((arr = array_from_pyobj(fp->defs[i].type,dims,fp->defs[i].rank,F2PY_INTENT_IN,v))==NULL) return -1; (*(fp->defs[i].func))(&fp->defs[i].rank,PyArray_DIMS(arr),set_data,&flag); } else { /* deallocate */ for(k=0;k<fp->defs[i].rank;k++) dims[k]=0; (*(fp->defs[i].func))(&fp->defs[i].rank,dims,set_data,&flag); for(k=0;k<fp->defs[i].rank;k++) dims[k]=-1; } memcpy(fp->defs[i].dims.d,dims,fp->defs[i].rank*sizeof(npy_intp)); } else { /* not allocatable array */ if ((arr = array_from_pyobj(fp->defs[i].type,fp->defs[i].dims.d,fp->defs[i].rank,F2PY_INTENT_IN,v))==NULL) return -1; } if (fp->defs[i].data!=NULL) { /* copy Python object to Fortran array */ npy_intp s = PyArray_MultiplyList(fp->defs[i].dims.d,PyArray_NDIM(arr)); if (s==-1) s = PyArray_MultiplyList(PyArray_DIMS(arr),PyArray_NDIM(arr)); if (s<0 || (memcpy(fp->defs[i].data,PyArray_DATA(arr),s*PyArray_ITEMSIZE(arr)))==NULL) { if ((PyObject*)arr!=v) { Py_DECREF(arr); } return -1; } if ((PyObject*)arr!=v) { Py_DECREF(arr); } } else return (fp->defs[i].func==NULL?-1:0); return 0; /* succesful */ } if (fp->dict == NULL) { fp->dict = PyDict_New(); if (fp->dict == NULL) return -1; } if (v == NULL) { int rv = PyDict_DelItemString(fp->dict, name); if (rv < 0) PyErr_SetString(PyExc_AttributeError,"delete non-existing fortran attribute"); return rv; } else return PyDict_SetItemString(fp->dict, name, v); }
Py::Object _path_module::affine_transform(const Py::Tuple& args) { args.verify_length(2); Py::Object vertices_obj = args[0]; Py::Object transform_obj = args[1]; PyArrayObject* vertices = NULL; PyArrayObject* transform = NULL; PyArrayObject* result = NULL; try { vertices = (PyArrayObject*)PyArray_FromObject (vertices_obj.ptr(), PyArray_DOUBLE, 1, 2); if (!vertices || (PyArray_NDIM(vertices) == 2 && PyArray_DIM(vertices, 1) != 2) || (PyArray_NDIM(vertices) == 1 && PyArray_DIM(vertices, 0) != 2)) throw Py::ValueError("Invalid vertices array."); transform = (PyArrayObject*) PyArray_FromObject (transform_obj.ptr(), PyArray_DOUBLE, 2, 2); if (!transform || PyArray_DIM(transform, 0) != 3 || PyArray_DIM(transform, 1) != 3) throw Py::ValueError("Invalid transform."); double a, b, c, d, e, f; { size_t stride0 = PyArray_STRIDE(transform, 0); size_t stride1 = PyArray_STRIDE(transform, 1); char* row0 = PyArray_BYTES(transform); char* row1 = row0 + stride0; a = *(double*)(row0); row0 += stride1; c = *(double*)(row0); row0 += stride1; e = *(double*)(row0); b = *(double*)(row1); row1 += stride1; d = *(double*)(row1); row1 += stride1; f = *(double*)(row1); } result = (PyArrayObject*)PyArray_SimpleNew (PyArray_NDIM(vertices), PyArray_DIMS(vertices), PyArray_DOUBLE); if (PyArray_NDIM(vertices) == 2) { size_t n = PyArray_DIM(vertices, 0); char* vertex_in = PyArray_BYTES(vertices); double* vertex_out = (double*)PyArray_DATA(result); size_t stride0 = PyArray_STRIDE(vertices, 0); size_t stride1 = PyArray_STRIDE(vertices, 1); double x; double y; for (size_t i = 0; i < n; ++i) { x = *(double*)(vertex_in); y = *(double*)(vertex_in + stride1); *vertex_out++ = a*x + c*y + e; *vertex_out++ = b*x + d*y + f; vertex_in += stride0; } } else { char* vertex_in = PyArray_BYTES(vertices); double* vertex_out = (double*)PyArray_DATA(result); size_t stride0 = PyArray_STRIDE(vertices, 0); double x; double y; x = *(double*)(vertex_in); y = *(double*)(vertex_in + stride0); *vertex_out++ = a*x + c*y + e; *vertex_out++ = b*x + d*y + f; } } catch (...) { Py_XDECREF(vertices); Py_XDECREF(transform); Py_XDECREF(result); throw; } Py_XDECREF(vertices); Py_XDECREF(transform); return Py::Object((PyObject*)result, true); }
NPY_NO_EXPORT int PyArray_DTypeFromObjectHelper(PyObject *obj, int maxdims, PyArray_Descr **out_dtype, int string_type) { int i, size; PyArray_Descr *dtype = NULL; PyObject *ip; Py_buffer buffer_view; /* types for sequence handling */ PyObject ** objects; PyObject * seq; PyTypeObject * common_type; /* Check if it's an ndarray */ if (PyArray_Check(obj)) { dtype = PyArray_DESCR((PyArrayObject *)obj); Py_INCREF(dtype); goto promote_types; } /* See if it's a python None */ if (obj == Py_None) { dtype = PyArray_DescrFromType(NPY_OBJECT); if (dtype == NULL) { goto fail; } Py_INCREF(dtype); goto promote_types; } /* Check if it's a NumPy scalar */ else if (PyArray_IsScalar(obj, Generic)) { if (!string_type) { dtype = PyArray_DescrFromScalar(obj); if (dtype == NULL) { goto fail; } } else { int itemsize; PyObject *temp; if (string_type == NPY_STRING) { if ((temp = PyObject_Str(obj)) == NULL) { return -1; } #if defined(NPY_PY3K) #if PY_VERSION_HEX >= 0x03030000 itemsize = PyUnicode_GetLength(temp); #else itemsize = PyUnicode_GET_SIZE(temp); #endif #else itemsize = PyString_GET_SIZE(temp); #endif } else if (string_type == NPY_UNICODE) { #if defined(NPY_PY3K) if ((temp = PyObject_Str(obj)) == NULL) { #else if ((temp = PyObject_Unicode(obj)) == NULL) { #endif return -1; } itemsize = PyUnicode_GET_DATA_SIZE(temp); #ifndef Py_UNICODE_WIDE itemsize <<= 1; #endif } else { goto fail; } Py_DECREF(temp); if (*out_dtype != NULL && (*out_dtype)->type_num == string_type && (*out_dtype)->elsize >= itemsize) { return 0; } dtype = PyArray_DescrNewFromType(string_type); if (dtype == NULL) { goto fail; } dtype->elsize = itemsize; } goto promote_types; } /* Check if it's a Python scalar */ dtype = _array_find_python_scalar_type(obj); if (dtype != NULL) { if (string_type) { int itemsize; PyObject *temp; if (string_type == NPY_STRING) { if ((temp = PyObject_Str(obj)) == NULL) { return -1; } #if defined(NPY_PY3K) #if PY_VERSION_HEX >= 0x03030000 itemsize = PyUnicode_GetLength(temp); #else itemsize = PyUnicode_GET_SIZE(temp); #endif #else itemsize = PyString_GET_SIZE(temp); #endif } else if (string_type == NPY_UNICODE) { #if defined(NPY_PY3K) if ((temp = PyObject_Str(obj)) == NULL) { #else if ((temp = PyObject_Unicode(obj)) == NULL) { #endif return -1; } itemsize = PyUnicode_GET_DATA_SIZE(temp); #ifndef Py_UNICODE_WIDE itemsize <<= 1; #endif } else { goto fail; } Py_DECREF(temp); if (*out_dtype != NULL && (*out_dtype)->type_num == string_type && (*out_dtype)->elsize >= itemsize) { return 0; } dtype = PyArray_DescrNewFromType(string_type); if (dtype == NULL) { goto fail; } dtype->elsize = itemsize; } goto promote_types; } /* Check if it's an ASCII string */ if (PyBytes_Check(obj)) { int itemsize = PyString_GET_SIZE(obj); /* If it's already a big enough string, don't bother type promoting */ if (*out_dtype != NULL && (*out_dtype)->type_num == NPY_STRING && (*out_dtype)->elsize >= itemsize) { return 0; } dtype = PyArray_DescrNewFromType(NPY_STRING); if (dtype == NULL) { goto fail; } dtype->elsize = itemsize; goto promote_types; } /* Check if it's a Unicode string */ if (PyUnicode_Check(obj)) { int itemsize = PyUnicode_GET_DATA_SIZE(obj); #ifndef Py_UNICODE_WIDE itemsize <<= 1; #endif /* * If it's already a big enough unicode object, * don't bother type promoting */ if (*out_dtype != NULL && (*out_dtype)->type_num == NPY_UNICODE && (*out_dtype)->elsize >= itemsize) { return 0; } dtype = PyArray_DescrNewFromType(NPY_UNICODE); if (dtype == NULL) { goto fail; } dtype->elsize = itemsize; goto promote_types; } /* PEP 3118 buffer interface */ if (PyObject_CheckBuffer(obj) == 1) { memset(&buffer_view, 0, sizeof(Py_buffer)); if (PyObject_GetBuffer(obj, &buffer_view, PyBUF_FORMAT|PyBUF_STRIDES) == 0 || PyObject_GetBuffer(obj, &buffer_view, PyBUF_FORMAT) == 0) { PyErr_Clear(); dtype = _descriptor_from_pep3118_format(buffer_view.format); PyBuffer_Release(&buffer_view); if (dtype) { goto promote_types; } } else if (PyObject_GetBuffer(obj, &buffer_view, PyBUF_STRIDES) == 0 || PyObject_GetBuffer(obj, &buffer_view, PyBUF_SIMPLE) == 0) { PyErr_Clear(); dtype = PyArray_DescrNewFromType(NPY_VOID); dtype->elsize = buffer_view.itemsize; PyBuffer_Release(&buffer_view); goto promote_types; } else { PyErr_Clear(); } } /* The array interface */ ip = PyArray_LookupSpecial_OnInstance(obj, "__array_interface__"); if (ip != NULL) { if (PyDict_Check(ip)) { PyObject *typestr; #if defined(NPY_PY3K) PyObject *tmp = NULL; #endif typestr = PyDict_GetItemString(ip, "typestr"); #if defined(NPY_PY3K) /* Allow unicode type strings */ if (PyUnicode_Check(typestr)) { tmp = PyUnicode_AsASCIIString(typestr); typestr = tmp; } #endif if (typestr && PyBytes_Check(typestr)) { dtype =_array_typedescr_fromstr(PyBytes_AS_STRING(typestr)); #if defined(NPY_PY3K) if (tmp == typestr) { Py_DECREF(tmp); } #endif Py_DECREF(ip); if (dtype == NULL) { goto fail; } goto promote_types; } } Py_DECREF(ip); } /* The array struct interface */ ip = PyArray_LookupSpecial_OnInstance(obj, "__array_struct__"); if (ip != NULL) { PyArrayInterface *inter; char buf[40]; if (NpyCapsule_Check(ip)) { inter = (PyArrayInterface *)NpyCapsule_AsVoidPtr(ip); if (inter->two == 2) { PyOS_snprintf(buf, sizeof(buf), "|%c%d", inter->typekind, inter->itemsize); dtype = _array_typedescr_fromstr(buf); Py_DECREF(ip); if (dtype == NULL) { goto fail; } goto promote_types; } } Py_DECREF(ip); } /* The old buffer interface */ #if !defined(NPY_PY3K) if (PyBuffer_Check(obj)) { dtype = PyArray_DescrNewFromType(NPY_VOID); if (dtype == NULL) { goto fail; } dtype->elsize = Py_TYPE(obj)->tp_as_sequence->sq_length(obj); PyErr_Clear(); goto promote_types; } #endif /* The __array__ attribute */ ip = PyArray_LookupSpecial_OnInstance(obj, "__array__"); if (ip != NULL) { Py_DECREF(ip); ip = PyObject_CallMethod(obj, "__array__", NULL); if(ip && PyArray_Check(ip)) { dtype = PyArray_DESCR((PyArrayObject *)ip); Py_INCREF(dtype); Py_DECREF(ip); goto promote_types; } Py_XDECREF(ip); if (PyErr_Occurred()) { goto fail; } } /* * If we reached the maximum recursion depth without hitting one * of the above cases, and obj isn't a sequence-like object, the output * dtype should be either OBJECT or a user-defined type. * * Note that some libraries define sequence-like classes but want them to * be treated as objects, and they expect numpy to treat it as an object if * __len__ is not defined. */ if (maxdims == 0 || !PySequence_Check(obj) || PySequence_Size(obj) < 0) { // clear any PySequence_Size error, which corrupts further calls to it PyErr_Clear(); if (*out_dtype == NULL || (*out_dtype)->type_num != NPY_OBJECT) { Py_XDECREF(*out_dtype); *out_dtype = PyArray_DescrFromType(NPY_OBJECT); if (*out_dtype == NULL) { return -1; } } return 0; } /* Recursive case, first check the sequence contains only one type */ seq = PySequence_Fast(obj, "Could not convert object to sequence"); if (seq == NULL) { goto fail; } size = PySequence_Fast_GET_SIZE(seq); objects = PySequence_Fast_ITEMS(seq); common_type = size > 0 ? Py_TYPE(objects[0]) : NULL; for (i = 1; i < size; ++i) { if (Py_TYPE(objects[i]) != common_type) { common_type = NULL; break; } } /* all types are the same and scalar, one recursive call is enough */ if (common_type != NULL && !string_type && (common_type == &PyFloat_Type || /* TODO: we could add longs if we add a range check */ #if !defined(NPY_PY3K) common_type == &PyInt_Type || #endif common_type == &PyBool_Type || common_type == &PyComplex_Type)) { size = 1; } /* Recursive call for each sequence item */ for (i = 0; i < size; ++i) { int res = PyArray_DTypeFromObjectHelper(objects[i], maxdims - 1, out_dtype, string_type); if (res < 0) { Py_DECREF(seq); goto fail; } else if (res > 0) { Py_DECREF(seq); return res; } } Py_DECREF(seq); return 0; promote_types: /* Set 'out_dtype' if it's NULL */ if (*out_dtype == NULL) { if (!string_type && dtype->type_num == NPY_STRING) { Py_DECREF(dtype); return RETRY_WITH_STRING; } if (!string_type && dtype->type_num == NPY_UNICODE) { Py_DECREF(dtype); return RETRY_WITH_UNICODE; } *out_dtype = dtype; return 0; } /* Do type promotion with 'out_dtype' */ else { PyArray_Descr *res_dtype = PyArray_PromoteTypes(dtype, *out_dtype); Py_DECREF(dtype); if (res_dtype == NULL) { return -1; } if (!string_type && res_dtype->type_num == NPY_UNICODE && (*out_dtype)->type_num != NPY_UNICODE) { Py_DECREF(res_dtype); return RETRY_WITH_UNICODE; } if (!string_type && res_dtype->type_num == NPY_STRING && (*out_dtype)->type_num != NPY_STRING) { Py_DECREF(res_dtype); return RETRY_WITH_STRING; } Py_DECREF(*out_dtype); *out_dtype = res_dtype; return 0; } fail: Py_XDECREF(*out_dtype); *out_dtype = NULL; return -1; } #undef RETRY_WITH_STRING #undef RETRY_WITH_UNICODE /* new reference */ NPY_NO_EXPORT PyArray_Descr * _array_typedescr_fromstr(char *c_str) { PyArray_Descr *descr = NULL; PyObject *stringobj = PyString_FromString(c_str); if (stringobj == NULL) { return NULL; } if (PyArray_DescrConverter(stringobj, &descr) != NPY_SUCCEED) { Py_DECREF(stringobj); return NULL; } Py_DECREF(stringobj); return descr; } NPY_NO_EXPORT char * index2ptr(PyArrayObject *mp, npy_intp i) { npy_intp dim0; if (PyArray_NDIM(mp) == 0) { PyErr_SetString(PyExc_IndexError, "0-d arrays can't be indexed"); return NULL; } dim0 = PyArray_DIMS(mp)[0]; if (check_and_adjust_index(&i, dim0, 0, NULL) < 0) return NULL; if (i == 0) { return PyArray_DATA(mp); } return PyArray_BYTES(mp)+i*PyArray_STRIDES(mp)[0]; }
/*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; }
static PyObject * anglesToGVec(PyObject * self, PyObject * args) { PyArrayObject *angs, *bHat_l, *eHat_l, *rMat_c; PyArrayObject *gVec_c; double chi; npy_intp nvecs, rdims[2]; int nangs, nbhat, nehat, nrmat; int da1, db1, de1, dr1, dr2; double *angs_ptr, *bHat_l_ptr, *eHat_l_ptr, *rMat_c_ptr; double *gVec_c_ptr; /* Parse arguments */ if ( !PyArg_ParseTuple(args,"OOOdO", &angs, &bHat_l, &eHat_l, &chi, &rMat_c)) return(NULL); if ( angs == NULL ) return(NULL); /* Verify shape of input arrays */ nangs = PyArray_NDIM(angs); nbhat = PyArray_NDIM(bHat_l); nehat = PyArray_NDIM(eHat_l); nrmat = PyArray_NDIM(rMat_c); assert( nangs==2 && nbhat==1 && nehat==1 && nrmat==2 ); /* Verify dimensions of input arrays */ nvecs = PyArray_DIMS(angs)[0]; //rows da1 = PyArray_DIMS(angs)[1]; //cols db1 = PyArray_DIMS(bHat_l)[0]; de1 = PyArray_DIMS(eHat_l)[0]; dr1 = PyArray_DIMS(rMat_c)[0]; dr2 = PyArray_DIMS(rMat_c)[1]; assert( da1 == 3 ); assert( db1 == 3 && de1 == 3); assert( dr1 == 3 && dr2 == 3); /* Allocate C-style array for return data */ rdims[0] = nvecs; rdims[1] = 3; gVec_c = (PyArrayObject*)PyArray_EMPTY(2,rdims,NPY_DOUBLE,0); /* Grab pointers to the various data arrays */ angs_ptr = (double*)PyArray_DATA(angs); bHat_l_ptr = (double*)PyArray_DATA(bHat_l); eHat_l_ptr = (double*)PyArray_DATA(eHat_l); rMat_c_ptr = (double*)PyArray_DATA(rMat_c); gVec_c_ptr = (double*)PyArray_DATA(gVec_c); /* Call the actual function */ anglesToGvec_cfunc(nvecs, angs_ptr, bHat_l_ptr, eHat_l_ptr, chi, rMat_c_ptr, gVec_c_ptr); /* Build and return the nested data structure */ return((PyObject*)gVec_c); }
mitk::Image::Pointer mitk::PythonService::CopySimpleItkImageFromPython(const std::string &stdvarName) { double*ds = nullptr; // access python module PyObject *pyMod = PyImport_AddModule((char*)"__main__"); // global dictionarry PyObject *pyDict = PyModule_GetDict(pyMod); mitk::Image::Pointer mitkImage = mitk::Image::New(); mitk::Vector3D spacing; mitk::Point3D origin; QString command; QString varName = QString::fromStdString( stdvarName ); command.append( QString("%1_numpy_array = sitk.GetArrayFromImage(%1)\n").arg(varName) ); command.append( QString("%1_spacing = numpy.asarray(%1.GetSpacing())\n").arg(varName) ); command.append( QString("%1_origin = numpy.asarray(%1.GetOrigin())\n").arg(varName) ); command.append( QString("%1_dtype = %1_numpy_array.dtype.name\n").arg(varName) ); command.append( QString("%1_direction = numpy.asarray(%1.GetDirection())\n").arg(varName) ); command.append( QString("%1_nrComponents = numpy.asarray(%1.GetNumberOfComponentsPerPixel())\n").arg(varName)); command.append( QString("%1_dtype = %1_numpy_array.dtype.name\n").arg(varName) ); MITK_DEBUG("PythonService") << "Issuing python command " << command.toStdString(); this->Execute(command.toStdString(), IPythonService::MULTI_LINE_COMMAND ); PyObject* py_dtype = PyDict_GetItemString(pyDict,QString("%1_dtype").arg(varName).toStdString().c_str() ); std::string dtype = PyString_AsString(py_dtype); PyArrayObject* py_data = (PyArrayObject*) PyDict_GetItemString(pyDict,QString("%1_numpy_array").arg(varName).toStdString().c_str() ); PyArrayObject* py_spacing = (PyArrayObject*) PyDict_GetItemString(pyDict,QString("%1_spacing").arg(varName).toStdString().c_str() ); PyArrayObject* py_origin = (PyArrayObject*) PyDict_GetItemString(pyDict,QString("%1_origin").arg(varName).toStdString().c_str() ); PyArrayObject* py_direction = (PyArrayObject*) PyDict_GetItemString(pyDict,QString("%1_direction").arg(varName).toStdString().c_str() ); PyArrayObject* py_nrComponents = (PyArrayObject*) PyDict_GetItemString(pyDict,QString("%1_nrComponents").arg(varName).toStdString().c_str() ); unsigned int nr_Components = *(reinterpret_cast<unsigned int*>(PyArray_DATA(py_nrComponents))); unsigned int nr_dimensions = PyArray_NDIM(py_data); if (nr_Components > 1) // for VectorImages the last dimension in the numpy array are the vector components. { --nr_dimensions; } mitk::PixelType pixelType = DeterminePixelType(dtype, nr_Components, nr_dimensions); unsigned int* dimensions = new unsigned int[nr_dimensions]; // fill backwards , nd data saves dimensions in opposite direction for( unsigned i = 0; i < nr_dimensions; ++i ) { dimensions[i] = PyArray_DIMS(py_data)[nr_dimensions - 1 - i]; } mitkImage->Initialize(pixelType, nr_dimensions, dimensions); mitkImage->SetChannel(PyArray_DATA(py_data)); ds = reinterpret_cast<double*>(PyArray_DATA(py_spacing)); spacing[0] = ds[0]; spacing[1] = ds[1]; spacing[2] = ds[2]; mitkImage->GetGeometry()->SetSpacing(spacing); ds = reinterpret_cast<double*>(PyArray_DATA(py_origin)); origin[0] = ds[0]; origin[1] = ds[1]; origin[2] = ds[2]; mitkImage->GetGeometry()->SetOrigin(origin); itk::Matrix<double,3,3> py_transform; ds = reinterpret_cast<double*>(PyArray_DATA(py_direction)); py_transform[0][0] = ds[0]; py_transform[0][1] = ds[1]; py_transform[0][2] = ds[2]; py_transform[1][0] = ds[3]; py_transform[1][1] = ds[4]; py_transform[1][2] = ds[5]; py_transform[2][0] = ds[6]; py_transform[2][1] = ds[7]; py_transform[2][2] = ds[8]; mitk::AffineTransform3D::Pointer affineTransform = mitkImage->GetGeometry()->GetIndexToWorldTransform(); itk::Matrix<double,3,3> transform = py_transform * affineTransform->GetMatrix(); affineTransform->SetMatrix(transform); mitkImage->GetGeometry()->SetIndexToWorldTransform(affineTransform); // mitk::AffineTransform3D::New(); //mitkImage->GetGeometry()->SetIndexToWorldTransform(); // cleanup command.clear(); command.append( QString("del %1_numpy_array\n").arg(varName) ); command.append( QString("del %1_dtype\n").arg(varName) ); command.append( QString("del %1_spacing\n").arg(varName) ); command.append( QString("del %1_origin\n").arg(varName) ); command.append( QString("del %1_direction\n").arg(varName) ); command.append( QString("del %1_nrComponents\n").arg(varName) ); MITK_DEBUG("PythonService") << "Issuing python command " << command.toStdString(); this->Execute(command.toStdString(), IPythonService::MULTI_LINE_COMMAND ); delete[] dimensions; return mitkImage; }
static PyObject * array_slice(PyArrayObject *self, Py_ssize_t ilow, Py_ssize_t ihigh) { PyArrayObject *ret; PyArray_Descr *dtype; Py_ssize_t dim0; char *data; npy_intp shape[NPY_MAXDIMS]; if (PyArray_NDIM(self) == 0) { PyErr_SetString(PyExc_ValueError, "cannot slice a 0-d array"); return NULL; } dim0 = PyArray_DIM(self, 0); if (ilow < 0) { ilow = 0; } else if (ilow > dim0) { ilow = dim0; } if (ihigh < ilow) { ihigh = ilow; } else if (ihigh > dim0) { ihigh = dim0; } data = PyArray_DATA(self); if (ilow < ihigh) { data += ilow * PyArray_STRIDE(self, 0); } /* Same shape except dimension 0 */ shape[0] = ihigh - ilow; memcpy(shape+1, PyArray_DIMS(self) + 1, (PyArray_NDIM(self)-1)*sizeof(npy_intp)); dtype = PyArray_DESCR(self); Py_INCREF(dtype); ret = (PyArrayObject *)PyArray_NewFromDescr(Py_TYPE(self), dtype, PyArray_NDIM(self), shape, PyArray_STRIDES(self), data, PyArray_FLAGS(self) & ~(NPY_ARRAY_MASKNA | NPY_ARRAY_OWNMASKNA), (PyObject *)self); if (ret == NULL) { return NULL; } Py_INCREF(self); if (PyArray_SetBaseObject(ret, (PyObject *)self) < 0) { Py_DECREF(ret); return NULL; } PyArray_UpdateFlags(ret, NPY_ARRAY_UPDATE_ALL); /* Also take a view of the NA mask if it exists */ if (PyArray_HASMASKNA(self)) { PyArrayObject_fields *fret = (PyArrayObject_fields *)ret; fret->maskna_dtype = PyArray_MASKNA_DTYPE(self); Py_INCREF(fret->maskna_dtype); data = PyArray_MASKNA_DATA(self); if (ilow < ihigh) { data += ilow * PyArray_MASKNA_STRIDES(self)[0]; } fret->maskna_data = data; memcpy(fret->maskna_strides, PyArray_MASKNA_STRIDES(self), PyArray_NDIM(self) * sizeof(npy_intp)); /* This view doesn't own the mask */ fret->flags |= NPY_ARRAY_MASKNA; fret->flags &= ~NPY_ARRAY_OWNMASKNA; } return (PyObject *)ret; }
//query the ball tree. Arguments are the array of search points // and the number of nearest neighbors, k (optional) static PyObject * BallTree_query(BallTreeObject *self, PyObject *args, PyObject *kwds){ //we use goto statements : all variables should be declared up front int return_distance = 1; long int k = 1; PyObject *arg = NULL; PyObject *arr = NULL; PyObject *nbrs = NULL; PyObject *dist = NULL; PyArrayIterObject *arr_iter = NULL; PyArrayIterObject *nbrs_iter = NULL; PyArrayIterObject *dist_iter = NULL; long int* nbrs_data; double* dist_data; static char *kwlist[] = {"x", "k", "return_distance", NULL}; int nd, pt_size, pt_inc; npy_intp* dim; //parse arguments. If k is not provided, the default is 1 if(!PyArg_ParseTupleAndKeywords(args,kwds,"O|li",kwlist, &arg,&k,&return_distance)){ goto fail; } //check value of k if(k < 1){ PyErr_SetString(PyExc_ValueError, "k must be positive"); goto fail; } if(k > self->size){ PyErr_SetString(PyExc_ValueError, "k must not be greater than number of points"); goto fail; } //get the array object from the first argument arr = PyArray_FROM_OTF(arg,NPY_DOUBLE,NPY_ALIGNED); //check that the array was properly constructed if(arr==NULL){ PyErr_SetString(PyExc_ValueError, "pt must be convertable to array"); goto fail; } nd = PyArray_NDIM(arr); if(nd == 0){ PyErr_SetString(PyExc_ValueError, "pt cannot be zero-sized array"); goto fail; } pt_size = PyArray_DIM(arr,nd-1); if( pt_size != self->tree->PointSize() ){ PyErr_SetString(PyExc_ValueError, "points are incorrect dimension"); goto fail; } //create a neighbors array and distance array dim = new npy_intp[nd]; for(int i=0; i<nd-1;i++) dim[i] = PyArray_DIM(arr,i); dim[nd-1] = k; nbrs = (PyObject*)PyArray_SimpleNew(nd,dim,PyArray_LONG); if(return_distance) dist = (PyObject*)PyArray_SimpleNew(nd,dim,PyArray_DOUBLE); delete[] dim; if(nbrs==NULL) goto fail; //create iterators to cycle through points nd-=1; arr_iter = (PyArrayIterObject*)PyArray_IterAllButAxis(arr,&nd); nbrs_iter = (PyArrayIterObject*)PyArray_IterAllButAxis(nbrs,&nd); if(return_distance) dist_iter = (PyArrayIterObject*)PyArray_IterAllButAxis(dist,&nd); nd+=1; if( arr_iter==NULL || nbrs_iter==NULL || (arr_iter->size != nbrs_iter->size) || (return_distance && (dist_iter==NULL || (arr_iter->size != dist_iter->size))) ){ PyErr_SetString(PyExc_ValueError, "failure constructing iterators"); goto fail; } pt_inc = PyArray_STRIDES(arr)[nd-1] / PyArray_DESCR(arr)->elsize; if( (PyArray_STRIDES(nbrs)[nd-1] != PyArray_DESCR(nbrs)->elsize ) || (return_distance && (PyArray_STRIDES(dist)[nd-1] != PyArray_DESCR(dist)->elsize )) ){ PyErr_SetString(PyExc_ValueError, "nbrs & dist not allocated as a C-array"); goto fail; } //iterate through points and determine neighbors //warning: if nbrs is not a C-array, or if we're not iterating // over the last dimension, this may cause a seg fault. if(return_distance){ while(arr_iter->index < arr_iter->size){ BallTree_Point pt(arr, (double*)PyArray_ITER_DATA(arr_iter), pt_inc,pt_size); nbrs_data = (long int*)(PyArray_ITER_DATA(nbrs_iter)); dist_data = (double*)(PyArray_ITER_DATA(dist_iter)); self->tree->query(pt,k,nbrs_data,dist_data); PyArray_ITER_NEXT(arr_iter); PyArray_ITER_NEXT(nbrs_iter); PyArray_ITER_NEXT(dist_iter); } }else{ while(arr_iter->index < arr_iter->size){ BallTree_Point pt(arr, (double*)PyArray_ITER_DATA(arr_iter), pt_inc,pt_size); nbrs_data = (long int*)(PyArray_ITER_DATA(nbrs_iter)); self->tree->query(pt,k,nbrs_data); PyArray_ITER_NEXT(arr_iter); PyArray_ITER_NEXT(nbrs_iter); } } //if only one neighbor is requested, then resize the neighbors array if(k==1){ PyArray_Dims dims; dims.ptr = PyArray_DIMS(arr); dims.len = PyArray_NDIM(arr)-1; //PyArray_Resize returns None - this needs to be picked // up and dereferenced. PyObject *NoneObj = PyArray_Resize( (PyArrayObject*)nbrs, &dims, 0, NPY_ANYORDER ); if (NoneObj == NULL){ goto fail; } Py_DECREF(NoneObj); if(return_distance){ NoneObj = PyArray_Resize( (PyArrayObject*)dist, &dims, 0, NPY_ANYORDER ); if (NoneObj == NULL){ goto fail; } Py_DECREF(NoneObj); } } if(return_distance){ Py_DECREF(arr_iter); Py_DECREF(nbrs_iter); Py_DECREF(dist_iter); Py_DECREF(arr); arr = Py_BuildValue("(OO)",dist,nbrs); Py_DECREF(nbrs); Py_DECREF(dist); return arr; }else{ Py_DECREF(arr_iter); Py_DECREF(nbrs_iter); Py_DECREF(arr); return nbrs; } fail: Py_XDECREF(arr); Py_XDECREF(nbrs); Py_XDECREF(dist); Py_XDECREF(arr_iter); Py_XDECREF(nbrs_iter); Py_XDECREF(dist_iter); return NULL; }
/*@null@*/ static PyObject* Wcs_det2im( Wcs* self, PyObject* args, PyObject* kwds) { PyObject* detcrd_obj = NULL; int origin = 1; PyArrayObject* detcrd = NULL; PyArrayObject* imcrd = NULL; int status = -1; const char* keywords[] = { "detcrd", "origin", NULL }; if (!PyArg_ParseTupleAndKeywords(args, kwds, "Oi:det2im", (char **)keywords, &detcrd_obj, &origin)) { return NULL; } if (self->x.det2im[0] == NULL && self->x.det2im[1] == NULL) { Py_INCREF(detcrd_obj); return detcrd_obj; } detcrd = (PyArrayObject*)PyArray_ContiguousFromAny(detcrd_obj, PyArray_DOUBLE, 2, 2); if (detcrd == NULL) { return NULL; } if (PyArray_DIM(detcrd, 1) != NAXES) { PyErr_SetString(PyExc_ValueError, "Pixel array must be an Nx2 array"); goto exit; } imcrd = (PyArrayObject*)PyArray_SimpleNew(2, PyArray_DIMS(detcrd), PyArray_DOUBLE); if (imcrd == NULL) { status = 2; goto exit; } Py_BEGIN_ALLOW_THREADS preoffset_array(detcrd, origin); status = p4_pix2foc(2, (void *)self->x.det2im, (unsigned int)PyArray_DIM(detcrd, 0), (double*)PyArray_DATA(detcrd), (double*)PyArray_DATA(imcrd)); unoffset_array(detcrd, origin); unoffset_array(imcrd, origin); Py_END_ALLOW_THREADS exit: Py_XDECREF(detcrd); if (status == 0) { return (PyObject*)imcrd; } else { Py_XDECREF(imcrd); if (status == -1) { /* Exception already set */ return NULL; } else { PyErr_SetString(PyExc_MemoryError, "NULL pointer passed"); return NULL; } } }
//query the ball tree. Arguments are the array of search points // and the radius around each point to search static PyObject * BallTree_queryball(BallTreeObject *self, PyObject *args, PyObject *kwds){ //we use goto statements : all variables should be declared up front int count_only = 0; double r; PyObject *arg = NULL; PyObject *arr = NULL; PyObject *nbrs = NULL; PyArrayIterObject* arr_iter = NULL; PyArrayIterObject* nbrs_iter = NULL; int nd, pt_size, pt_inc; static char *kwlist[] = {"x", "r", "count_only", NULL}; //parse arguments. If kmax is not provided, the default is 20 if(!PyArg_ParseTupleAndKeywords(args,kwds,"Od|i", kwlist,&arg,&r,&count_only)){ goto fail; } //check value of r if(r < 0){ PyErr_SetString(PyExc_ValueError, "r must not be negative"); goto fail; } //get the array object from the first argument arr = PyArray_FROM_OTF(arg,NPY_DOUBLE,NPY_ALIGNED); //check that the array was properly constructed if(arr==NULL){ PyErr_SetString(PyExc_ValueError, "pt must be convertable to array"); goto fail; } nd = PyArray_NDIM(arr); if(nd == 0){ PyErr_SetString(PyExc_ValueError, "pt cannot be zero-sized array"); goto fail; } pt_size = PyArray_DIM(arr,nd-1); if( pt_size != self->tree->PointSize() ){ PyErr_SetString(PyExc_ValueError, "points are incorrect dimension"); goto fail; } // Case 1: return arrays of all neighbors for each point // if(!count_only){ //create a neighbors array. This is an array of python objects. // each of which will be a numpy array of neighbors nbrs = (PyObject*)PyArray_SimpleNew(nd-1,PyArray_DIMS(arr), PyArray_OBJECT); if(nbrs==NULL){ goto fail; } //create iterators to cycle through points --nd; arr_iter = (PyArrayIterObject*)PyArray_IterAllButAxis(arr,&nd); nbrs_iter = (PyArrayIterObject*)PyArray_IterNew(nbrs); ++nd; if( arr_iter==NULL || nbrs_iter==NULL || (arr_iter->size != nbrs_iter->size)){ PyErr_SetString(PyExc_ValueError, "unable to construct iterator"); goto fail; } pt_inc = PyArray_STRIDES(arr)[nd-1] / PyArray_DESCR(arr)->elsize; if(PyArray_NDIM(nbrs)==0){ BallTree_Point pt(arr, (double*)PyArray_ITER_DATA(arr_iter), pt_inc,pt_size); std::vector<long int> nbrs_vec; self->tree->query_ball(pt,r,nbrs_vec); npy_intp N_nbrs = nbrs_vec.size(); PyObject* nbrs_obj = PyArray_SimpleNew(1, &N_nbrs, PyArray_LONG); long int* data = (long int*)PyArray_DATA(nbrs_obj); for(int i=0; i<N_nbrs; i++) data[i] = nbrs_vec[i]; PyObject* tmp = nbrs; nbrs = nbrs_obj; Py_DECREF(tmp); }else{ while(arr_iter->index < arr_iter->size){ BallTree_Point pt(arr, (double*)PyArray_ITER_DATA(arr_iter), pt_inc,pt_size); std::vector<long int> nbrs_vec; self->tree->query_ball(pt,r,nbrs_vec); npy_intp N_nbrs = nbrs_vec.size(); PyObject* nbrs_obj = PyArray_SimpleNew(1, &N_nbrs, PyArray_LONG); long int* data = (long int*)PyArray_DATA(nbrs_obj); for(int i=0; i<N_nbrs; i++) data[i] = nbrs_vec[i]; PyObject** nbrs_data = (PyObject**)PyArray_ITER_DATA(nbrs_iter); PyObject* tmp = nbrs_data[0]; nbrs_data[0] = nbrs_obj; Py_XDECREF(tmp); PyArray_ITER_NEXT(arr_iter); PyArray_ITER_NEXT(nbrs_iter); } } } // Case 2 : return number of neighbors for each point else{ //create an array to keep track of the count nbrs = (PyObject*)PyArray_SimpleNew(nd-1,PyArray_DIMS(arr), PyArray_LONG); if(nbrs==NULL){ goto fail; } //create iterators to cycle through points --nd; arr_iter = (PyArrayIterObject*)PyArray_IterAllButAxis(arr,&nd); nbrs_iter = (PyArrayIterObject*)PyArray_IterNew(nbrs); ++nd; if( arr_iter==NULL || nbrs_iter==NULL || (arr_iter->size != nbrs_iter->size)){ PyErr_SetString(PyExc_ValueError, "unable to construct iterator"); goto fail; } //go through points and call BallTree::query_ball to count neighbors pt_inc = PyArray_STRIDES(arr)[nd-1] / PyArray_DESCR(arr)->elsize; while(arr_iter->index < arr_iter->size){ BallTree_Point pt(arr, (double*)PyArray_ITER_DATA(arr_iter), pt_inc,pt_size); long int* nbrs_count = (long int*)PyArray_ITER_DATA(nbrs_iter); *nbrs_count = self->tree->query_ball(pt,r); PyArray_ITER_NEXT(arr_iter); PyArray_ITER_NEXT(nbrs_iter); } } Py_DECREF(nbrs_iter); Py_DECREF(arr_iter); Py_DECREF(arr); return nbrs; fail: Py_XDECREF(nbrs_iter); Py_XDECREF(arr_iter); Py_XDECREF(arr); Py_XDECREF(nbrs); return NULL; }
PyObject * fftpack_rfftf(PyObject *NPY_UNUSED(self), PyObject *args) { PyObject *op1, *op2; PyArrayObject *data, *ret; PyArray_Descr *descr; double *wsave, *dptr, *rptr; npy_intp nsave; int npts, nrepeats, i, rstep; if(!PyArg_ParseTuple(args, "OO", &op1, &op2)) { return NULL; } data = (PyArrayObject *)PyArray_ContiguousFromObject(op1, NPY_DOUBLE, 1, 0); if (data == NULL) { return NULL; } /* FIXME, direct access changing contents of data->dimensions */ npts = PyArray_DIM(data, PyArray_NDIM(data) - 1); PyArray_DIMS(data)[PyArray_NDIM(data) - 1] = npts/2 + 1; ret = (PyArrayObject *)PyArray_Zeros(PyArray_NDIM(data), PyArray_DIMS(data), PyArray_DescrFromType(NPY_CDOUBLE), 0); PyArray_DIMS(data)[PyArray_NDIM(data) - 1] = npts; rstep = PyArray_DIM(ret, PyArray_NDIM(ret) - 1)*2; descr = PyArray_DescrFromType(NPY_DOUBLE); if (PyArray_AsCArray(&op2, (void *)&wsave, &nsave, 1, descr) == -1) { goto fail; } if (data == NULL || ret == NULL) { goto fail; } if (nsave != npts*2+15) { PyErr_SetString(ErrorObject, "invalid work array for fft size"); goto fail; } nrepeats = PyArray_SIZE(data)/npts; rptr = (double *)PyArray_DATA(ret); dptr = (double *)PyArray_DATA(data); NPY_SIGINT_ON; for (i = 0; i < nrepeats; i++) { memcpy((char *)(rptr+1), dptr, npts*sizeof(double)); rfftf(npts, rptr+1, wsave); rptr[0] = rptr[1]; rptr[1] = 0.0; rptr += rstep; dptr += npts; } NPY_SIGINT_OFF; PyArray_Free(op2, (char *)wsave); Py_DECREF(data); return (PyObject *)ret; fail: PyArray_Free(op2, (char *)wsave); Py_XDECREF(data); Py_XDECREF(ret); return NULL; }
//Wrapper for Brute-Force neighbor search static PyObject* BallTree_knn_brute(PyObject *self, PyObject *args, PyObject *kwds){ long int k = 1; std::vector<BallTree_Point*> Points; PyObject *arg1 = NULL; PyObject *arg2 = NULL; PyObject *arr1 = NULL; PyObject *arr2 = NULL; PyObject *nbrs = NULL; long int* nbrs_data; PyArrayIterObject *arr2_iter = NULL; PyArrayIterObject *nbrs_iter = NULL; static char *kwlist[] = {"x", "pt", "k", NULL}; npy_intp* dim; int nd, pt_size, pt_inc; long int N; long int D; //parse arguments. If k is not provided, the default is 1 if(!PyArg_ParseTupleAndKeywords(args,kwds,"OO|l",kwlist, &arg1,&arg2,&k)) goto fail; //First array should be a 2D array of doubles arr1 = PyArray_FROM_OTF(arg1,NPY_DOUBLE,0); if(arr1==NULL) goto fail; if( PyArray_NDIM(arr1) != 2){ PyErr_SetString(PyExc_ValueError, "x must be two dimensions"); goto fail; } //Second array should be a 1D array of doubles arr2 = PyArray_FROM_OTF(arg2,NPY_DOUBLE,0); if(arr2==NULL) goto fail; nd = PyArray_NDIM(arr2); if(nd == 0){ PyErr_SetString(PyExc_ValueError, "pt cannot be zero-sized array"); goto fail; } pt_size = PyArray_DIM(arr2,nd-1); //Check that dimensions match N = PyArray_DIMS(arr1)[0]; D = PyArray_DIMS(arr1)[1]; if( pt_size != D ){ PyErr_SetString(PyExc_ValueError, "pt must be same dimension as x"); goto fail; } //check the value of k if(k<1){ PyErr_SetString(PyExc_ValueError, "k must be a positive integer"); goto fail; } if(k>N){ PyErr_SetString(PyExc_ValueError, "k must be less than the number of points"); goto fail; } //create a neighbors array and distance array dim = new npy_intp[nd]; for(int i=0; i<nd-1;i++) dim[i] = PyArray_DIM(arr2,i); dim[nd-1] = k; nbrs = (PyObject*)PyArray_SimpleNew(nd,dim,PyArray_LONG); delete[] dim; if(nbrs==NULL) goto fail; //create iterators to cycle through points nd-=1; arr2_iter = (PyArrayIterObject*)PyArray_IterAllButAxis(arr2,&nd); nbrs_iter = (PyArrayIterObject*)PyArray_IterAllButAxis(nbrs,&nd); nd+=1; if( arr2_iter==NULL || nbrs_iter==NULL || (arr2_iter->size != nbrs_iter->size) ){ PyErr_SetString(PyExc_ValueError, "failure constructing iterators"); goto fail; } pt_inc = PyArray_STRIDES(arr2)[nd-1] / PyArray_DESCR(arr2)->elsize; if(PyArray_STRIDES(nbrs)[nd-1] != PyArray_DESCR(nbrs)->elsize ){ PyErr_SetString(PyExc_ValueError, "nbrs not allocated as a C-array"); goto fail; } //create the list of points pt_inc = PyArray_STRIDES(arr1)[1]/PyArray_DESCR(arr1)->elsize; Points.resize(N); for(int i=0;i<N;i++) Points[i] = new BallTree_Point(arr1, (double*)PyArray_GETPTR2(arr1,i,0), pt_inc, PyArray_DIM(arr1,1)); //iterate through points and determine neighbors //warning: if nbrs is not a C-array, or if we're not iterating // over the last dimension, this may cause a seg fault. while(arr2_iter->index < arr2_iter->size){ BallTree_Point Query_Point(arr2, (double*)PyArray_ITER_DATA(arr2_iter), pt_inc,pt_size); nbrs_data = (long int*)(PyArray_ITER_DATA(nbrs_iter)); BruteForceNeighbors(Points, Query_Point, k, nbrs_data ); PyArray_ITER_NEXT(arr2_iter); PyArray_ITER_NEXT(nbrs_iter); } for(int i=0;i<N;i++) delete Points[i]; //if only one neighbor is requested, then resize the neighbors array if(k==1){ PyArray_Dims dims; dims.ptr = PyArray_DIMS(arr2); dims.len = PyArray_NDIM(arr2)-1; //PyArray_Resize returns None - this needs to be picked // up and dereferenced. PyObject *NoneObj = PyArray_Resize( (PyArrayObject*)nbrs, &dims, 0, NPY_ANYORDER ); if (NoneObj == NULL){ goto fail; } Py_DECREF(NoneObj); } return nbrs; fail: Py_XDECREF(arr1); Py_XDECREF(arr2); Py_XDECREF(nbrs); Py_XDECREF(arr2_iter); Py_XDECREF(nbrs_iter); return NULL; }
// return a NEW (owned) reference // inline PyObject * numpy_extractor_impl ( PyObject * X, bool allow_copy, std::string type_name, int elementsType, int rank, size_t * lengths, std::ptrdiff_t * strides, size_t size_of_ValueType) { PyObject * numpy_obj; if (X==NULL) TRIQS_RUNTIME_ERROR<<"numpy interface : the python object is NULL !"; if (_import_array()!=0) TRIQS_RUNTIME_ERROR <<"Internal Error in importing numpy"; static const char * error_msg = " A deep copy of the object would be necessary while views are supposed to guarantee to present a *view* of the python data.\n"; if (!allow_copy) { if (!PyArray_Check(X)) throw copy_exception () << error_msg<<" Indeed the object was not even an array !\n"; if ( elementsType != PyArray_TYPE((PyArrayObject*)X)) throw copy_exception () << error_msg<<" The deep copy is caused by a type mismatch of the elements. Expected "<< type_name<< " and found XXX \n"; PyArrayObject *arr = (PyArrayObject *)X; #ifdef TRIQS_NUMPY_VERSION_LT_17 if ( arr->nd != rank) throw copy_exception () << error_msg<<" Rank mismatch . numpy array is of rank "<< arr->nd << "while you ask for rank "<< rank<<". \n"; #else if ( PyArray_NDIM(arr) != rank) throw copy_exception () << error_msg<<" Rank mismatch . numpy array is of rank "<< PyArray_NDIM(arr) << "while you ask for rank "<< rank<<". \n"; #endif numpy_obj = X; Py_INCREF(X); } else { // From X, we ask the numpy library to make a numpy, and of the correct type. // This handles automatically the cases where : // - we have list, or list of list/tuple // - the numpy type is not the one we want. // - adjust the dimension if needed // If X is an array : // - if Order is same, don't change it // - else impose it (may provoque a copy). // if X is not array : // - Order = FortranOrder or SameOrder - > Fortran order otherwise C //bool ForceCast = false;// Unless FORCECAST is present in flags, this call will generate an error if the data type cannot be safely obtained from the object. int flags = 0; //(ForceCast ? NPY_FORCECAST : 0) ;// do NOT force a copy | (make_copy ? NPY_ENSURECOPY : 0); if (!(PyArray_Check(X) )) //flags |= ( IndexMapType::traversal_order == indexmaps::mem_layout::c_order(rank) ? NPY_C_CONTIGUOUS : NPY_F_CONTIGUOUS); //impose mem order #ifdef TRIQS_NUMPY_VERSION_LT_17 flags |= (NPY_C_CONTIGUOUS); //impose mem order #else flags |= (NPY_ARRAY_C_CONTIGUOUS); //impose mem order #endif numpy_obj= PyArray_FromAny(X,PyArray_DescrFromType(elementsType), rank,rank, flags , NULL ); // do several checks if (!numpy_obj) {// The convertion of X to a numpy has failed ! if (PyErr_Occurred()) {PyErr_Print();PyErr_Clear();} TRIQS_RUNTIME_ERROR<<"numpy interface : the python object is not convertible to a numpy. "; } assert (PyArray_Check(numpy_obj)); assert((numpy_obj->ob_refcnt==1) || ((numpy_obj ==X))); PyArrayObject *arr_obj; arr_obj = (PyArrayObject *)numpy_obj; try { #ifdef TRIQS_NUMPY_VERSION_LT_17 if (arr_obj->nd!=rank) TRIQS_RUNTIME_ERROR<<"numpy interface : internal error : dimensions do not match"; if (arr_obj->descr->type_num != elementsType) TRIQS_RUNTIME_ERROR<<"numpy interface : internal error : incorrect type of element :" <<arr_obj->descr->type_num <<" vs "<<elementsType; #else if ( PyArray_NDIM(arr_obj) !=rank) TRIQS_RUNTIME_ERROR<<"numpy interface : internal error : dimensions do not match"; if ( PyArray_DESCR(arr_obj)->type_num != elementsType) TRIQS_RUNTIME_ERROR<<"numpy interface : internal error : incorrect type of element :" <<PyArray_DESCR(arr_obj)->type_num <<" vs "<<elementsType; #endif } catch(...) { Py_DECREF(numpy_obj); throw;} // make sure that in case of problem, the reference counting of python is still ok... } // extract strides and lengths PyArrayObject *arr_obj; arr_obj = (PyArrayObject *)numpy_obj; #ifdef TRIQS_NUMPY_VERSION_LT_17 const size_t dim =arr_obj->nd; // we know that dim == rank for (size_t i=0; i< dim ; ++i) { lengths[i] = size_t(arr_obj-> dimensions[i]); strides[i] = std::ptrdiff_t(arr_obj-> strides[i])/ size_of_ValueType; } #else const size_t dim = PyArray_NDIM(arr_obj); // we know that dim == rank for (size_t i=0; i< dim ; ++i) { lengths[i] = size_t( PyArray_DIMS(arr_obj)[i]); strides[i] = std::ptrdiff_t( PyArray_STRIDES(arr_obj)[i])/ size_of_ValueType; } #endif return numpy_obj; }
/* Takes a list of unit reciprocal lattice vectors in crystal frame to the specified detector-relative frame, subject to the conditions: 1) the reciprocal lattice vector must be able to satisfy a bragg condition 2) the associated diffracted beam must intersect the detector plane Required Arguments: gVec_c -- (n, 3) ndarray of n reciprocal lattice vectors in the CRYSTAL FRAME rMat_d -- (3, 3) ndarray, the COB taking DETECTOR FRAME components to LAB FRAME rMat_s -- (n, 3, 3) ndarray, the COB taking SAMPLE FRAME components to LAB FRAME rMat_c -- (3, 3) ndarray, the COB taking CRYSTAL FRAME components to SAMPLE FRAME tVec_d -- (3, 1) ndarray, the translation vector connecting LAB to DETECTOR tVec_s -- (3, 1) ndarray, the translation vector connecting LAB to SAMPLE tVec_c -- (3, 1) ndarray, the translation vector connecting SAMPLE to CRYSTAL Outputs: (m, 2) ndarray containing the intersections of m <= n diffracted beams associated with gVecs */ static PyObject * gvecToDetectorXYArray(PyObject * self, PyObject * args) { PyArrayObject *gVec_c, *rMat_d, *rMat_s, *rMat_c, *tVec_d, *tVec_s, *tVec_c, *beamVec; PyArrayObject *result; int dgc, drd, drs, drc, dtd, dts, dtc, dbv; npy_intp npts, dims[2]; double *gVec_c_Ptr, *rMat_d_Ptr, *rMat_s_Ptr, *rMat_c_Ptr, *tVec_d_Ptr, *tVec_s_Ptr, *tVec_c_Ptr, *beamVec_Ptr; double *result_Ptr; /* Parse arguments */ if ( !PyArg_ParseTuple(args,"OOOOOOOO", &gVec_c, &rMat_d, &rMat_s, &rMat_c, &tVec_d, &tVec_s, &tVec_c, &beamVec)) return(NULL); if ( gVec_c == NULL || rMat_d == NULL || rMat_s == NULL || rMat_c == NULL || tVec_d == NULL || tVec_s == NULL || tVec_c == NULL || beamVec == NULL ) return(NULL); /* Verify shape of input arrays */ dgc = PyArray_NDIM(gVec_c); drd = PyArray_NDIM(rMat_d); drs = PyArray_NDIM(rMat_s); drc = PyArray_NDIM(rMat_c); dtd = PyArray_NDIM(tVec_d); dts = PyArray_NDIM(tVec_s); dtc = PyArray_NDIM(tVec_c); dbv = PyArray_NDIM(beamVec); assert( dgc == 2 ); assert( drd == 2 && drs == 3 && drc == 2 ); assert( dtd == 1 && dts == 1 && dtc == 1 ); assert( dbv == 1 ); /* Verify dimensions of input arrays */ npts = PyArray_DIMS(gVec_c)[0]; if (npts != PyArray_DIM(rMat_s, 0)) { PyErr_Format(PyExc_ValueError, "gVec_c and rMat_s length mismatch %d vs %d", (int)PyArray_DIM(gVec_c, 0), (int)PyArray_DIM(rMat_s, 0)); return NULL; } assert( PyArray_DIMS(gVec_c)[1] == 3 ); assert( PyArray_DIMS(rMat_d)[0] == 3 && PyArray_DIMS(rMat_d)[1] == 3 ); assert( PyArray_DIMS(rMat_s)[1] == 3 && PyArray_DIMS(rMat_s)[2] == 3 ); assert( PyArray_DIMS(rMat_c)[0] == 3 && PyArray_DIMS(rMat_c)[1] == 3 ); assert( PyArray_DIMS(tVec_d)[0] == 3 ); assert( PyArray_DIMS(tVec_s)[0] == 3 ); assert( PyArray_DIMS(tVec_c)[0] == 3 ); assert( PyArray_DIMS(beamVec)[0] == 3 ); /* Allocate C-style array for return data */ // result_Ptr = malloc(2*npts*sizeof(double)); dims[0] = npts; dims[1] = 2; result = (PyArrayObject*)PyArray_EMPTY(2,dims,NPY_DOUBLE,0); /* Grab data pointers into various arrays */ gVec_c_Ptr = (double*)PyArray_DATA(gVec_c); rMat_d_Ptr = (double*)PyArray_DATA(rMat_d); rMat_s_Ptr = (double*)PyArray_DATA(rMat_s); rMat_c_Ptr = (double*)PyArray_DATA(rMat_c); tVec_d_Ptr = (double*)PyArray_DATA(tVec_d); tVec_s_Ptr = (double*)PyArray_DATA(tVec_s); tVec_c_Ptr = (double*)PyArray_DATA(tVec_c); beamVec_Ptr = (double*)PyArray_DATA(beamVec); result_Ptr = (double*)PyArray_DATA(result); /* Call the computational routine */ gvecToDetectorXYArray_cfunc(npts, gVec_c_Ptr, rMat_d_Ptr, rMat_s_Ptr, rMat_c_Ptr, tVec_d_Ptr, tVec_s_Ptr, tVec_c_Ptr, beamVec_Ptr, result_Ptr); /* Use the returned pointer to build the result object */ /* We do this since nadm may be less than npts and the result_Ptr may not be the same as the one allocated earlier. */ /* if ( nadm < npts ) { */ /* new_result_Ptr = (double*)realloc(result_Ptr,2*nadm*sizeof(double)); */ /* if ( new_result_Ptr != NULL ) result_Ptr = new_result_Ptr; */ /* else */ /* assert( false ); /\* This really should never happen *\/ */ /* } */ /* assert( false ); /\* This really should never happen *\/ */ /* } */ /* dims[0] = nadm; */ /* dims[1] = 2; */ /* result = (PyArrayObject*)PyArray_SimpleNewFromData(2,dims,NPY_DOUBLE,result_Ptr); */ /* Build and return the nested data structure */ return((PyObject*)result); }
/// @brief Construct a Mat from an NDArray object. static void construct(PyObject* object, boost::python::converter::rvalue_from_python_stage1_data* data) { namespace python = boost::python; // Object is a borrowed reference, so create a handle indicting it is // borrowed for proper reference counting. python::handle<> handle(python::borrowed(object)); // Obtain a handle to the memory block that the converter has allocated // for the C++ type. typedef python::converter::rvalue_from_python_storage<Mat> storage_type; void* storage = reinterpret_cast<storage_type*>(data)->storage.bytes; // Allocate the C++ type into the converter's memory block, and assign // its handle to the converter's convertible variable. The C++ // container is populated by passing the begin and end iterators of // the python object to the container's constructor. PyArrayObject* oarr = (PyArrayObject*) object; bool needcopy = false, needcast = false; int typenum = PyArray_TYPE(oarr), new_typenum = typenum; int type = typenum == NPY_UBYTE ? CV_8U : typenum == NPY_BYTE ? CV_8S : typenum == NPY_USHORT ? CV_16U : typenum == NPY_SHORT ? CV_16S : typenum == NPY_INT ? CV_32S : typenum == NPY_INT32 ? CV_32S : typenum == NPY_FLOAT ? CV_32F : typenum == NPY_DOUBLE ? CV_64F : -1; if (type < 0) { needcopy = needcast = true; new_typenum = NPY_INT; type = CV_32S; } #ifndef CV_MAX_DIM const int CV_MAX_DIM = 32; #endif int ndims = PyArray_NDIM(oarr); int size[CV_MAX_DIM + 1]; size_t step[CV_MAX_DIM + 1]; size_t elemsize = CV_ELEM_SIZE1(type); const npy_intp* _sizes = PyArray_DIMS(oarr); const npy_intp* _strides = PyArray_STRIDES(oarr); bool ismultichannel = ndims == 3 && _sizes[2] <= CV_CN_MAX; for (int i = ndims - 1; i >= 0 && !needcopy; i--) { // these checks handle cases of // a) multi-dimensional (ndims > 2) arrays, as well as simpler 1- and 2-dimensional cases // b) transposed arrays, where _strides[] elements go in non-descending order // c) flipped arrays, where some of _strides[] elements are negative if ((i == ndims - 1 && (size_t) _strides[i] != elemsize) || (i < ndims - 1 && _strides[i] < _strides[i + 1])) needcopy = true; } if (ismultichannel && _strides[1] != (npy_intp) elemsize * _sizes[2]) needcopy = true; if (needcopy) { if (needcast) { object = PyArray_Cast(oarr, new_typenum); oarr = (PyArrayObject*) object; } else { oarr = PyArray_GETCONTIGUOUS(oarr); object = (PyObject*) oarr; } _strides = PyArray_STRIDES(oarr); } for (int i = 0; i < ndims; i++) { size[i] = (int) _sizes[i]; step[i] = (size_t) _strides[i]; } // handle degenerate case if (ndims == 0) { size[ndims] = 1; step[ndims] = elemsize; ndims++; } if (ismultichannel) { ndims--; type |= CV_MAKETYPE(0, size[2]); } if (!needcopy) { Py_INCREF(object); } cv::Mat* m = new (storage) cv::Mat(ndims, size, type, PyArray_DATA(oarr), step); m->u = g_numpyAllocator.allocate(object, ndims, size, type, step); m->allocator = &g_numpyAllocator; m->addref(); data->convertible = storage; }
/* Takes a list cartesian (x, y) pairs in the detector coordinates and calculates the associated reciprocal lattice (G) vectors and (bragg angle, azimuth) pairs with respect to the specified beam and azimth (eta) reference directions Required Arguments: xy_det -- (n, 2) ndarray or list-like input of n detector (x, y) points rMat_d -- (3, 3) ndarray, the COB taking DETECTOR FRAME components to LAB FRAME rMat_s -- (3, 3) ndarray, the COB taking SAMPLE FRAME components to LAB FRAME tVec_d -- (3, 1) ndarray, the translation vector connecting LAB to DETECTOR tVec_s -- (3, 1) ndarray, the translation vector connecting LAB to SAMPLE tVec_c -- (3, 1) ndarray, the translation vector connecting SAMPLE to CRYSTAL Optional Keyword Arguments: beamVec -- (1, 3) mdarray containing the incident beam direction components in the LAB FRAME etaVec -- (1, 3) mdarray containing the reference azimuth direction components in the LAB FRAME Outputs: (n, 2) ndarray containing the (tTh, eta) pairs associated with each (x, y) (n, 3) ndarray containing the associated G vector directions in the LAB FRAME associated with gVecs */ static PyObject * detectorXYToGvec(PyObject * self, PyObject * args) { PyArrayObject *xy_det, *rMat_d, *rMat_s, *tVec_d, *tVec_s, *tVec_c, *beamVec, *etaVec; PyArrayObject *tTh, *eta, *gVec_l; PyObject *inner_tuple, *outer_tuple; int dxy, drd, drs, dtd, dts, dtc, dbv, dev; npy_intp npts, dims[2]; double *xy_Ptr, *rMat_d_Ptr, *rMat_s_Ptr, *tVec_d_Ptr, *tVec_s_Ptr, *tVec_c_Ptr, *beamVec_Ptr, *etaVec_Ptr; double *tTh_Ptr, *eta_Ptr, *gVec_l_Ptr; /* Parse arguments */ if ( !PyArg_ParseTuple(args,"OOOOOOOO", &xy_det, &rMat_d, &rMat_s, &tVec_d, &tVec_s, &tVec_c, &beamVec, &etaVec)) return(NULL); if ( xy_det == NULL || rMat_d == NULL || rMat_s == NULL || tVec_d == NULL || tVec_s == NULL || tVec_c == NULL || beamVec == NULL || etaVec == NULL ) return(NULL); /* Verify shape of input arrays */ dxy = PyArray_NDIM(xy_det); drd = PyArray_NDIM(rMat_d); drs = PyArray_NDIM(rMat_s); dtd = PyArray_NDIM(tVec_d); dts = PyArray_NDIM(tVec_s); dtc = PyArray_NDIM(tVec_c); dbv = PyArray_NDIM(beamVec); dev = PyArray_NDIM(etaVec); assert( dxy == 2 && drd == 2 && drs == 2 && dtd == 1 && dts == 1 && dtc == 1 && dbv == 1 && dev == 1); /* Verify dimensions of input arrays */ npts = PyArray_DIMS(xy_det)[0]; assert( PyArray_DIMS(xy_det)[1] == 2 ); assert( PyArray_DIMS(rMat_d)[0] == 3 && PyArray_DIMS(rMat_d)[1] == 3 ); assert( PyArray_DIMS(rMat_s)[0] == 3 && PyArray_DIMS(rMat_s)[1] == 3 ); assert( PyArray_DIMS(tVec_d)[0] == 3 ); assert( PyArray_DIMS(tVec_s)[0] == 3 ); assert( PyArray_DIMS(tVec_c)[0] == 3 ); assert( PyArray_DIMS(beamVec)[0] == 3 ); assert( PyArray_DIMS(etaVec)[0] == 3 ); /* Allocate arrays for return values */ dims[0] = npts; dims[1] = 3; gVec_l = (PyArrayObject*)PyArray_EMPTY(2,dims,NPY_DOUBLE,0); tTh = (PyArrayObject*)PyArray_EMPTY(1,&npts,NPY_DOUBLE,0); eta = (PyArrayObject*)PyArray_EMPTY(1,&npts,NPY_DOUBLE,0); /* Grab data pointers into various arrays */ xy_Ptr = (double*)PyArray_DATA(xy_det); gVec_l_Ptr = (double*)PyArray_DATA(gVec_l); tTh_Ptr = (double*)PyArray_DATA(tTh); eta_Ptr = (double*)PyArray_DATA(eta); rMat_d_Ptr = (double*)PyArray_DATA(rMat_d); rMat_s_Ptr = (double*)PyArray_DATA(rMat_s); tVec_d_Ptr = (double*)PyArray_DATA(tVec_d); tVec_s_Ptr = (double*)PyArray_DATA(tVec_s); tVec_c_Ptr = (double*)PyArray_DATA(tVec_c); beamVec_Ptr = (double*)PyArray_DATA(beamVec); etaVec_Ptr = (double*)PyArray_DATA(etaVec); /* Call the computational routine */ detectorXYToGvec_cfunc(npts, xy_Ptr, rMat_d_Ptr, rMat_s_Ptr, tVec_d_Ptr, tVec_s_Ptr, tVec_c_Ptr, beamVec_Ptr, etaVec_Ptr, tTh_Ptr, eta_Ptr, gVec_l_Ptr); /* Build and return the nested data structure */ /* Note that Py_BuildValue with 'O' increases reference count */ inner_tuple = Py_BuildValue("OO",tTh,eta); outer_tuple = Py_BuildValue("OO", inner_tuple, gVec_l); Py_DECREF(inner_tuple); Py_DECREF(tTh); Py_DECREF(eta); Py_DECREF(gVec_l); return outer_tuple; }
// ============================================================================= int Epetra_NumPyIntSerialDenseVector::getVectorSize(PyObject * pyObject) { if (!tmp_array) getArray(pyObject); return (int) PyArray_MultiplyList(PyArray_DIMS(tmp_array), PyArray_NDIM(tmp_array)); }
static PyObject * oscillAnglesOfHKLs(PyObject * self, PyObject * args) { PyArrayObject *hkls, *rMat_c, *bMat, *vInv_s, *beamVec, *etaVec; PyFloatObject *chi, *wavelength; PyArrayObject *oangs0, *oangs1; PyObject *return_tuple; int dhkls, drc, dbm, dvi, dbv, dev; npy_intp npts, dims[2]; double *hkls_Ptr, chi_d, *rMat_c_Ptr, *bMat_Ptr, wavelen_d, *vInv_s_Ptr, *beamVec_Ptr, *etaVec_Ptr; double *oangs0_Ptr, *oangs1_Ptr; /* Parse arguments */ if ( !PyArg_ParseTuple(args,"OOOOOOOO", &hkls, &chi, &rMat_c, &bMat, &wavelength, &vInv_s, &beamVec, &etaVec)) return(NULL); if ( hkls == NULL || chi == NULL || rMat_c == NULL || bMat == NULL || wavelength == NULL || vInv_s == NULL || beamVec == NULL || etaVec == NULL ) return(NULL); /* Verify shape of input arrays */ dhkls = PyArray_NDIM(hkls); drc = PyArray_NDIM(rMat_c); dbm = PyArray_NDIM(bMat); dvi = PyArray_NDIM(vInv_s); dbv = PyArray_NDIM(beamVec); dev = PyArray_NDIM(etaVec); assert( dhkls == 2 && drc == 2 && dbm == 2 && dvi == 1 && dbv == 1 && dev == 1); /* Verify dimensions of input arrays */ npts = PyArray_DIMS(hkls)[0]; assert( PyArray_DIMS(hkls)[1] == 3 ); assert( PyArray_DIMS(rMat_c)[0] == 3 && PyArray_DIMS(rMat_c)[1] == 3 ); assert( PyArray_DIMS(bMat)[0] == 3 && PyArray_DIMS(bMat)[1] == 3 ); assert( PyArray_DIMS(vInv_s)[0] == 6 ); assert( PyArray_DIMS(beamVec)[0] == 3 ); assert( PyArray_DIMS(etaVec)[0] == 3 ); /* Allocate arrays for return values */ dims[0] = npts; dims[1] = 3; oangs0 = (PyArrayObject*)PyArray_EMPTY(2,dims,NPY_DOUBLE,0); oangs1 = (PyArrayObject*)PyArray_EMPTY(2,dims,NPY_DOUBLE,0); /* Grab data pointers into various arrays */ hkls_Ptr = (double*)PyArray_DATA(hkls); chi_d = PyFloat_AsDouble((PyObject*)chi); wavelen_d = PyFloat_AsDouble((PyObject*)wavelength); rMat_c_Ptr = (double*)PyArray_DATA(rMat_c); bMat_Ptr = (double*)PyArray_DATA(bMat); vInv_s_Ptr = (double*)PyArray_DATA(vInv_s); beamVec_Ptr = (double*)PyArray_DATA(beamVec); etaVec_Ptr = (double*)PyArray_DATA(etaVec); oangs0_Ptr = (double*)PyArray_DATA(oangs0); oangs1_Ptr = (double*)PyArray_DATA(oangs1); /* Call the computational routine */ oscillAnglesOfHKLs_cfunc(npts, hkls_Ptr, chi_d, rMat_c_Ptr, bMat_Ptr, wavelen_d, vInv_s_Ptr, beamVec_Ptr, etaVec_Ptr, oangs0_Ptr, oangs1_Ptr); // printf("chi = %g, wavelength = %g\n",PyFloat_AsDouble((PyObject*)chi),PyFloat_AsDouble((PyObject*)wavelength)); /* np.ascontiguousarray(hkls),chi,rMat_c,bMat,wavelength, beamVec.flatten(),etaVec.flatten() */ /* Build and return the list data structure */ return_tuple = Py_BuildValue("OO",oangs0,oangs1); Py_DECREF(oangs1); Py_DECREF(oangs0); return return_tuple; }
static PyObject* py_fitexpsin(PyObject *obj, PyObject *args, PyObject *kwds) { PyArrayObject *data = NULL; PyArrayObject *fitt = NULL; PyArrayObject *rslt = NULL; PyArrayIterObject *data_it = NULL; PyArrayIterObject *fitt_it = NULL; PyArrayIterObject *rslt_it = NULL; Py_ssize_t newshape[NPY_MAXDIMS]; double *poly = NULL; double *coef = NULL; double *buff = NULL; int i, j, error, lastaxis, numdata; int startcoef = -1; int numcoef = MAXCOEF; int axis = NPY_MAXDIMS; double deltat = 1.0; static char *kwlist[] = {"data", "numcoef", "deltat", "axis", NULL}; if (!PyArg_ParseTupleAndKeywords(args, kwds, "O&|idO&", kwlist, PyConverter_AnyDoubleArray, &data, &numcoef, &deltat, PyArray_AxisConverter, &axis)) return NULL; if (axis < 0) { axis += PyArray_NDIM(data); } if ((axis < 0) || (axis >= NPY_MAXDIMS)) { PyErr_Format(PyExc_ValueError, "invalid axis"); goto _fail; } lastaxis = PyArray_NDIM(data) - 1; if ((numcoef < 1) || (numcoef > MAXCOEF)) { PyErr_Format(PyExc_ValueError, "numcoef out of bounds"); goto _fail; } if (startcoef < 0) { /* start regression away from zero coefficients */ startcoef = 4; } if (startcoef > numcoef - 2) { PyErr_Format(PyExc_ValueError, "startcoef out of bounds"); goto _fail; } numdata = (int)PyArray_DIM(data, axis); if (numcoef > numdata) numcoef = numdata; if ((numcoef - startcoef - 1) < 3) { PyErr_Format(PyExc_ValueError, "number of coefficients insufficient to fit data"); goto _fail; } /* fitted data */ fitt = (PyArrayObject *)PyArray_SimpleNew(PyArray_NDIM(data), PyArray_DIMS(data), NPY_DOUBLE); if (fitt == NULL) { PyErr_Format(PyExc_MemoryError, "unable to allocate fitt array"); goto _fail; } /* fitted parameters */ j = 0; for (i = 0; i < PyArray_NDIM(data); i++) { if (i != axis) newshape[j++] = PyArray_DIM(data, i); } newshape[j] = 5; rslt = (PyArrayObject *)PyArray_SimpleNew(PyArray_NDIM(data), newshape, NPY_DOUBLE); if (rslt == NULL) { PyErr_Format(PyExc_MemoryError, "unable to allocate rslt array"); goto _fail; } /* working buffer */ buff = (double *)PyMem_Malloc(3*numdata * sizeof(double)); if (buff == NULL) { PyErr_Format(PyExc_MemoryError, "unable to allocate buff array"); goto _fail; } /* buffer for differential coefficients */ coef = (double *)PyMem_Malloc((3+1)*(numcoef+1) * sizeof(double)); if (coef == NULL) { PyErr_Format(PyExc_MemoryError, "unable to allocate coef array"); goto _fail; } /* precalculate normalized Chebyshev polynomial */ poly = (double *)PyMem_Malloc(numdata * (numcoef+1) * sizeof(double)); if (poly == NULL) { PyErr_Format(PyExc_MemoryError, "unable to allocate poly"); goto _fail; } error = chebypoly(numdata, numcoef, poly, 1); if (error != 0) { PyErr_Format(PyExc_ValueError, "chebypoly() failed with error code %i", error); goto _fail; } /* iterate over all but specified axis */ data_it = (PyArrayIterObject *)PyArray_IterAllButAxis( (PyObject *)data, &axis); fitt_it = (PyArrayIterObject *)PyArray_IterAllButAxis( (PyObject *)fitt, &axis); rslt_it = (PyArrayIterObject *)PyArray_IterAllButAxis( (PyObject *)rslt, &lastaxis); while (data_it->index < data_it->size) { error = fitexpsin( (char *)data_it->dataptr, (int)PyArray_STRIDE(data, axis), numdata, poly, coef, numcoef, deltat, startcoef, buff, (double *)rslt_it->dataptr, (char *)fitt_it->dataptr, (int)PyArray_STRIDE(fitt, axis)); if (error != 0) { PyErr_Format(PyExc_ValueError, "fitexpsin() failed with error code %i", error); goto _fail; } PyArray_ITER_NEXT(data_it); PyArray_ITER_NEXT(fitt_it); PyArray_ITER_NEXT(rslt_it); } Py_XDECREF(data_it); Py_XDECREF(fitt_it); Py_XDECREF(rslt_it); Py_XDECREF(data); PyMem_Free(poly); PyMem_Free(coef); PyMem_Free(buff); return Py_BuildValue("(N, N)", rslt, fitt); _fail: Py_XDECREF(data_it); Py_XDECREF(fitt_it); Py_XDECREF(rslt_it); Py_XDECREF(data); Py_XDECREF(fitt); Py_XDECREF(rslt); PyMem_Free(poly); PyMem_Free(coef); PyMem_Free(buff); 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; }