/*NUMPY_API * Ptp */ NPY_NO_EXPORT PyObject * PyArray_Ptp(PyArrayObject *ap, int axis, PyArrayObject *out) { PyArrayObject *arr; PyObject *ret; PyObject *obj1 = NULL, *obj2 = NULL; arr=(PyArrayObject *)PyArray_CheckAxis(ap, &axis, 0); if (arr == NULL) { return NULL; } obj1 = PyArray_Max(arr, axis, out); if (obj1 == NULL) { goto fail; } obj2 = PyArray_Min(arr, axis, NULL); if (obj2 == NULL) { goto fail; } Py_DECREF(arr); if (out) { ret = PyObject_CallFunction(n_ops.subtract, "OOO", out, obj2, out); } else { ret = PyNumber_Subtract(obj1, obj2); } Py_DECREF(obj1); Py_DECREF(obj2); return ret; fail: Py_XDECREF(arr); Py_XDECREF(obj1); Py_XDECREF(obj2); return NULL; }
/** * Constructor */ dtnode :: dtnode(PyArrayObject* arg_edges, PyObject* arg_children, PyObject* arg_maxind, int arg_leafstart) { // Do some argument checking if(!PyList_Check(arg_children) || !PyList_Check(arg_maxind)) { // ERROR PyErr_SetString(PyExc_RuntimeError, "Non-List children/maxind element in dirtree node"); throw 1; } if(arg_leafstart < 0) { // ERROR PyErr_SetString(PyExc_RuntimeError, "Negative leafstart value in dirtree node"); throw 1; } if(PyList_Size(arg_children) != PyList_Size(arg_maxind)) { // ERROR PyErr_SetString(PyExc_RuntimeError, "Different sizes for children/maxind in dirtree node"); throw 1; } double edgemin = PyFloat_AsDouble(PyArray_Min(arg_edges,NPY_MAXDIMS,NULL)); if(edgemin <= 0) { // ERROR PyErr_SetString(PyExc_RuntimeError, "Negative/zero edge value in dirtree node"); throw 1; } // Populate data members int nci = PyList_Size(arg_children); this->leafstart = arg_leafstart; // Get edge values and sum // (note that this *must* be a copy!) npy_intp* edims = new npy_intp[1]; edims[0] = PyArray_DIM(arg_edges,0); this->edges = (PyArrayObject*) PyArray_ZEROS(1,edims,PyArray_DOUBLE,0); PyArray_CopyInto(this->edges,arg_edges); this->edgesum = PyFloat_AsDouble(PyArray_Sum(this->edges,NPY_MAXDIMS, PyArray_DOUBLE,NULL)); // Also make a copy of *original* edge values // (not augmented by counts) this->orig_edges = (PyArrayObject*) PyArray_ZEROS(1,edims,PyArray_DOUBLE,0); PyArray_CopyInto(this->orig_edges,arg_edges); this->orig_edgesum = PyFloat_AsDouble(PyArray_Sum(this->orig_edges,NPY_MAXDIMS, PyArray_DOUBLE,NULL)); delete[] edims; // Recursively build children // int c; for(c = 0; c < nci; c++) { // Get max leaf index under this child, check it maxind.push_back(PyInt_AsLong(PyList_GetItem(arg_maxind,c))); if(maxind[c] < 0) { // ERROR PyErr_SetString(PyExc_RuntimeError, "Negative maxind value in dirtree node"); throw 1; } // exploiting boolean short-circuit here... if(c > 0 && maxind[c] <= maxind[c-1]) { // ERROR PyErr_SetString(PyExc_RuntimeError, "Non-increasing maxind value in dirtree node"); throw 1; } // Recursively build child // try{ // Check that node tuple size is correct PyObject* pynode = PyList_GetItem(arg_children,c); // Is child a dtnode, or a multinode? // if(4 == PyTuple_Size(pynode)) { // dtnode // Unpack tuple contents PyArrayObject* cedges = (PyArrayObject*) PyTuple_GetItem(pynode,0); PyObject* cchildren = PyTuple_GetItem(pynode,1); PyObject* cmaxind = PyTuple_GetItem(pynode,2); int cleafstart = PyInt_AsLong(PyTuple_GetItem(pynode,3)); // Build child dtnode node* newchild = new dtnode(cedges,cchildren, cmaxind,cleafstart); ichildren.push_back(newchild); } else if(5 == PyTuple_Size(pynode)) { // multinode // Unpack tuple contents PyObject* cchildren = PyTuple_GetItem(pynode,1); PyObject* cmaxind = PyTuple_GetItem(pynode,2); int cleafstart = PyInt_AsLong(PyTuple_GetItem(pynode,3)); PyObject* variants = PyTuple_GetItem(pynode,4); // Build child multinode node* newchild = new multinode(cchildren,cmaxind, cleafstart,variants); ichildren.push_back(newchild); } else{ // ERROR PyErr_SetString(PyExc_RuntimeError, "Node has wrong number of elements"); throw 1; } } catch (int err) { throw 1; } } }