static PyObject *premalloced_npy_double_array(double *data, npy_intp len) { PyObject *premalloced = premalloced_new(data); if (!premalloced) return NULL; npy_intp dims[1] = {len}; PyArrayObject *out = (PyArrayObject *) PyArray_SimpleNewFromData(1, dims, NPY_DOUBLE, data); if (!out) { Py_DECREF(premalloced); return NULL; } #ifdef PyArray_BASE /* FIXME: PyArray_BASE changed from a macro to a getter function in * Numpy 1.7. When we drop Numpy 1.6 support, remove this #ifdef block. */ PyArray_BASE(out) = premalloced; #else if (PyArray_SetBaseObject(out, premalloced)) { Py_DECREF(out); return NULL; } #endif return (PyObject *)out; }
PyObject * gdkpixbuf_get_pixels_array(PyObject *pixbuf_pyobject) { GdkPixbuf *pixbuf = GDK_PIXBUF(((PyGObject *)pixbuf_pyobject)->obj); PyArrayObject *array; npy_intp dims[3] = { 0, 0, 3 }; dims[0] = gdk_pixbuf_get_height(pixbuf); dims[1] = gdk_pixbuf_get_width(pixbuf); if (gdk_pixbuf_get_has_alpha(pixbuf)) dims[2] = 4; guchar *pixels = gdk_pixbuf_get_pixels(pixbuf); array = (PyArrayObject *)PyArray_SimpleNewFromData(3, dims, NPY_UBYTE, pixels); if (array == NULL) return NULL; PyArray_STRIDES(array)[0] = gdk_pixbuf_get_rowstride(pixbuf); // the array holds a ref to the pixbuf pixels through this wrapper Py_INCREF(pixbuf_pyobject); #ifdef NPY_1_7_API_VERSION PyArray_SetBaseObject(array, (PyObject *)pixbuf_pyobject); #else array->base = (PyObject *)pixbuf_pyobject; #endif return PyArray_Return(array); }
static PyObject *__getattro__(PyObject *self, PyObject *attr_name) { const char *name = PyString_AsString(attr_name); pylal_COMPLEX16FrequencySeries *obj = (pylal_COMPLEX16FrequencySeries *) self; if(!strcmp(name, "name")) return PyString_FromString(obj->series->name); if(!strcmp(name, "epoch")) return pylal_LIGOTimeGPS_new(obj->series->epoch); if(!strcmp(name, "f0")) return PyFloat_FromDouble(obj->series->f0); if(!strcmp(name, "deltaF")) return PyFloat_FromDouble(obj->series->deltaF); if(!strcmp(name, "sampleUnits")) return pylal_LALUnit_new(0, obj->series->sampleUnits); if(!strcmp(name, "data")) { npy_intp dims[] = {obj->series->data->length}; PyObject *array = PyArray_SimpleNewFromData(1, dims, NPY_CDOUBLE, obj->series->data->data); if(!array) return NULL; /* incref self to prevent data from disappearing while * array is still in use, and tell numpy to decref self * when the array is deallocated */ Py_INCREF(self); PyArray_SetBaseObject((PyArrayObject *) array, self); return array; } PyErr_SetString(PyExc_AttributeError, name); return NULL; }
/*@null@*/ static INLINE PyObject* _PyArrayProxy_New( /*@shared@*/ PyObject* self, int nd, const npy_intp* dims, int typenum, const void* data, const int flags) { PyArray_Descr* type_descr = NULL; PyObject* result = NULL; type_descr = (PyArray_Descr*)PyArray_DescrFromType(typenum); if (type_descr == NULL) { return NULL; } result = (PyObject*)PyArray_NewFromDescr( &PyArray_Type, type_descr, nd, (npy_intp*)dims, NULL, (void*)data, NPY_ARRAY_C_CONTIGUOUS | flags, NULL); if (result == NULL) { return NULL; } Py_INCREF(self); PyArray_SetBaseObject((PyArrayObject *)result, self); return result; }
bp::object PyBlobWrap::get_diff() { npy_intp dims[] = {num(), channels(), height(), width()}; PyObject *obj = PyArray_SimpleNewFromData(4, dims, NPY_FLOAT32, blob_->mutable_cpu_diff()); PyArray_SetBaseObject(reinterpret_cast<PyArrayObject *>(obj), self_); Py_INCREF(self_); bp::handle<> h(obj); return bp::object(h); }
PyObjectHandle LuaToPythonConverter::convertTensor(lua_State* L, thpp::Tensor<T>& tensor, int numpyType) { npy_intp zero = 0; int ndims; std::unique_ptr<npy_intp[]> dims; npy_intp* dimsPtr; std::unique_ptr<npy_intp[]> strides; // Numpy and Torch disagree on empty tensors. In Torch, an empty tensor // is a tensor with zero dimensions. In Numpy, a tensor with zero dimensions // is a scalar (with one element). So we'll convert an empty Torch tensor // to a 1d Numpy tensor of shape [0]. Also see pushTensor in PythonToLua.cpp. if (tensor.ndims() != 0) { ndims = tensor.ndims(); auto tsizes = tensor.sizes(); DCHECK_EQ(tsizes.size(), ndims); dims.reset(new npy_intp[ndims]); dimsPtr = dims.get(); std::copy(tsizes.begin(), tsizes.end(), dims.get()); if (!tensor.isContiguous()) { auto tstrides = tensor.strides(); DCHECK_EQ(tstrides.size(), ndims); strides.reset(new npy_intp[ndims]); // Numpy strides use bytes; Torch strides use element counts. for (int i = 0; i < ndims; ++i) { strides[i] = tstrides[i] * sizeof(T); } } } else { ndims = 1; dimsPtr = &zero; } PyObjectHandle obj(PyArray_New( &PyArray_Type, ndims, dimsPtr, numpyType, strides.get(), tensor.data(), 0, NPY_ARRAY_ALIGNED, nullptr)); checkPythonError(obj, L, "create numpy.ndarray of type {}", numpyType); // Create a PythonStorage object to hold the reference count. // PyArray_SetBaseObject steals the reference to the base object. int r = PyArray_SetBaseObject(reinterpret_cast<PyArrayObject*>(obj.get()), PythonStorage<T>::allocate( L, tensor.storage()).release()); checkPythonError(r != -1, L, "SetBaseObject on numpy.ndarray"); return obj; }
static PyObject *pixbuf_get_pixels_array(PyObject *self, PyObject *args) { /* 1) read in Python pixbuf, get the underlying gdk_pixbuf */ PyGObject *py_pixbuf; GdkPixbuf *gdk_pixbuf; PyArrayObject *array; npy_intp dims[3] = { 0, 0, 3 }; npy_intp strides[3]; if (!PyArg_ParseTuple(args, "O!:pixbuf_get_pixels_array", &PyGdkPixbuf_Type, &py_pixbuf)) return NULL; gdk_pixbuf = GDK_PIXBUF(py_pixbuf->obj); /* 2) same as pygtk/gtk/gdk.c _wrap_gdk_pixbuf_get_pixels_array() * with 'self' changed to py_pixbuf */ dims[0] = gdk_pixbuf_get_height(gdk_pixbuf); dims[1] = gdk_pixbuf_get_width(gdk_pixbuf); if (gdk_pixbuf_get_has_alpha(gdk_pixbuf)) dims[2] = 4; strides[0] = gdk_pixbuf_get_rowstride(gdk_pixbuf); strides[1] = dims[2]; strides[2] = 1; array = (PyArrayObject*) PyArray_New(&PyArray_Type, 3, dims, NPY_UBYTE, strides, (void*)gdk_pixbuf_get_pixels(gdk_pixbuf), 1, NPY_ARRAY_WRITEABLE, NULL); if (array == NULL) return NULL; /* the array holds a ref to the pixbuf pixels through this wrapper*/ Py_INCREF(py_pixbuf); #if NPY_API_VERSION >= 0x00000007 if (PyArray_SetBaseObject(array, (PyObject *)py_pixbuf) == -1) { Py_DECREF(py_pixbuf); Py_DECREF(array); return NULL; } #else PyArray_BASE(array) = (PyObject *) py_pixbuf; #endif return PyArray_Return(array); }
PyObject * array_view_to_python ( ArrayViewType const & A, bool copy=false) { //_import_array(); typedef typename ArrayViewType::value_type value_type; static const int rank = ArrayViewType::rank; const int elementsType (numpy_to_C_type<value_type>::arraytype); npy_intp dims[rank], strides[rank]; for(size_t i =0; i<rank; ++i) { dims[i] = A.indexmap().lengths()[i]; strides[i] = A.indexmap().strides()[i]*sizeof(value_type); } const value_type * data = A.data_start(); //int flags = NPY_ARRAY_BEHAVED & ~NPY_ARRAY_OWNDATA;;// for numpy2 #ifdef TRIQS_NUMPY_VERSION_LT_17 int flags = NPY_BEHAVED & ~NPY_OWNDATA; #else int flags = NPY_ARRAY_BEHAVED & ~NPY_ARRAY_OWNDATA; #endif PyObject* res = PyArray_NewFromDescr(&PyArray_Type, PyArray_DescrFromType(elementsType), (int) rank, dims, strides, (void*) data, flags, NULL); if (!res) { if (PyErr_Occurred()) {PyErr_Print();PyErr_Clear();} TRIQS_RUNTIME_ERROR<<" array_view_from_numpy : the python numpy object could not be build"; } if (!PyArray_Check(res)) TRIQS_RUNTIME_ERROR<<" array_view_from_numpy : internal error : the python object is not a numpy"; PyArrayObject * arr = (PyArrayObject *)(res); //PyArray_SetBaseObject(arr, A.storage().new_python_ref()); #ifdef TRIQS_NUMPY_VERSION_LT_17 arr->base = A.storage().new_python_ref(); assert( arr->flags == (arr->flags & ~NPY_OWNDATA)); #else int r = PyArray_SetBaseObject(arr,A.storage().new_python_ref()); if (r!=0) TRIQS_RUNTIME_ERROR << "Internal Error setting the guard in numpy !!!!"; assert( PyArray_FLAGS(arr) == (PyArray_FLAGS(arr) & ~NPY_ARRAY_OWNDATA)); #endif if (copy) { PyObject * na = PyObject_CallMethod(res,(char*)"copy",NULL); Py_DECREF(res); // POrt this for 1.7 //assert(((PyArrayObject *)na)->base ==NULL); res = na; } return res; }
/* * 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, int need_copy) { 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; } if (need_copy) { PyArrayObject *ret_copy; ret_copy = (PyArrayObject *)PyArray_NewLikeArray( (PyArrayObject *)ret, NPY_ANYORDER, NULL, 0); if (ret_copy == NULL) { Py_DECREF(ret); return NULL; } if (PyArray_CopyInto(ret_copy, (PyArrayObject *)ret) != 0) { Py_DECREF(ret); Py_DECREF(ret_copy); return NULL; } Py_INCREF(ret); if (PyArray_SetWritebackIfCopyBase(ret_copy, (PyArrayObject *)ret) < 0) { Py_DECREF(ret); Py_DECREF(ret_copy); return NULL; } return ret_copy; } else { return (PyArrayObject *)ret; } }
/* unravel_index implementation - see add_newdocs.py */ NPY_NO_EXPORT PyObject * arr_unravel_index(PyObject *self, PyObject *args, PyObject *kwds) { PyObject *indices0 = NULL, *ret_tuple = NULL; PyArrayObject *ret_arr = NULL; PyArrayObject *indices = NULL; PyArray_Descr *dtype = NULL; PyArray_Dims dimensions={0,0}; NPY_ORDER order = NPY_CORDER; npy_intp unravel_size; NpyIter *iter = NULL; int i, ret_ndim; npy_intp ret_dims[NPY_MAXDIMS], ret_strides[NPY_MAXDIMS]; char *kwlist[] = {"indices", "dims", "order", NULL}; if (!PyArg_ParseTupleAndKeywords(args, kwds, "OO&|O&:unravel_index", kwlist, &indices0, PyArray_IntpConverter, &dimensions, PyArray_OrderConverter, &order)) { goto fail; } if (dimensions.len == 0) { PyErr_SetString(PyExc_ValueError, "dims must have at least one value"); goto fail; } unravel_size = PyArray_MultiplyList(dimensions.ptr, dimensions.len); if (!PyArray_Check(indices0)) { indices = (PyArrayObject*)PyArray_FromAny(indices0, NULL, 0, 0, 0, NULL); if (indices == NULL) { goto fail; } } else { indices = (PyArrayObject *)indices0; Py_INCREF(indices); } dtype = PyArray_DescrFromType(NPY_INTP); if (dtype == NULL) { goto fail; } iter = NpyIter_New(indices, NPY_ITER_READONLY| NPY_ITER_ALIGNED| NPY_ITER_BUFFERED| NPY_ITER_ZEROSIZE_OK| NPY_ITER_DONT_NEGATE_STRIDES| NPY_ITER_MULTI_INDEX, NPY_KEEPORDER, NPY_SAME_KIND_CASTING, dtype); if (iter == NULL) { goto fail; } /* * Create the return array with a layout compatible with the indices * and with a dimension added to the end for the multi-index */ ret_ndim = PyArray_NDIM(indices) + 1; if (NpyIter_GetShape(iter, ret_dims) != NPY_SUCCEED) { goto fail; } ret_dims[ret_ndim-1] = dimensions.len; if (NpyIter_CreateCompatibleStrides(iter, dimensions.len*sizeof(npy_intp), ret_strides) != NPY_SUCCEED) { goto fail; } ret_strides[ret_ndim-1] = sizeof(npy_intp); /* Remove the multi-index and inner loop */ if (NpyIter_RemoveMultiIndex(iter) != NPY_SUCCEED) { goto fail; } if (NpyIter_EnableExternalLoop(iter) != NPY_SUCCEED) { goto fail; } ret_arr = (PyArrayObject *)PyArray_NewFromDescr(&PyArray_Type, dtype, ret_ndim, ret_dims, ret_strides, NULL, 0, NULL); dtype = NULL; if (ret_arr == NULL) { goto fail; } if (order == NPY_CORDER) { if (NpyIter_GetIterSize(iter) != 0) { NpyIter_IterNextFunc *iternext; char **dataptr; npy_intp *strides; npy_intp *countptr, count; npy_intp *coordsptr = (npy_intp *)PyArray_DATA(ret_arr); iternext = NpyIter_GetIterNext(iter, NULL); if (iternext == NULL) { goto fail; } dataptr = NpyIter_GetDataPtrArray(iter); strides = NpyIter_GetInnerStrideArray(iter); countptr = NpyIter_GetInnerLoopSizePtr(iter); do { count = *countptr; if (unravel_index_loop_corder(dimensions.len, dimensions.ptr, unravel_size, count, *dataptr, *strides, coordsptr) != NPY_SUCCEED) { goto fail; } coordsptr += count*dimensions.len; } while(iternext(iter)); } } else if (order == NPY_FORTRANORDER) { if (NpyIter_GetIterSize(iter) != 0) { NpyIter_IterNextFunc *iternext; char **dataptr; npy_intp *strides; npy_intp *countptr, count; npy_intp *coordsptr = (npy_intp *)PyArray_DATA(ret_arr); iternext = NpyIter_GetIterNext(iter, NULL); if (iternext == NULL) { goto fail; } dataptr = NpyIter_GetDataPtrArray(iter); strides = NpyIter_GetInnerStrideArray(iter); countptr = NpyIter_GetInnerLoopSizePtr(iter); do { count = *countptr; if (unravel_index_loop_forder(dimensions.len, dimensions.ptr, unravel_size, count, *dataptr, *strides, coordsptr) != NPY_SUCCEED) { goto fail; } coordsptr += count*dimensions.len; } while(iternext(iter)); } } else { PyErr_SetString(PyExc_ValueError, "only 'C' or 'F' order is permitted"); goto fail; } /* Now make a tuple of views, one per index */ ret_tuple = PyTuple_New(dimensions.len); if (ret_tuple == NULL) { goto fail; } for (i = 0; i < dimensions.len; ++i) { PyArrayObject *view; view = (PyArrayObject *)PyArray_New(&PyArray_Type, ret_ndim-1, ret_dims, NPY_INTP, ret_strides, PyArray_BYTES(ret_arr) + i*sizeof(npy_intp), 0, NPY_ARRAY_WRITEABLE, NULL); if (view == NULL) { goto fail; } Py_INCREF(ret_arr); if (PyArray_SetBaseObject(view, (PyObject *)ret_arr) < 0) { Py_DECREF(view); goto fail; } PyTuple_SET_ITEM(ret_tuple, i, PyArray_Return(view)); } Py_DECREF(ret_arr); Py_XDECREF(indices); PyDimMem_FREE(dimensions.ptr); NpyIter_Deallocate(iter); return ret_tuple; fail: Py_XDECREF(ret_tuple); Py_XDECREF(ret_arr); Py_XDECREF(dtype); Py_XDECREF(indices); PyDimMem_FREE(dimensions.ptr); NpyIter_Deallocate(iter); return NULL; }
/* * digitize(x, bins, right=False) returns an array of integers the same length * as x. The values i returned are such that bins[i - 1] <= x < bins[i] if * bins is monotonically increasing, or bins[i - 1] > x >= bins[i] if bins * is monotonically decreasing. Beyond the bounds of bins, returns either * i = 0 or i = len(bins) as appropriate. If right == True the comparison * is bins [i - 1] < x <= bins[i] or bins [i - 1] >= x > bins[i] */ NPY_NO_EXPORT PyObject * arr_digitize(PyObject *NPY_UNUSED(self), PyObject *args, PyObject *kwds) { PyObject *obj_x = NULL; PyObject *obj_bins = NULL; PyArrayObject *arr_x = NULL; PyArrayObject *arr_bins = NULL; PyObject *ret = NULL; npy_intp len_bins; int monotonic, right = 0; NPY_BEGIN_THREADS_DEF static char *kwlist[] = {"x", "bins", "right", NULL}; if (!PyArg_ParseTupleAndKeywords(args, kwds, "OO|i", kwlist, &obj_x, &obj_bins, &right)) { goto fail; } /* PyArray_SearchSorted will make `x` contiguous even if we don't */ arr_x = (PyArrayObject *)PyArray_FROMANY(obj_x, NPY_DOUBLE, 0, 0, NPY_ARRAY_CARRAY_RO); if (arr_x == NULL) { goto fail; } /* TODO: `bins` could be strided, needs change to check_array_monotonic */ arr_bins = (PyArrayObject *)PyArray_FROMANY(obj_bins, NPY_DOUBLE, 1, 1, NPY_ARRAY_CARRAY_RO); if (arr_bins == NULL) { goto fail; } len_bins = PyArray_SIZE(arr_bins); if (len_bins == 0) { PyErr_SetString(PyExc_ValueError, "bins must have non-zero length"); goto fail; } NPY_BEGIN_THREADS_THRESHOLDED(len_bins) monotonic = check_array_monotonic((const double *)PyArray_DATA(arr_bins), len_bins); NPY_END_THREADS if (monotonic == 0) { PyErr_SetString(PyExc_ValueError, "bins must be monotonically increasing or decreasing"); goto fail; } /* PyArray_SearchSorted needs an increasing array */ if (monotonic == - 1) { PyArrayObject *arr_tmp = NULL; npy_intp shape = PyArray_DIM(arr_bins, 0); npy_intp stride = -PyArray_STRIDE(arr_bins, 0); void *data = (void *)(PyArray_BYTES(arr_bins) - stride * (shape - 1)); arr_tmp = (PyArrayObject *)PyArray_New(&PyArray_Type, 1, &shape, NPY_DOUBLE, &stride, data, 0, PyArray_FLAGS(arr_bins), NULL); if (!arr_tmp) { goto fail; } if (PyArray_SetBaseObject(arr_tmp, (PyObject *)arr_bins) < 0) { Py_DECREF(arr_tmp); goto fail; } arr_bins = arr_tmp; } ret = PyArray_SearchSorted(arr_bins, (PyObject *)arr_x, right ? NPY_SEARCHLEFT : NPY_SEARCHRIGHT, NULL); if (!ret) { goto fail; } /* If bins is decreasing, ret has bins from end, not start */ if (monotonic == -1) { npy_intp *ret_data = (npy_intp *)PyArray_DATA((PyArrayObject *)ret); npy_intp len_ret = PyArray_SIZE((PyArrayObject *)ret); NPY_BEGIN_THREADS_THRESHOLDED(len_ret) while (len_ret--) { *ret_data = len_bins - *ret_data; ret_data++; } NPY_END_THREADS }
NRT_adapt_ndarray_to_python(arystruct_t* arystruct, int ndim, int writeable, PyArray_Descr *descr) { PyArrayObject *array; MemInfoObject *miobj = NULL; PyObject *args; npy_intp *shape, *strides; int flags = 0; if (!PyArray_DescrCheck(descr)) { PyErr_Format(PyExc_TypeError, "expected dtype object, got '%.200s'", Py_TYPE(descr)->tp_name); return NULL; } if (arystruct->parent) { PyObject *obj = try_to_return_parent(arystruct, ndim, descr); if (obj) { /* Release NRT reference to the numpy array */ NRT_MemInfo_release(arystruct->meminfo); return obj; } } if (arystruct->meminfo) { /* wrap into MemInfoObject */ miobj = PyObject_New(MemInfoObject, &MemInfoType); args = PyTuple_New(1); /* SETITEM steals reference */ PyTuple_SET_ITEM(args, 0, PyLong_FromVoidPtr(arystruct->meminfo)); /* Note: MemInfo_init() does not incref. This function steals the * NRT reference. */ if (MemInfo_init(miobj, args, NULL)) { return NULL; } Py_DECREF(args); } shape = arystruct->shape_and_strides; strides = shape + ndim; Py_INCREF((PyObject *) descr); array = (PyArrayObject *) PyArray_NewFromDescr(&PyArray_Type, descr, ndim, shape, strides, arystruct->data, flags, (PyObject *) miobj); if (array == NULL) return NULL; /* Set writable */ #if NPY_API_VERSION >= 0x00000007 if (writeable) { PyArray_ENABLEFLAGS(array, NPY_ARRAY_WRITEABLE); } else { PyArray_CLEARFLAGS(array, NPY_ARRAY_WRITEABLE); } #else if (writeable) { array->flags |= NPY_WRITEABLE; } else { array->flags &= ~NPY_WRITEABLE; } #endif if (miobj) { /* Set the MemInfoObject as the base object */ #if NPY_API_VERSION >= 0x00000007 if (-1 == PyArray_SetBaseObject(array, (PyObject *) miobj)) { Py_DECREF(array); Py_DECREF(miobj); return NULL; } #else PyArray_BASE(array) = (PyObject *) miobj; #endif } return (PyObject *) array; }
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; }