static PyObject * array_repr_builtin(PyArrayObject *self, int repr) { PyObject *ret; char *string; /* max_n initial value is arbitrary, dump_data will extend it */ Py_ssize_t n = 0, max_n = PyArray_NBYTES(self) * 4 + 7; if ((string = PyArray_malloc(max_n)) == NULL) { return PyErr_NoMemory(); } if (dump_data(&string, &n, &max_n, PyArray_DATA(self), PyArray_NDIM(self), PyArray_DIMS(self), PyArray_STRIDES(self), self) < 0) { PyArray_free(string); return NULL; } if (repr) { if (PyArray_ISEXTENDED(self)) { ret = PyUString_FromFormat("array(%s, '%c%d')", string, PyArray_DESCR(self)->type, PyArray_DESCR(self)->elsize); } else { ret = PyUString_FromFormat("array(%s, '%c')", string, PyArray_DESCR(self)->type); } } else { ret = PyUString_FromStringAndSize(string, n); } PyArray_free(string); return ret; }
NPY_NO_EXPORT PyObject * arr_interp(PyObject *NPY_UNUSED(self), PyObject *args, PyObject *kwdict) { PyObject *fp, *xp, *x; PyObject *left = NULL, *right = NULL; PyArrayObject *afp = NULL, *axp = NULL, *ax = NULL, *af = NULL; npy_intp i, lenx, lenxp; npy_double lval, rval; const npy_double *dy, *dx, *dz; npy_double *dres, *slopes = NULL; static char *kwlist[] = {"x", "xp", "fp", "left", "right", NULL}; NPY_BEGIN_THREADS_DEF; if (!PyArg_ParseTupleAndKeywords(args, kwdict, "OOO|OO", kwlist, &x, &xp, &fp, &left, &right)) { return NULL; } afp = (PyArrayObject *)PyArray_ContiguousFromAny(fp, NPY_DOUBLE, 1, 1); if (afp == NULL) { return NULL; } axp = (PyArrayObject *)PyArray_ContiguousFromAny(xp, NPY_DOUBLE, 1, 1); if (axp == NULL) { goto fail; } ax = (PyArrayObject *)PyArray_ContiguousFromAny(x, NPY_DOUBLE, 1, 0); if (ax == NULL) { goto fail; } lenxp = PyArray_SIZE(axp); if (lenxp == 0) { PyErr_SetString(PyExc_ValueError, "array of sample points is empty"); goto fail; } if (PyArray_SIZE(afp) != lenxp) { PyErr_SetString(PyExc_ValueError, "fp and xp are not of the same length."); goto fail; } af = (PyArrayObject *)PyArray_SimpleNew(PyArray_NDIM(ax), PyArray_DIMS(ax), NPY_DOUBLE); if (af == NULL) { goto fail; } lenx = PyArray_SIZE(ax); dy = (const npy_double *)PyArray_DATA(afp); dx = (const npy_double *)PyArray_DATA(axp); dz = (const npy_double *)PyArray_DATA(ax); dres = (npy_double *)PyArray_DATA(af); /* Get left and right fill values. */ if ((left == NULL) || (left == Py_None)) { lval = dy[0]; } else { lval = PyFloat_AsDouble(left); if ((lval == -1) && PyErr_Occurred()) { goto fail; } } if ((right == NULL) || (right == Py_None)) { rval = dy[lenxp - 1]; } else { rval = PyFloat_AsDouble(right); if ((rval == -1) && PyErr_Occurred()) { goto fail; } } /* binary_search_with_guess needs at least a 3 item long array */ if (lenxp == 1) { const npy_double xp_val = dx[0]; const npy_double fp_val = dy[0]; NPY_BEGIN_THREADS_THRESHOLDED(lenx); for (i = 0; i < lenx; ++i) { const npy_double x_val = dz[i]; dres[i] = (x_val < xp_val) ? lval : ((x_val > xp_val) ? rval : fp_val); } NPY_END_THREADS; } else { npy_intp j = 0; /* only pre-calculate slopes if there are relatively few of them. */ if (lenxp <= lenx) { slopes = PyArray_malloc((lenxp - 1) * sizeof(npy_double)); if (slopes == NULL) { goto fail; } } NPY_BEGIN_THREADS; if (slopes != NULL) { for (i = 0; i < lenxp - 1; ++i) { slopes[i] = (dy[i+1] - dy[i]) / (dx[i+1] - dx[i]); } } for (i = 0; i < lenx; ++i) { const npy_double x_val = dz[i]; if (npy_isnan(x_val)) { dres[i] = x_val; continue; } j = binary_search_with_guess(x_val, dx, lenxp, j); if (j == -1) { dres[i] = lval; } else if (j == lenxp) { dres[i] = rval; } else if (j == lenxp - 1) { dres[i] = dy[j]; } else { const npy_double slope = (slopes != NULL) ? slopes[j] : (dy[j+1] - dy[j]) / (dx[j+1] - dx[j]); dres[i] = slope*(x_val - dx[j]) + dy[j]; } } NPY_END_THREADS; } PyArray_free(slopes); Py_DECREF(afp); Py_DECREF(axp); Py_DECREF(ax); return (PyObject *)af; fail: Py_XDECREF(afp); Py_XDECREF(axp); Py_XDECREF(ax); Py_XDECREF(af); return NULL; }
static PyObject * ufunc_frompyfunc(PyObject *NPY_UNUSED(dummy), PyObject *args, PyObject *NPY_UNUSED(kwds)) { /* Keywords are ignored for now */ PyObject *function, *pyname = NULL; int nin, nout, i; PyUFunc_PyFuncData *fdata; PyUFuncObject *self; char *fname, *str; Py_ssize_t fname_len = -1; int offset[2]; if (!PyArg_ParseTuple(args, "Oii", &function, &nin, &nout)) { return NULL; } if (!PyCallable_Check(function)) { PyErr_SetString(PyExc_TypeError, "function must be callable"); return NULL; } if (nin + nout > NPY_MAXARGS) { PyErr_Format(PyExc_ValueError, "Cannot construct a ufunc with more than %d operands " "(requested number were: inputs = %d and outputs = %d)", NPY_MAXARGS, nin, nout); return NULL; } self = PyArray_malloc(sizeof(PyUFuncObject)); if (self == NULL) { return NULL; } PyObject_Init((PyObject *)self, &PyUFunc_Type); self->userloops = NULL; self->nin = nin; self->nout = nout; self->nargs = nin + nout; self->identity = PyUFunc_None; self->functions = pyfunc_functions; self->ntypes = 1; /* generalized ufunc */ self->core_enabled = 0; self->core_num_dim_ix = 0; self->core_num_dims = NULL; self->core_dim_ixs = NULL; self->core_offsets = NULL; self->core_signature = NULL; self->op_flags = PyArray_malloc(sizeof(npy_uint32)*self->nargs); if (self->op_flags == NULL) { return PyErr_NoMemory(); } memset(self->op_flags, 0, sizeof(npy_uint32)*self->nargs); self->iter_flags = 0; self->type_resolver = &object_ufunc_type_resolver; self->legacy_inner_loop_selector = &object_ufunc_loop_selector; pyname = PyObject_GetAttrString(function, "__name__"); if (pyname) { (void) PyString_AsStringAndSize(pyname, &fname, &fname_len); } if (PyErr_Occurred()) { fname = "?"; fname_len = 1; PyErr_Clear(); } /* * self->ptr holds a pointer for enough memory for * self->data[0] (fdata) * self->data * self->name * self->types * * To be safest, all of these need their memory aligned on void * pointers * Therefore, we may need to allocate extra space. */ offset[0] = sizeof(PyUFunc_PyFuncData); i = (sizeof(PyUFunc_PyFuncData) % sizeof(void *)); if (i) { offset[0] += (sizeof(void *) - i); } offset[1] = self->nargs; i = (self->nargs % sizeof(void *)); if (i) { offset[1] += (sizeof(void *)-i); } self->ptr = PyArray_malloc(offset[0] + offset[1] + sizeof(void *) + (fname_len + 14)); if (self->ptr == NULL) { Py_XDECREF(pyname); return PyErr_NoMemory(); } Py_INCREF(function); self->obj = function; fdata = (PyUFunc_PyFuncData *)(self->ptr); fdata->nin = nin; fdata->nout = nout; fdata->callable = function; self->data = (void **)(((char *)self->ptr) + offset[0]); self->data[0] = (void *)fdata; self->types = (char *)self->data + sizeof(void *); for (i = 0; i < self->nargs; i++) { self->types[i] = NPY_OBJECT; } str = self->types + offset[1]; memcpy(str, fname, fname_len); memcpy(str+fname_len, " (vectorized)", 14); self->name = str; Py_XDECREF(pyname); /* Do a better job someday */ self->doc = "dynamic ufunc based on a python function"; return (PyObject *)self; }
static PyObject * ufunc_frompyfunc(PyObject *NPY_UNUSED(dummy), PyObject *args, PyObject *NPY_UNUSED(kwds)) { /* Keywords are ignored for now */ PyObject *function, *pyname = NULL; int nin, nout, i, nargs; PyUFunc_PyFuncData *fdata; PyUFuncObject *self; char *fname, *str, *types, *doc; Py_ssize_t fname_len = -1; void * ptr, **data; int offset[2]; if (!PyArg_ParseTuple(args, "Oii:frompyfunc", &function, &nin, &nout)) { return NULL; } if (!PyCallable_Check(function)) { PyErr_SetString(PyExc_TypeError, "function must be callable"); return NULL; } nargs = nin + nout; pyname = PyObject_GetAttrString(function, "__name__"); if (pyname) { (void) PyString_AsStringAndSize(pyname, &fname, &fname_len); } if (PyErr_Occurred()) { fname = "?"; fname_len = 1; PyErr_Clear(); } /* * ptr will be assigned to self->ptr, holds a pointer for enough memory for * self->data[0] (fdata) * self->data * self->name * self->types * * To be safest, all of these need their memory aligned on void * pointers * Therefore, we may need to allocate extra space. */ offset[0] = sizeof(PyUFunc_PyFuncData); i = (sizeof(PyUFunc_PyFuncData) % sizeof(void *)); if (i) { offset[0] += (sizeof(void *) - i); } offset[1] = nargs; i = (nargs % sizeof(void *)); if (i) { offset[1] += (sizeof(void *)-i); } ptr = PyArray_malloc(offset[0] + offset[1] + sizeof(void *) + (fname_len + 14)); if (ptr == NULL) { Py_XDECREF(pyname); return PyErr_NoMemory(); } fdata = (PyUFunc_PyFuncData *)(ptr); fdata->callable = function; fdata->nin = nin; fdata->nout = nout; data = (void **)(((char *)ptr) + offset[0]); data[0] = (void *)fdata; types = (char *)data + sizeof(void *); for (i = 0; i < nargs; i++) { types[i] = NPY_OBJECT; } str = types + offset[1]; memcpy(str, fname, fname_len); memcpy(str+fname_len, " (vectorized)", 14); Py_XDECREF(pyname); /* Do a better job someday */ doc = "dynamic ufunc based on a python function"; self = (PyUFuncObject *)PyUFunc_FromFuncAndData( (PyUFuncGenericFunction *)pyfunc_functions, data, types, /* ntypes */ 1, nin, nout, PyUFunc_None, str, doc, /* unused */ 0); if (self == NULL) { PyArray_free(ptr); return NULL; } Py_INCREF(function); self->obj = function; self->ptr = ptr; self->type_resolver = &object_ufunc_type_resolver; self->legacy_inner_loop_selector = &object_ufunc_loop_selector; return (PyObject *)self; }
/* * Converts a Python input into a non-normalized list of holidays. * * IMPORTANT: This function can't do the normalization, because it doesn't * know the weekmask. You must call 'normalize_holiday_list' * on the result before using it. */ NPY_NO_EXPORT int PyArray_HolidaysConverter(PyObject *dates_in, npy_holidayslist *holidays) { PyArrayObject *dates = NULL; PyArray_Descr *date_dtype = NULL; npy_intp count; /* Make 'dates' into an array */ if (PyArray_Check(dates_in)) { dates = (PyArrayObject *)dates_in; Py_INCREF(dates); } else { PyArray_Descr *datetime_dtype; /* Use the datetime dtype with generic units so it fills it in */ datetime_dtype = PyArray_DescrFromType(NPY_DATETIME); if (datetime_dtype == NULL) { goto fail; } /* This steals the datetime_dtype reference */ dates = (PyArrayObject *)PyArray_FromAny(dates_in, datetime_dtype, 0, 0, 0, dates_in); if (dates == NULL) { goto fail; } } date_dtype = create_datetime_dtype_with_unit(NPY_DATETIME, NPY_FR_D); if (date_dtype == NULL) { goto fail; } if (!PyArray_CanCastTypeTo(PyArray_DESCR(dates), date_dtype, NPY_SAFE_CASTING)) { PyErr_SetString(PyExc_ValueError, "Cannot safely convert " "provided holidays input into an array of dates"); goto fail; } if (PyArray_NDIM(dates) != 1) { PyErr_SetString(PyExc_ValueError, "holidays must be a provided " "as a one-dimensional array"); goto fail; } /* Allocate the memory for the dates */ count = PyArray_DIM(dates, 0); holidays->begin = PyArray_malloc(sizeof(npy_datetime) * count); if (holidays->begin == NULL) { PyErr_NoMemory(); goto fail; } holidays->end = holidays->begin + count; /* Cast the data into a raw date array */ if (PyArray_CastRawArrays(count, PyArray_BYTES(dates), (char *)holidays->begin, PyArray_STRIDE(dates, 0), sizeof(npy_datetime), PyArray_DESCR(dates), date_dtype, 0) != NPY_SUCCEED) { goto fail; } Py_DECREF(dates); Py_DECREF(date_dtype); return 1; fail: Py_XDECREF(dates); Py_XDECREF(date_dtype); return 0; }
PyObject * ufunc_fromfunc(PyObject *NPY_UNUSED(dummy), PyObject *args) { // unsigned long func_address; // unused int nin, nout; int nfuncs, ntypes, ndata; PyObject *func_list; PyObject *type_list; PyObject *data_list; PyObject *func_obj; PyObject *type_obj; PyObject *data_obj; PyObject *object=NULL; /* object to hold on to while ufunc is alive */ PyObject *dispatcher = NULL; int i, j; int custom_dtype = 0; PyUFuncGenericFunction *funcs; int *types; void **data; PyObject *ufunc; if (!PyArg_ParseTuple(args, "O!O!iiO|OO", &PyList_Type, &func_list, &PyList_Type, &type_list, &nin, &nout, &data_list, &dispatcher, &object)) { return NULL; } if (dispatcher == Py_None) dispatcher = NULL; nfuncs = PyList_Size(func_list); ntypes = PyList_Size(type_list); if (ntypes != nfuncs) { PyErr_SetString(PyExc_TypeError, "length of types list must be same as length of function pointer list"); return NULL; } ndata = PyList_Size(data_list); if (ndata != nfuncs) { PyErr_SetString(PyExc_TypeError, "length of data pointer list must be same as length of function pointer list"); return NULL; } funcs = PyArray_malloc(nfuncs * sizeof(PyUFuncGenericFunction)); if (funcs == NULL) { return NULL; } /* build function pointer array */ for (i = 0; i < nfuncs; i++) { func_obj = PyList_GetItem(func_list, i); /* Function pointers are passed in as long objects. Is there a better way to do this? */ if (PyLong_Check(func_obj)) { funcs[i] = (PyUFuncGenericFunction)PyLong_AsVoidPtr(func_obj); } else { PyErr_SetString(PyExc_TypeError, "function pointer must be long object, or None"); return NULL; } } types = PyArray_malloc(nfuncs * (nin+nout) * sizeof(int)); if (types == NULL) { return NULL; } /* build function signatures array */ for (i = 0; i < nfuncs; i++) { type_obj = PyList_GetItem(type_list, i); if (!type_obj) return NULL; for (j = 0; j < (nin+nout); j++) { int dtype_num; PyObject *dtype_num_obj = PyList_GetItem(type_obj, j); if (!dtype_num_obj) return NULL; SENTRY_VALID_LONG( types[i*(nin+nout) + j] = PyLong_AsLong(dtype_num_obj) ); dtype_num = PyLong_AsLong(PyList_GetItem(type_obj, j)); SENTRY_VALID_LONG(dtype_num); if (dtype_num >= NPY_USERDEF) { custom_dtype = dtype_num; } } } data = PyArray_malloc(nfuncs * sizeof(void *)); if (data == NULL) { return NULL; } /* build function data pointers array */ for (i = 0; i < nfuncs; i++) { if (PyList_Check(data_list)) { data_obj = PyList_GetItem(data_list, i); if (PyLong_Check(data_obj)) { data[i] = PyLong_AsVoidPtr(data_obj); } else if (data_obj == Py_None) { data[i] = NULL; } else { PyErr_SetString(PyExc_TypeError, "data pointer must be long object, or None"); return NULL; } } else if (data_list == Py_None) { data[i] = NULL; } else { PyErr_SetString(PyExc_TypeError, "data pointers argument must be a list of void pointers, or None"); return NULL; } } if (!custom_dtype) { char *char_types = PyArray_malloc(nfuncs * (nin+nout) * sizeof(char)); for (i = 0; i < nfuncs; i++) { for (j = 0; j < (nin+nout); j++) { char_types[i*(nin+nout) + j] = (char)types[i*(nin+nout) + j]; } } PyArray_free(types); ufunc = PyDynUFunc_FromFuncAndData((PyUFuncGenericFunction*) funcs, data, (char*) char_types, nfuncs, nin, nout, PyUFunc_None, "ufunc", (char*) "ufunc", object, dispatcher); } else { ufunc = PyDynUFunc_FromFuncAndData(0, 0, 0, 0, nin, nout, PyUFunc_None, "ufunc", (char*) "ufunc", object, dispatcher); PyUFunc_RegisterLoopForType((PyUFuncObject*)ufunc, custom_dtype, funcs[0], types, 0); PyArray_free(funcs); PyArray_free(types); PyArray_free(data); } return ufunc; }
fffpy_multi_iterator* fffpy_multi_iterator_new(int narr, int axis, ...) { fffpy_multi_iterator* thisone; va_list va; fff_vector** vector; PyArrayMultiIterObject *multi; PyObject *current, *arr; int i, err=0; /* Create new instance */ thisone = (fffpy_multi_iterator*)malloc(sizeof(fffpy_multi_iterator)); multi = PyArray_malloc(sizeof(PyArrayMultiIterObject)); vector = (fff_vector**)malloc(narr*sizeof(fff_vector*)); /* Initialize the PyArrayMultiIterObject instance from the variadic arguments */ PyObject_Init((PyObject *)multi, &PyArrayMultiIter_Type); for (i=0; i<narr; i++) multi->iters[i] = NULL; multi->numiter = narr; multi->index = 0; va_start(va, axis); for (i=0; i<narr; i++) { current = va_arg(va, PyObject *); arr = PyArray_FROM_O(current); if (arr==NULL) { err=1; break; } else { multi->iters[i] = (PyArrayIterObject *)PyArray_IterAllButAxis(arr, &axis); Py_DECREF(arr); } } va_end(va); /* Test */ if (!err && _PyArray_BroadcastAllButAxis(multi, axis) < 0) err=1; if (err) { FFF_ERROR("Cannot create broadcast object", ENOMEM); free(thisone); free(vector); Py_DECREF(multi); return NULL; } /* Initialize the multi iterator */ PyArray_MultiIter_RESET(multi); /* Create the fff vectors (views or copies) */ for(i=0; i<narr; i++) vector[i] = _fff_vector_new_from_PyArrayIter((const PyArrayIterObject*)multi->iters[i], axis); /* Instantiate fiels */ thisone->narr = narr; thisone->axis = axis; thisone->vector = vector; thisone->multi = multi; thisone->index = thisone->multi->index; thisone->size = thisone->multi->size; return thisone; }