/* * PyArray_IntpFromIndexSequence * Returns the number of dimensions or -1 if an error occurred. * vals must be large enough to hold maxvals. * Opposed to PyArray_IntpFromSequence it uses and returns npy_intp * for the number of values. */ NPY_NO_EXPORT npy_intp PyArray_IntpFromIndexSequence(PyObject *seq, npy_intp *vals, npy_intp maxvals) { Py_ssize_t nd; npy_intp i; PyObject *op, *err; /* * Check to see if sequence is a single integer first. * or, can be made into one */ nd = PySequence_Length(seq); if (nd == -1) { if (PyErr_Occurred()) { PyErr_Clear(); } vals[0] = PyArray_PyIntAsIntp(seq); if(vals[0] == -1) { err = PyErr_Occurred(); if (err && PyErr_GivenExceptionMatches(err, PyExc_OverflowError)) { PyErr_SetString(PyExc_ValueError, "Maximum allowed dimension exceeded"); } if(err != NULL) { return -1; } } nd = 1; } else { for (i = 0; i < PyArray_MIN(nd,maxvals); i++) { op = PySequence_GetItem(seq, i); if (op == NULL) { return -1; } vals[i] = PyArray_PyIntAsIntp(op); Py_DECREF(op); if(vals[i] == -1) { err = PyErr_Occurred(); if (err && PyErr_GivenExceptionMatches(err, PyExc_OverflowError)) { PyErr_SetString(PyExc_ValueError, "Maximum allowed dimension exceeded"); } if(err != NULL) { return -1; } } } } return nd; }
/*NUMPY_API*/ NPY_NO_EXPORT int PyArray_PyIntAsInt(PyObject *o) { npy_intp long_value; /* This assumes that NPY_SIZEOF_INTP >= NPY_SIZEOF_INT */ long_value = PyArray_PyIntAsIntp(o); #if (NPY_SIZEOF_INTP > NPY_SIZEOF_INT) if ((long_value < INT_MIN) || (long_value > INT_MAX)) { PyErr_SetString(PyExc_ValueError, "integer won't fit into a C int"); return -1; } #endif return (int) long_value; }
/* * arr_bincount is registered as bincount. * * bincount accepts one, two or three arguments. The first is an array of * non-negative integers The second, if present, is an array of weights, * which must be promotable to double. Call these arguments list and * weight. Both must be one-dimensional with len(weight) == len(list). If * weight is not present then bincount(list)[i] is the number of occurrences * of i in list. If weight is present then bincount(self,list, weight)[i] * is the sum of all weight[j] where list [j] == i. Self is not used. * The third argument, if present, is a minimum length desired for the * output array. */ NPY_NO_EXPORT PyObject * arr_bincount(PyObject *NPY_UNUSED(self), PyObject *args, PyObject *kwds) { PyArray_Descr *type; PyObject *list = NULL, *weight=Py_None, *mlength=Py_None; PyArrayObject *lst=NULL, *ans=NULL, *wts=NULL; npy_intp *numbers, *ians, len , mx, mn, ans_size, minlength; npy_intp i; double *weights , *dans; static char *kwlist[] = {"list", "weights", "minlength", NULL}; if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|OO", kwlist, &list, &weight, &mlength)) { goto fail; } lst = (PyArrayObject *)PyArray_ContiguousFromAny(list, NPY_INTP, 1, 1); if (lst == NULL) { goto fail; } len = PyArray_SIZE(lst); type = PyArray_DescrFromType(NPY_INTP); if (mlength == Py_None) { minlength = 0; } else { minlength = PyArray_PyIntAsIntp(mlength); if (minlength <= 0) { if (!PyErr_Occurred()) { PyErr_SetString(PyExc_ValueError, "minlength must be positive"); } goto fail; } } /* handle empty list */ if (len == 0) { if (!(ans = (PyArrayObject *)PyArray_Zeros(1, &minlength, type, 0))){ goto fail; } Py_DECREF(lst); return (PyObject *)ans; } numbers = (npy_intp *) PyArray_DATA(lst); minmax(numbers, len, &mn, &mx); if (mn < 0) { PyErr_SetString(PyExc_ValueError, "The first argument of bincount must be non-negative"); goto fail; } ans_size = mx + 1; if (mlength != Py_None) { if (ans_size < minlength) { ans_size = minlength; } } if (weight == Py_None) { ans = (PyArrayObject *)PyArray_Zeros(1, &ans_size, type, 0); if (ans == NULL) { goto fail; } ians = (npy_intp *)(PyArray_DATA(ans)); NPY_BEGIN_ALLOW_THREADS; for (i = 0; i < len; i++) ians[numbers[i]] += 1; NPY_END_ALLOW_THREADS; Py_DECREF(lst); } else { wts = (PyArrayObject *)PyArray_ContiguousFromAny( weight, NPY_DOUBLE, 1, 1); if (wts == NULL) { goto fail; } weights = (double *)PyArray_DATA (wts); if (PyArray_SIZE(wts) != len) { PyErr_SetString(PyExc_ValueError, "The weights and list don't have the same length."); goto fail; } type = PyArray_DescrFromType(NPY_DOUBLE); ans = (PyArrayObject *)PyArray_Zeros(1, &ans_size, type, 0); if (ans == NULL) { goto fail; } dans = (double *)PyArray_DATA(ans); NPY_BEGIN_ALLOW_THREADS; for (i = 0; i < len; i++) { dans[numbers[i]] += weights[i]; } NPY_END_ALLOW_THREADS; Py_DECREF(lst); Py_DECREF(wts); } return (PyObject *)ans; fail: Py_XDECREF(lst); Py_XDECREF(wts); Py_XDECREF(ans); return NULL; }