static PyObject *_histogram1d(PyObject *self, PyObject *args) { long i, n; int ix, nx; double xmin, xmax, tx, fnx, normx; PyObject *x_obj, *x_array, *count_array; npy_intp dims[1]; double *x, *count; /* Parse the input tuple */ if (!PyArg_ParseTuple(args, "Oidd", &x_obj, &nx, &xmin, &xmax)) { PyErr_SetString(PyExc_TypeError, "Error parsing input"); return NULL; } /* Interpret the input objects as `numpy` arrays. */ x_array = PyArray_FROM_OTF(x_obj, NPY_DOUBLE, NPY_IN_ARRAY); /* If that didn't work, throw an `Exception`. */ if (x_array == NULL) { PyErr_SetString(PyExc_TypeError, "Couldn't parse the input arrays."); Py_XDECREF(x_array); return NULL; } /* How many data points are there? */ n = (long)PyArray_DIM(x_array, 0); /* Build the output array */ dims[0] = nx; count_array = PyArray_SimpleNew(1, dims, NPY_DOUBLE); if (count_array == NULL) { PyErr_SetString(PyExc_TypeError, "Couldn't build output array"); Py_DECREF(x_array); Py_XDECREF(count_array); return NULL; } PyArray_FILLWBYTE(count_array, 0); /* Get pointers to the data as C-types. */ x = (double*)PyArray_DATA(x_array); count = (double*)PyArray_DATA(count_array); fnx = nx; normx = 1. / (xmax - xmin); for(i = 0; i < n; i++) { tx = x[i]; if (tx >= xmin && tx < xmax) { ix = (tx - xmin) * normx * fnx; count[ix] += 1.; } } /* Clean up. */ Py_DECREF(x_array); return count_array; }
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; } }
static PyObject *_histogram2d(PyObject *self, PyObject *args) { long i, n; int ix, iy, nx, ny; double xmin, xmax, tx, fnx, normx, ymin, ymax, ty, fny, normy; PyObject *x_obj, *y_obj, *x_array, *y_array, *count_array; npy_intp dims[2]; double *x, *y, *count; /* Parse the input tuple */ if (!PyArg_ParseTuple(args, "OOiddidd", &x_obj, &y_obj, &nx, &xmin, &xmax, &ny, &ymin, &ymax)) { PyErr_SetString(PyExc_TypeError, "Error parsing input"); return NULL; } /* Interpret the input objects as `numpy` arrays. */ x_array = PyArray_FROM_OTF(x_obj, NPY_DOUBLE, NPY_IN_ARRAY); y_array = PyArray_FROM_OTF(y_obj, NPY_DOUBLE, NPY_IN_ARRAY); /* If that didn't work, throw an `Exception`. */ if (x_array == NULL || y_array == NULL) { PyErr_SetString(PyExc_TypeError, "Couldn't parse the input arrays."); Py_XDECREF(x_array); Py_XDECREF(y_array); return NULL; } /* How many data points are there? */ n = (long)PyArray_DIM(x_array, 0); /* Check the dimensions. */ if (n != (long)PyArray_DIM(y_array, 0)) { PyErr_SetString(PyExc_RuntimeError, "Dimension mismatch between x and y"); Py_DECREF(x_array); Py_DECREF(y_array); return NULL; } /* Build the output array */ dims[0] = nx; dims[1] = ny; count_array = PyArray_SimpleNew(2, dims, NPY_DOUBLE); if (count_array == NULL) { PyErr_SetString(PyExc_TypeError, "Couldn't build output array"); Py_DECREF(x_array); Py_XDECREF(count_array); return NULL; } PyArray_FILLWBYTE(count_array, 0); /* Get pointers to the data as C-types. */ x = (double*)PyArray_DATA(x_array); y = (double*)PyArray_DATA(y_array); count = (double*)PyArray_DATA(count_array); fnx = nx; fny = ny; normx = 1. / (xmax - xmin); normy = 1. / (ymax - ymin); for(i = 0; i < n; i++) { tx = x[i]; ty = y[i]; if (tx >= xmin && tx < xmax && ty >= ymin && ty < ymax) { ix = (tx - xmin) * normx * fnx; iy = (ty - ymin) * normy * fny; count[iy + ny * ix] += 1.; } } /* Clean up. */ Py_DECREF(x_array); Py_DECREF(y_array); return count_array; }