static PyObject *phoebeRV2(PyObject *self, PyObject *args) { int index, i; PyObject *obj, *ret, *ts; char *rstr; PHOEBE_column_type itype; PHOEBE_vector *indep; PHOEBE_curve *curve; if (!PyArg_ParseTuple(args, "Oi", &obj, &index)) { printf("parsing failed: call with rv2(t_array, curve_index).\n"); return NULL; } ts = PyArray_FromObject(obj, NPY_DOUBLE, 0, 0); indep = phoebe_vector_new_from_copied_data(PyArray_DATA(ts), PyArray_SIZE(ts)); phoebe_parameter_get_value (phoebe_parameter_lookup ("phoebe_indep"), &rstr); phoebe_column_get_type (&itype, rstr); curve = phoebe_curve_new(); phoebe_curve_compute(curve, indep, index, itype, PHOEBE_COLUMN_SECONDARY_RV, NULL, NULL, NULL); ret = PyTuple_New(indep->dim); for (i = 0; i < indep->dim; i++) PyTuple_SetItem(ret, i, Py_BuildValue("d", curve->dep->val[i])); phoebe_curve_free(curve); phoebe_vector_free(indep); return ret; }
static PyObject *soomfunc_preload(PyObject *module, PyObject *args) { PyObject *obj; PyArrayObject *array; int preload = -1; if (!PyArg_ParseTuple(args, "O|i", &obj, &preload)) return NULL; array = (PyArrayObject *)PyArray_FromObject(obj, PyArray_NOTYPE, 0, 0); if (array == NULL) return NULL; if (array->nd != 1) { PyErr_SetString(PyExc_ValueError, "arrays must be rank-1"); Py_DECREF(array); return NULL; } if (preload < 0 || preload > array->dimensions[0]) preload = array->dimensions[0] - 1; INSTRUMENT(("ssi", "preload", "enter", preload)); switch (array->descr->type_num) { case PyArray_CHAR: case PyArray_SBYTE: preload_schar(array, preload); break; case PyArray_UBYTE: preload_uchar(array, preload); break; case PyArray_SHORT: preload_short(array, preload); break; case PyArray_INT: preload_int(array, preload); break; case PyArray_LONG: preload_long(array, preload); break; case PyArray_FLOAT: preload_float(array, preload); break; case PyArray_DOUBLE: preload_double(array, preload); break; } Py_DECREF(array); Py_INCREF(Py_None); INSTRUMENT(("ss", "preload", "exit")); return Py_None; }
static PyObject *IIRsymorder2(PyObject *NPY_UNUSED(dummy), PyObject *args) { PyObject *sig=NULL; PyArrayObject *a_sig=NULL, *out=NULL; double r, omega; double precision = -1.0; int thetype, N, ret; npy_intp outstrides, instrides; if (!PyArg_ParseTuple(args, "Odd|d", &sig, &r, &omega, &precision)) return NULL; thetype = PyArray_ObjectType(sig, PyArray_FLOAT); thetype = NPY_MIN(thetype, PyArray_DOUBLE); a_sig = (PyArrayObject *)PyArray_FromObject(sig, thetype, 1, 1); if ((a_sig == NULL)) goto fail; out = (PyArrayObject *)PyArray_SimpleNew(1,DIMS(a_sig),thetype); if (out == NULL) goto fail; N = DIMS(a_sig)[0]; convert_strides(STRIDES(a_sig), &instrides, ELSIZE(a_sig), 1); outstrides = 1; switch (thetype) { case PyArray_FLOAT: if ((precision <= 0.0) || (precision > 1.0)) precision = 1e-6; ret = S_IIR_forback2 (r, omega, (float *)DATA(a_sig), (float *)DATA(out), N, instrides, outstrides, precision); break; case PyArray_DOUBLE: if ((precision <= 0.0) || (precision > 1.0)) precision = 1e-11; ret = D_IIR_forback2 (r, omega, (double *)DATA(a_sig), (double *)DATA(out), N, instrides, outstrides, precision); break; default: PYERR("Incorrect type."); } if (ret < 0) PYERR("Problem occured inside routine."); Py_DECREF(a_sig); return PyArray_Return(out); fail: Py_XDECREF(a_sig); Py_XDECREF(out); return NULL; }
static void* convertible(PyObject* obj_ptr) { PyArrayObject* a; a = (PyArrayObject*)PyArray_FromObject( obj_ptr, ::detail::numpy_type_map<T>::typenum, NDims, NDims); if (a == NULL) { return 0; } Py_DECREF(a); return obj_ptr; }
/* Construct from an existing Numpy array */ numpy_boost(PyObject* obj) throw (python_exception) : super(NULL, std::vector<typename super::index>(NDims, 0)), array(NULL) { PyArrayObject* a; a = (PyArrayObject*)PyArray_FromObject( obj, detail::numpy_type_map<T>::typenum, NDims, NDims); if (a == NULL) { throw python_exception(); } init_from_array(a); }
/* Construct from an existing Numpy array */ numpy_boost(PyObject* obj) throw () : super(NULL, std::vector<typename super::index>(NDims, 0)), array(NULL) { PyArrayObject* a; a = (PyArrayObject*)PyArray_FromObject( obj, detail::numpy_type_map<T>::typenum, NDims, NDims); if (a == NULL) { throw boost::python::error_already_set(); } init_from_array(a); }
static PyObject *qspline2d(PyObject *NPY_UNUSED(dummy), PyObject *args) { PyObject *image=NULL; PyArrayObject *a_image=NULL, *ck=NULL; double lambda = 0.0; double precision = -1.0; int thetype, M, N, retval=0; npy_intp outstrides[2], instrides[2]; if (!PyArg_ParseTuple(args, "O|dd", &image, &lambda, &precision)) return NULL; if (lambda != 0.0) PYERR("Smoothing spline not yet implemented."); thetype = PyArray_ObjectType(image, PyArray_FLOAT); thetype = NPY_MIN(thetype, PyArray_DOUBLE); a_image = (PyArrayObject *)PyArray_FromObject(image, thetype, 2, 2); if (a_image == NULL) goto fail; ck = (PyArrayObject *)PyArray_SimpleNew(2,DIMS(a_image),thetype); if (ck == NULL) goto fail; M = DIMS(a_image)[0]; N = DIMS(a_image)[1]; convert_strides(STRIDES(a_image), instrides, ELSIZE(a_image), 2); outstrides[0] = N; outstrides[1] = 1; if (thetype == PyArray_FLOAT) { if ((precision <= 0.0) || (precision > 1.0)) precision = 1e-3; retval = S_quadratic_spline2D((float *)DATA(a_image), (float *)DATA(ck), M, N, lambda, instrides, outstrides, precision); } else if (thetype == PyArray_DOUBLE) { if ((precision <= 0.0) || (precision > 1.0)) precision = 1e-6; retval = D_quadratic_spline2D((double *)DATA(a_image), (double *)DATA(ck), M, N, lambda, instrides, outstrides, precision); } if (retval == -3) PYERR("Precision too high. Error did not converge."); if (retval < 0) PYERR("Problem occured inside routine"); Py_DECREF(a_image); return PyArray_Return(ck); fail: Py_XDECREF(a_image); Py_XDECREF(ck); return NULL; }
PyObject * PyAubio_CFmatToArray (fmat_t * input) { PyObject *array = NULL; uint_t i; npy_intp dims[] = { input->length, 1 }; PyObject *concat = PyList_New (0), *tmp = NULL; for (i = 0; i < input->height; i++) { tmp = PyArray_SimpleNewFromData (1, dims, AUBIO_NPY_SMPL, input->data[i]); PyList_Append (concat, tmp); Py_DECREF (tmp); } array = PyArray_FromObject (concat, AUBIO_NPY_SMPL, 2, 2); Py_DECREF (concat); return array; }
/* Convert the given PyObject to a NumPy array with the given * typecode. On success, return a valid PyArrayObject* with the * correct type. On failure, the python error string will be set and * the routine returns NULL. */ PyArrayObject* obj_to_array_allow_conversion(PyObject* input, int typecode, int* is_new_object) { PyArrayObject* ary = NULL; PyObject* py_obj; if (is_array(input) && (typecode == NPY_NOTYPE || PyArray_EquivTypenums(array_type(input),typecode))) { ary = (PyArrayObject*) input; *is_new_object = 0; } else { py_obj = PyArray_FromObject(input, typecode, 0, 0); /* If NULL, PyArray_FromObject will have set python error value.*/ ary = (PyArrayObject*) py_obj; *is_new_object = 1; } PyErr_Clear(); return ary; }
static ArrayInfo *check_array_args(PyObject *args, int min_arrays, int max_arrays, int contiguous) { char msg[128]; ArrayInfo *array_info, *info; int num_arrays, type_num, i; num_arrays = PyTuple_Size(args); if (num_arrays < min_arrays) { sprintf(msg, "at least %d arrays required", min_arrays); PyErr_SetString(PyExc_ValueError, msg); return NULL; } if (max_arrays > 0 && num_arrays > max_arrays) { sprintf(msg, "more than %d arrays not supported", max_arrays); PyErr_SetString(PyExc_ValueError, msg); return NULL; } type_num = -1; array_info = malloc(sizeof(*array_info) * num_arrays); if (array_info == NULL) return (ArrayInfo*)PyErr_NoMemory(); memset(array_info, 0, sizeof(*array_info) * num_arrays); for (i = 0, info = array_info; i < num_arrays; i++, info++) { PyObject *arg; PyArrayObject *array; arg = PyTuple_GetItem(args, i); if (arg == NULL) goto error; if (contiguous) array = (PyArrayObject *) PyArray_ContiguousFromObject(arg, PyArray_NOTYPE, 0, 0); else array = (PyArrayObject *) PyArray_FromObject(arg, PyArray_NOTYPE, 0, 0); if (array == NULL) goto error; if (i == 0) type_num = array->descr->type_num; else if (array->descr->type_num != type_num) { PyErr_SetString(PyExc_ValueError, "arrays must have the same typecode"); goto error; } if (array->nd != 1) { PyErr_SetString(PyExc_ValueError, "arrays must be rank-1"); goto error; } if (array->descr->type_num == PyArray_CFLOAT || array->descr->type_num == PyArray_CDOUBLE || array->descr->type_num == PyArray_OBJECT || array->descr->type_num == PyArray_NTYPES || array->descr->type_num == PyArray_NOTYPE) { PyErr_SetString(PyExc_ValueError, "unhandled array type"); goto error; } set_array_info(info, array); } return array_info; error: free_array_info(array_info, num_arrays); return NULL; }
static PyObject* test_neighborhood_iterator_oob(PyObject* NPY_UNUSED(self), PyObject* args) { PyObject *x, *out, *b1, *b2; PyArrayObject *ax; PyArrayIterObject *itx; int i, typenum, mode1, mode2, st; npy_intp bounds[NPY_MAXDIMS*2]; PyArrayNeighborhoodIterObject *niterx1, *niterx2; if (!PyArg_ParseTuple(args, "OOiOi", &x, &b1, &mode1, &b2, &mode2)) { return NULL; } if (!PySequence_Check(b1) || !PySequence_Check(b2)) { return NULL; } typenum = PyArray_ObjectType(x, 0); ax = (PyArrayObject*)PyArray_FromObject(x, typenum, 1, 10); if (ax == NULL) { return NULL; } if (PySequence_Size(b1) != 2 * PyArray_NDIM(ax)) { PyErr_SetString(PyExc_ValueError, "bounds sequence 1 size not compatible with x input"); goto clean_ax; } if (PySequence_Size(b2) != 2 * PyArray_NDIM(ax)) { PyErr_SetString(PyExc_ValueError, "bounds sequence 2 size not compatible with x input"); goto clean_ax; } out = PyList_New(0); if (out == NULL) { goto clean_ax; } itx = (PyArrayIterObject*)PyArray_IterNew(x); if (itx == NULL) { goto clean_out; } /* Compute boundaries for the neighborhood iterator */ for (i = 0; i < 2 * PyArray_NDIM(ax); ++i) { PyObject* bound; bound = PySequence_GetItem(b1, i); if (bounds == NULL) { goto clean_itx; } if (!PyInt_Check(bound)) { PyErr_SetString(PyExc_ValueError, "bound not long"); Py_DECREF(bound); goto clean_itx; } bounds[i] = PyInt_AsLong(bound); Py_DECREF(bound); } /* Create the neighborhood iterator */ niterx1 = (PyArrayNeighborhoodIterObject*)PyArray_NeighborhoodIterNew( (PyArrayIterObject*)itx, bounds, mode1, NULL); if (niterx1 == NULL) { goto clean_out; } for (i = 0; i < 2 * PyArray_NDIM(ax); ++i) { PyObject* bound; bound = PySequence_GetItem(b2, i); if (bounds == NULL) { goto clean_itx; } if (!PyInt_Check(bound)) { PyErr_SetString(PyExc_ValueError, "bound not long"); Py_DECREF(bound); goto clean_itx; } bounds[i] = PyInt_AsLong(bound); Py_DECREF(bound); } niterx2 = (PyArrayNeighborhoodIterObject*)PyArray_NeighborhoodIterNew( (PyArrayIterObject*)niterx1, bounds, mode2, NULL); if (niterx1 == NULL) { goto clean_niterx1; } switch (typenum) { case NPY_DOUBLE: st = copy_double_double(niterx1, niterx2, bounds, &out); break; default: PyErr_SetString(PyExc_ValueError, "Type not supported"); goto clean_niterx2; } if (st) { goto clean_niterx2; } Py_DECREF(niterx2); Py_DECREF(niterx1); Py_DECREF(itx); Py_DECREF(ax); return out; clean_niterx2: Py_DECREF(niterx2); clean_niterx1: Py_DECREF(niterx1); clean_itx: Py_DECREF(itx); clean_out: Py_DECREF(out); clean_ax: Py_DECREF(ax); return NULL; }
Py::Object _image_module::fromarray(const Py::Tuple& args) { _VERBOSE("_image_module::fromarray"); args.verify_length(2); Py::Object x = args[0]; int isoutput = Py::Int(args[1]); //PyArrayObject *A = (PyArrayObject *) PyArray_ContiguousFromObject(x.ptr(), PyArray_DOUBLE, 2, 3); PyArrayObject *A = (PyArrayObject *) PyArray_FromObject(x.ptr(), PyArray_DOUBLE, 2, 3); if (A==NULL) throw Py::ValueError("Array must be rank 2 or 3 of doubles"); Image* imo = new Image; imo->rowsIn = A->dimensions[0]; imo->colsIn = A->dimensions[1]; size_t NUMBYTES(imo->colsIn * imo->rowsIn * imo->BPP); agg::int8u *buffer = new agg::int8u[NUMBYTES]; if (buffer==NULL) //todo: also handle allocation throw throw Py::MemoryError("_image_module::fromarray could not allocate memory"); if (isoutput) { // make the output buffer point to the input buffer imo->rowsOut = imo->rowsIn; imo->colsOut = imo->colsIn; imo->rbufOut = new agg::rendering_buffer; imo->bufferOut = buffer; imo->rbufOut->attach(imo->bufferOut, imo->colsOut, imo->rowsOut, imo->colsOut * imo->BPP); } else { imo->bufferIn = buffer; imo->rbufIn = new agg::rendering_buffer; imo->rbufIn->attach(buffer, imo->colsIn, imo->rowsIn, imo->colsIn*imo->BPP); } if (A->nd == 2) { //assume luminance for now; agg::int8u gray; for (size_t rownum=0; rownum<imo->rowsIn; rownum++) for (size_t colnum=0; colnum<imo->colsIn; colnum++) { double val = *(double *)(A->data + rownum*A->strides[0] + colnum*A->strides[1]); gray = int(255 * val); *buffer++ = gray; // red *buffer++ = gray; // green *buffer++ = gray; // blue *buffer++ = 255; // alpha } } else if (A->nd == 3) { // assume RGB if (A->dimensions[2] != 3 && A->dimensions[2] != 4 ) { Py_XDECREF(A); throw Py::ValueError(Printf("3rd dimension must be length 3 (RGB) or 4 (RGBA); found %d", A->dimensions[2]).str()); } int rgba = A->dimensions[2]==4; double r,g,b,alpha; int offset =0; for (size_t rownum=0; rownum<imo->rowsIn; rownum++) for (size_t colnum=0; colnum<imo->colsIn; colnum++) { offset = rownum*A->strides[0] + colnum*A->strides[1]; r = *(double *)(A->data + offset); g = *(double *)(A->data + offset + A->strides[2] ); b = *(double *)(A->data + offset + 2*A->strides[2] ); if (rgba) alpha = *(double *)(A->data + offset + 3*A->strides[2] ); else alpha = 1.0; *buffer++ = int(255*r); // red *buffer++ = int(255*g); // green *buffer++ = int(255*b); // blue *buffer++ = int(255*alpha); // alpha } } else { // error Py_XDECREF(A); throw Py::ValueError("Illegal array rank; must be rank; must 2 or 3"); } buffer -= NUMBYTES; Py_XDECREF(A); return Py::asObject( imo ); }
static PyObject *phoebeLC(PyObject *self, PyObject *args) { int status; int index, i; PyObject *obj, *lc, *combo = NULL, *ts = NULL; char *rstr; Py_ssize_t mswitch = 0, hswitch = 0; PHOEBE_column_type itype; PHOEBE_vector *indep; PHOEBE_curve *curve; PHOEBE_mesh *mesh1 = NULL, *mesh2 = NULL; PHOEBE_horizon *horizon = NULL; if (!PyArg_ParseTuple(args, "Oi|ii", &obj, &index, &mswitch, &hswitch)) { printf("parsing failed: call with lc(t_array, curve_index [, mswitch, hswitch]).\n"); return NULL; } // printf("array type: %s\n", obj->ob_type->tp_name); // if (!PyArray_Check(obj)) { // printf("timestamps need to be provided as a numpy-compatible array.\n"); // return NULL; // } // tlen = PyTuple_Size(obj); ts = PyArray_FromObject(obj, NPY_DOUBLE, 0, 0); indep = phoebe_vector_new_from_copied_data(PyArray_DATA(ts), PyArray_SIZE(ts)); // printf("dim=%d\n", indep->dim); phoebe_parameter_get_value (phoebe_parameter_lookup ("phoebe_indep"), &rstr); phoebe_column_get_type (&itype, rstr); /* If mswitch is turned on, we need to store the computed meshes. */ if (mswitch) { mesh1 = phoebe_mesh_new(); mesh2 = phoebe_mesh_new(); } /* If hswitch is turned on, we need to store the horizon. */ if (hswitch) { horizon = phoebe_horizon_new(); } curve = phoebe_curve_new(); status = phoebe_curve_compute(curve, indep, index, itype, PHOEBE_COLUMN_FLUX, mesh1, mesh2, horizon); if (status != SUCCESS) { printf("%s", phoebe_error(status)); return NULL; } lc = PyTuple_New(indep->dim); for (i = 0; i < indep->dim; i++) PyTuple_SetItem(lc, i, Py_BuildValue("d", curve->dep->val[i])); if (mswitch || hswitch) { combo = PyTuple_New(1 + mswitch + hswitch); PyTuple_SetItem(combo, 0, lc); } if (mswitch) { /* Now we need to wrap this into something nice. */ PyObject *dict = PyDict_New(); intern_add_mesh_to_dict(dict, mesh1, "vcx1", 0); intern_add_mesh_to_dict(dict, mesh1, "vcy1", 1); intern_add_mesh_to_dict(dict, mesh1, "vcz1", 2); intern_add_mesh_to_dict(dict, mesh1, "rad1", 3); intern_add_mesh_to_dict(dict, mesh1, "grx1", 4); intern_add_mesh_to_dict(dict, mesh1, "gry1", 5); intern_add_mesh_to_dict(dict, mesh1, "grz1", 6); intern_add_mesh_to_dict(dict, mesh1, "fr1", 7); intern_add_mesh_to_dict(dict, mesh1, "slump1", 8); intern_add_mesh_to_dict(dict, mesh1, "glump1", 9); intern_add_mesh_to_dict(dict, mesh1, "gmag1", 10); intern_add_mesh_to_dict(dict, mesh1, "glog1", 11); intern_add_mesh_to_dict(dict, mesh1, "csbt1", 12); intern_add_mesh_to_dict(dict, mesh1, "tloc1", 13); intern_add_mesh_to_dict(dict, mesh1, "Inorm1", 14); intern_add_mesh_to_dict(dict, mesh2, "vcx2", 0); intern_add_mesh_to_dict(dict, mesh2, "vcy2", 1); intern_add_mesh_to_dict(dict, mesh2, "vcz2", 2); intern_add_mesh_to_dict(dict, mesh2, "rad2", 3); intern_add_mesh_to_dict(dict, mesh2, "grx2", 4); intern_add_mesh_to_dict(dict, mesh2, "gry2", 5); intern_add_mesh_to_dict(dict, mesh2, "grz2", 6); intern_add_mesh_to_dict(dict, mesh2, "fr2", 7); intern_add_mesh_to_dict(dict, mesh2, "slump2", 8); intern_add_mesh_to_dict(dict, mesh2, "glump2", 9); intern_add_mesh_to_dict(dict, mesh2, "gmag2", 10); intern_add_mesh_to_dict(dict, mesh2, "glog2", 11); intern_add_mesh_to_dict(dict, mesh2, "csbt2", 12); intern_add_mesh_to_dict(dict, mesh2, "tloc2", 13); intern_add_mesh_to_dict(dict, mesh2, "Inorm2", 14); PyTuple_SetItem(combo, 1, dict); } if (hswitch) { PyObject *dict = PyDict_New(); intern_add_horizon_to_dict(dict, horizon); PyTuple_SetItem(combo, 1+mswitch, dict); } phoebe_curve_free(curve); phoebe_vector_free(indep); phoebe_mesh_free(mesh1); phoebe_mesh_free(mesh2); phoebe_horizon_free(horizon); if (mswitch || hswitch) return combo; return lc; }
static PyObject* test_neighborhood_iterator(PyObject* NPY_UNUSED(self), PyObject* args) { PyObject *x, *fill, *out, *b; PyArrayObject *ax, *afill; PyArrayIterObject *itx; int i, typenum, mode, st; npy_intp bounds[NPY_MAXDIMS*2]; PyArrayNeighborhoodIterObject *niterx; if (!PyArg_ParseTuple(args, "OOOi", &x, &b, &fill, &mode)) { return NULL; } if (!PySequence_Check(b)) { return NULL; } typenum = PyArray_ObjectType(x, 0); typenum = PyArray_ObjectType(fill, typenum); ax = (PyArrayObject*)PyArray_FromObject(x, typenum, 1, 10); if (ax == NULL) { return NULL; } if (PySequence_Size(b) != 2 * PyArray_NDIM(ax)) { PyErr_SetString(PyExc_ValueError, "bounds sequence size not compatible with x input"); goto clean_ax; } out = PyList_New(0); if (out == NULL) { goto clean_ax; } itx = (PyArrayIterObject*)PyArray_IterNew(x); if (itx == NULL) { goto clean_out; } /* Compute boundaries for the neighborhood iterator */ for (i = 0; i < 2 * PyArray_NDIM(ax); ++i) { PyObject* bound; bound = PySequence_GetItem(b, i); if (bounds == NULL) { goto clean_itx; } if (!PyInt_Check(bound)) { PyErr_SetString(PyExc_ValueError, "bound not long"); Py_DECREF(bound); goto clean_itx; } bounds[i] = PyInt_AsLong(bound); Py_DECREF(bound); } /* Create the neighborhood iterator */ afill = NULL; if (mode == NPY_NEIGHBORHOOD_ITER_CONSTANT_PADDING) { afill = (PyArrayObject *)PyArray_FromObject(fill, typenum, 0, 0); if (afill == NULL) { goto clean_itx; } } niterx = (PyArrayNeighborhoodIterObject*)PyArray_NeighborhoodIterNew( (PyArrayIterObject*)itx, bounds, mode, afill); if (niterx == NULL) { goto clean_afill; } switch (typenum) { case NPY_OBJECT: st = copy_object(itx, niterx, bounds, &out); break; case NPY_INT: st = copy_int(itx, niterx, bounds, &out); break; case NPY_DOUBLE: st = copy_double(itx, niterx, bounds, &out); break; default: PyErr_SetString(PyExc_ValueError, "Type not supported"); goto clean_niterx; } if (st) { goto clean_niterx; } Py_DECREF(niterx); Py_XDECREF(afill); Py_DECREF(itx); Py_DECREF(ax); return out; clean_niterx: Py_DECREF(niterx); clean_afill: Py_XDECREF(afill); clean_itx: Py_DECREF(itx); clean_out: Py_DECREF(out); clean_ax: Py_DECREF(ax); return NULL; }
Py::Object _path_module::point_in_path_collection(const Py::Tuple& args) { args.verify_length(9); //segments, trans, clipbox, colors, linewidths, antialiaseds double x = Py::Float(args[0]); double y = Py::Float(args[1]); double radius = Py::Float(args[2]); agg::trans_affine master_transform = py_to_agg_transformation_matrix(args[3].ptr()); Py::SeqBase<Py::Object> paths = args[4]; Py::SeqBase<Py::Object> transforms_obj = args[5]; Py::SeqBase<Py::Object> offsets_obj = args[6]; agg::trans_affine offset_trans = py_to_agg_transformation_matrix(args[7].ptr()); bool filled = Py::Boolean(args[8]); PyArrayObject* offsets = (PyArrayObject*)PyArray_FromObject( offsets_obj.ptr(), PyArray_DOUBLE, 0, 2); if (!offsets || (PyArray_NDIM(offsets) == 2 && PyArray_DIM(offsets, 1) != 2) || (PyArray_NDIM(offsets) == 1 && PyArray_DIM(offsets, 0) != 0)) { Py_XDECREF(offsets); throw Py::ValueError("Offsets array must be Nx2"); } size_t Npaths = paths.length(); size_t Noffsets = offsets->dimensions[0]; size_t N = std::max(Npaths, Noffsets); size_t Ntransforms = std::min(transforms_obj.length(), N); size_t i; // Convert all of the transforms up front typedef std::vector<agg::trans_affine> transforms_t; transforms_t transforms; transforms.reserve(Ntransforms); for (i = 0; i < Ntransforms; ++i) { agg::trans_affine trans = py_to_agg_transformation_matrix (transforms_obj[i].ptr(), false); trans *= master_transform; transforms.push_back(trans); } Py::List result; agg::trans_affine trans; for (i = 0; i < N; ++i) { PathIterator path(paths[i % Npaths]); if (Ntransforms) { trans = transforms[i % Ntransforms]; } else { trans = master_transform; } if (Noffsets) { double xo = *(double*)PyArray_GETPTR2(offsets, i % Noffsets, 0); double yo = *(double*)PyArray_GETPTR2(offsets, i % Noffsets, 1); offset_trans.transform(&xo, &yo); trans *= agg::trans_affine_translation(xo, yo); } if (filled) { if (::point_in_path(x, y, path, trans)) result.append(Py::Int((int)i)); } else { if (::point_on_path(x, y, radius, path, trans)) result.append(Py::Int((int)i)); } } return result; }
Py::Object _path_module::affine_transform(const Py::Tuple& args) { args.verify_length(2); Py::Object vertices_obj = args[0]; Py::Object transform_obj = args[1]; PyArrayObject* vertices = NULL; PyArrayObject* transform = NULL; PyArrayObject* result = NULL; try { vertices = (PyArrayObject*)PyArray_FromObject (vertices_obj.ptr(), PyArray_DOUBLE, 1, 2); if (!vertices || (PyArray_NDIM(vertices) == 2 && PyArray_DIM(vertices, 0) != 0 && PyArray_DIM(vertices, 1) != 2) || (PyArray_NDIM(vertices) == 1 && PyArray_DIM(vertices, 0) != 2 && PyArray_DIM(vertices, 0) != 0)) { throw Py::ValueError("Invalid vertices array."); } transform = (PyArrayObject*) PyArray_FromObject (transform_obj.ptr(), PyArray_DOUBLE, 2, 2); if (!transform || PyArray_DIM(transform, 0) != 3 || PyArray_DIM(transform, 1) != 3) { throw Py::ValueError("Invalid transform."); } double a, b, c, d, e, f; { size_t stride0 = PyArray_STRIDE(transform, 0); size_t stride1 = PyArray_STRIDE(transform, 1); char* row0 = PyArray_BYTES(transform); char* row1 = row0 + stride0; a = *(double*)(row0); row0 += stride1; c = *(double*)(row0); row0 += stride1; e = *(double*)(row0); b = *(double*)(row1); row1 += stride1; d = *(double*)(row1); row1 += stride1; f = *(double*)(row1); } result = (PyArrayObject*)PyArray_SimpleNew (PyArray_NDIM(vertices), PyArray_DIMS(vertices), PyArray_DOUBLE); if (result == NULL) { throw Py::MemoryError("Could not allocate memory for path"); } if (PyArray_NDIM(vertices) == 2) { size_t n = PyArray_DIM(vertices, 0); char* vertex_in = PyArray_BYTES(vertices); double* vertex_out = (double*)PyArray_DATA(result); size_t stride0 = PyArray_STRIDE(vertices, 0); size_t stride1 = PyArray_STRIDE(vertices, 1); double x; double y; for (size_t i = 0; i < n; ++i) { x = *(double*)(vertex_in); y = *(double*)(vertex_in + stride1); *vertex_out++ = a * x + c * y + e; *vertex_out++ = b * x + d * y + f; vertex_in += stride0; } } else if (PyArray_DIM(vertices, 0) != 0) { char* vertex_in = PyArray_BYTES(vertices); double* vertex_out = (double*)PyArray_DATA(result); size_t stride0 = PyArray_STRIDE(vertices, 0); double x; double y; x = *(double*)(vertex_in); y = *(double*)(vertex_in + stride0); *vertex_out++ = a * x + c * y + e; *vertex_out++ = b * x + d * y + f; } } catch (...) { Py_XDECREF(vertices); Py_XDECREF(transform); Py_XDECREF(result); throw; } Py_XDECREF(vertices); Py_XDECREF(transform); return Py::Object((PyObject*)result, true); }
Py::Object _path_module::update_path_extents(const Py::Tuple& args) { args.verify_length(5); double x0, y0, x1, y1; PathIterator path(args[0]); agg::trans_affine trans = py_to_agg_transformation_matrix( args[1].ptr(), false); if (!py_convert_bbox(args[2].ptr(), x0, y0, x1, y1)) { throw Py::ValueError( "Must pass Bbox object as arg 3 of update_path_extents"); } Py::Object minpos_obj = args[3]; bool ignore = Py::Boolean(args[4]); double xm, ym; PyArrayObject* input_minpos = NULL; try { input_minpos = (PyArrayObject*)PyArray_FromObject( minpos_obj.ptr(), PyArray_DOUBLE, 1, 1); if (!input_minpos || PyArray_DIM(input_minpos, 0) != 2) { throw Py::TypeError( "Argument 4 to update_path_extents must be a length-2 numpy array."); } xm = *(double*)PyArray_GETPTR1(input_minpos, 0); ym = *(double*)PyArray_GETPTR1(input_minpos, 1); } catch (...) { Py_XDECREF(input_minpos); throw; } Py_XDECREF(input_minpos); npy_intp extent_dims[] = { 2, 2, 0 }; double* extents_data = NULL; npy_intp minpos_dims[] = { 2, 0 }; double* minpos_data = NULL; PyArrayObject* extents = NULL; PyArrayObject* minpos = NULL; bool changed = false; try { extents = (PyArrayObject*)PyArray_SimpleNew (2, extent_dims, PyArray_DOUBLE); if (extents == NULL) { throw Py::MemoryError("Could not allocate result array"); } minpos = (PyArrayObject*)PyArray_SimpleNew (1, minpos_dims, PyArray_DOUBLE); if (minpos == NULL) { throw Py::MemoryError("Could not allocate result array"); } extents_data = (double*)PyArray_DATA(extents); minpos_data = (double*)PyArray_DATA(minpos); if (ignore) { extents_data[0] = std::numeric_limits<double>::infinity(); extents_data[1] = std::numeric_limits<double>::infinity(); extents_data[2] = -std::numeric_limits<double>::infinity(); extents_data[3] = -std::numeric_limits<double>::infinity(); minpos_data[0] = std::numeric_limits<double>::infinity(); minpos_data[1] = std::numeric_limits<double>::infinity(); } else { if (x0 > x1) { extents_data[0] = std::numeric_limits<double>::infinity(); extents_data[2] = -std::numeric_limits<double>::infinity(); } else { extents_data[0] = x0; extents_data[2] = x1; } if (y0 > y1) { extents_data[1] = std::numeric_limits<double>::infinity(); extents_data[3] = -std::numeric_limits<double>::infinity(); } else { extents_data[1] = y0; extents_data[3] = y1; } minpos_data[0] = xm; minpos_data[1] = ym; } ::get_path_extents(path, trans, &extents_data[0], &extents_data[1], &extents_data[2], &extents_data[3], &minpos_data[0], &minpos_data[1]); changed = (extents_data[0] != x0 || extents_data[1] != y0 || extents_data[2] != x1 || extents_data[3] != y1 || minpos_data[0] != xm || minpos_data[1] != ym); } catch (...) { Py_XDECREF(extents); Py_XDECREF(minpos); throw; } Py::Tuple result(3); result[0] = Py::Object((PyObject*) extents); result[1] = Py::Object((PyObject*) minpos); result[2] = Py::Int(changed ? 1 : 0); Py_XDECREF(extents); Py_XDECREF(minpos); return result; }
Py::Object _path_module::get_path_collection_extents(const Py::Tuple& args) { args.verify_length(5); //segments, trans, clipbox, colors, linewidths, antialiaseds agg::trans_affine master_transform = py_to_agg_transformation_matrix(args[0].ptr()); Py::SeqBase<Py::Object> paths = args[1]; Py::SeqBase<Py::Object> transforms_obj = args[2]; Py::Object offsets_obj = args[3]; agg::trans_affine offset_trans = py_to_agg_transformation_matrix(args[4].ptr(), false); PyArrayObject* offsets = NULL; double x0, y0, x1, y1, xm, ym; try { offsets = (PyArrayObject*)PyArray_FromObject( offsets_obj.ptr(), PyArray_DOUBLE, 0, 2); if (!offsets || (PyArray_NDIM(offsets) == 2 && PyArray_DIM(offsets, 1) != 2) || (PyArray_NDIM(offsets) == 1 && PyArray_DIM(offsets, 0) != 0)) { throw Py::ValueError("Offsets array must be Nx2"); } size_t Npaths = paths.length(); size_t Noffsets = offsets->dimensions[0]; size_t N = std::max(Npaths, Noffsets); size_t Ntransforms = std::min(transforms_obj.length(), N); size_t i; // Convert all of the transforms up front typedef std::vector<agg::trans_affine> transforms_t; transforms_t transforms; transforms.reserve(Ntransforms); for (i = 0; i < Ntransforms; ++i) { agg::trans_affine trans = py_to_agg_transformation_matrix (transforms_obj[i].ptr(), false); trans *= master_transform; transforms.push_back(trans); } // The offset each of those and collect the mins/maxs x0 = std::numeric_limits<double>::infinity(); y0 = std::numeric_limits<double>::infinity(); x1 = -std::numeric_limits<double>::infinity(); y1 = -std::numeric_limits<double>::infinity(); xm = std::numeric_limits<double>::infinity(); ym = std::numeric_limits<double>::infinity(); agg::trans_affine trans; for (i = 0; i < N; ++i) { PathIterator path(paths[i % Npaths]); if (Ntransforms) { trans = transforms[i % Ntransforms]; } else { trans = master_transform; } if (Noffsets) { double xo = *(double*)PyArray_GETPTR2(offsets, i % Noffsets, 0); double yo = *(double*)PyArray_GETPTR2(offsets, i % Noffsets, 1); offset_trans.transform(&xo, &yo); trans *= agg::trans_affine_translation(xo, yo); } ::get_path_extents(path, trans, &x0, &y0, &x1, &y1, &xm, &ym); } } catch (...) { Py_XDECREF(offsets); throw; } Py_XDECREF(offsets); Py::Tuple result(4); result[0] = Py::Float(x0); result[1] = Py::Float(y0); result[2] = Py::Float(x1); result[3] = Py::Float(y1); return result; }
static PyObject *Py_is_sorted(PyObject *self, PyObject *obj) { npy_intp size; bool result; PyArrayObject *array = (PyArrayObject *)PyArray_FromAny( obj, NULL, 1, 1, 0, NULL); if (array == NULL) { return NULL; } size = PyArray_DIM(array, 0); if (size < 2) { Py_DECREF(array); Py_RETURN_TRUE; } /* Handle just the most common types here, otherwise coerce to double */ switch(PyArray_TYPE(array)) { case NPY_INT: { _is_sorted_int<npy_int> is_sorted; result = is_sorted(array); } break; case NPY_LONG: { _is_sorted_int<npy_long> is_sorted; result = is_sorted(array); } break; case NPY_LONGLONG: { _is_sorted_int<npy_longlong> is_sorted; result = is_sorted(array); } break; case NPY_FLOAT: { _is_sorted<npy_float> is_sorted; result = is_sorted(array); } break; case NPY_DOUBLE: { _is_sorted<npy_double> is_sorted; result = is_sorted(array); } break; default: { Py_DECREF(array); array = (PyArrayObject *)PyArray_FromObject(obj, NPY_DOUBLE, 1, 1); if (array == NULL) { return NULL; } _is_sorted<npy_double> is_sorted; result = is_sorted(array); } } Py_DECREF(array); if (result) { Py_RETURN_TRUE; } else { Py_RETURN_FALSE; } }
static PyObject *FIRsepsym2d(PyObject *NPY_UNUSED(dummy), PyObject *args) { PyObject *image=NULL, *hrow=NULL, *hcol=NULL; PyArrayObject *a_image=NULL, *a_hrow=NULL, *a_hcol=NULL, *out=NULL; int thetype, M, N, ret; npy_intp outstrides[2], instrides[2]; if (!PyArg_ParseTuple(args, "OOO", &image, &hrow, &hcol)) return NULL; thetype = PyArray_ObjectType(image, PyArray_FLOAT); thetype = NPY_MIN(thetype, PyArray_CDOUBLE); a_image = (PyArrayObject *)PyArray_FromObject(image, thetype, 2, 2); a_hrow = (PyArrayObject *)PyArray_ContiguousFromObject(hrow, thetype, 1, 1); a_hcol = (PyArrayObject *)PyArray_ContiguousFromObject(hcol, thetype, 1, 1); if ((a_image == NULL) || (a_hrow == NULL) || (a_hcol==NULL)) goto fail; out = (PyArrayObject *)PyArray_SimpleNew(2,DIMS(a_image),thetype); if (out == NULL) goto fail; M = DIMS(a_image)[0]; N = DIMS(a_image)[1]; convert_strides(STRIDES(a_image), instrides, ELSIZE(a_image), 2); outstrides[0] = N; outstrides[1] = 1; switch (thetype) { case PyArray_FLOAT: ret = S_separable_2Dconvolve_mirror((float *)DATA(a_image), (float *)DATA(out), M, N, (float *)DATA(a_hrow), (float *)DATA(a_hcol), DIMS(a_hrow)[0], DIMS(a_hcol)[0], instrides, outstrides); break; case PyArray_DOUBLE: ret = D_separable_2Dconvolve_mirror((double *)DATA(a_image), (double *)DATA(out), M, N, (double *)DATA(a_hrow), (double *)DATA(a_hcol), DIMS(a_hrow)[0], DIMS(a_hcol)[0], instrides, outstrides); break; #ifdef __GNUC__ case PyArray_CFLOAT: ret = C_separable_2Dconvolve_mirror((__complex__ float *)DATA(a_image), (__complex__ float *)DATA(out), M, N, (__complex__ float *)DATA(a_hrow), (__complex__ float *)DATA(a_hcol), DIMS(a_hrow)[0], DIMS(a_hcol)[0], instrides, outstrides); break; case PyArray_CDOUBLE: ret = Z_separable_2Dconvolve_mirror((__complex__ double *)DATA(a_image), (__complex__ double *)DATA(out), M, N, (__complex__ double *)DATA(a_hrow), (__complex__ double *)DATA(a_hcol), DIMS(a_hrow)[0], DIMS(a_hcol)[0], instrides, outstrides); break; #endif default: PYERR("Incorrect type."); } if (ret < 0) PYERR("Problem occured inside routine."); Py_DECREF(a_image); Py_DECREF(a_hrow); Py_DECREF(a_hcol); return PyArray_Return(out); fail: Py_XDECREF(a_image); Py_XDECREF(a_hrow); Py_XDECREF(a_hcol); Py_XDECREF(out); return NULL; }
static PyObject* PyUnits_convert( PyUnits* self, PyObject* args, PyObject* kwds) { int status = 1; PyObject* input = NULL; PyArrayObject* input_arr = NULL; PyArrayObject* output_arr = NULL; PyObject* input_iter = NULL; PyObject* output_iter = NULL; double input_val; double output_val; if (!PyArg_ParseTuple(args, "O:UnitConverter.convert", &input)) { goto exit; } input_arr = (PyArrayObject*)PyArray_FromObject( input, NPY_DOUBLE, 0, NPY_MAXDIMS); if (input_arr == NULL) { goto exit; } output_arr = (PyArrayObject*)PyArray_SimpleNew( PyArray_NDIM(input_arr), PyArray_DIMS(input_arr), PyArray_DOUBLE); if (output_arr == NULL) { goto exit; } input_iter = PyArray_IterNew((PyObject*)input_arr); if (input_iter == NULL) { goto exit; } output_iter = PyArray_IterNew((PyObject*)output_arr); if (output_iter == NULL) { goto exit; } if (self->power != 1.0) { while (PyArray_ITER_NOTDONE(input_iter)) { input_val = *(double *)PyArray_ITER_DATA(input_iter); output_val = pow(self->scale*input_val + self->offset, self->power); if (errno) { PyErr_SetFromErrno(PyExc_ValueError); goto exit; } *(double *)PyArray_ITER_DATA(output_iter) = output_val; PyArray_ITER_NEXT(input_iter); PyArray_ITER_NEXT(output_iter); } } else { while (PyArray_ITER_NOTDONE(input_iter)) { input_val = *(double *)PyArray_ITER_DATA(input_iter); output_val = self->scale*input_val + self->offset; *(double *)PyArray_ITER_DATA(output_iter) = output_val; PyArray_ITER_NEXT(input_iter); PyArray_ITER_NEXT(output_iter); } } status = 0; exit: Py_XDECREF((PyObject*)input_arr); Py_XDECREF(input_iter); Py_XDECREF(output_iter); if (status) { Py_XDECREF((PyObject*)output_arr); return NULL; } return (PyObject*)output_arr; }
/* * Returns input array with values inserted sequentially into places * indicated by the mask */ NPY_NO_EXPORT PyObject * arr_insert(PyObject *NPY_UNUSED(self), PyObject *args, PyObject *kwdict) { PyObject *mask = NULL, *vals = NULL; PyArrayObject *ainput = NULL, *amask = NULL, *avals = NULL, *tmp = NULL; int numvals, totmask, sameshape; char *input_data, *mptr, *vptr, *zero = NULL; int melsize, delsize, nd, objarray, k; npy_intp *instrides, *inshape; static char *kwlist[] = {"input", "mask", "vals", NULL}; if (!PyArg_ParseTupleAndKeywords(args, kwdict, "O&OO", kwlist, PyArray_Converter, &ainput, &mask, &vals)) { goto fail; } amask = (PyArrayObject *)PyArray_FROM_OF(mask, NPY_ARRAY_CARRAY); if (amask == NULL) { goto fail; } /* Cast an object array */ if (PyArray_DESCR(amask)->type_num == NPY_OBJECT) { tmp = (PyArrayObject *)PyArray_Cast(amask, NPY_INTP); if (tmp == NULL) { goto fail; } Py_DECREF(amask); amask = tmp; } sameshape = 1; if (PyArray_NDIM(amask) == PyArray_NDIM(ainput)) { for (k = 0; k < PyArray_NDIM(amask); k++) { if (PyArray_DIMS(amask)[k] != PyArray_DIMS(ainput)[k]) { sameshape = 0; } } } else { /* Test to see if amask is 1d */ if (PyArray_NDIM(amask) != 1) { sameshape = 0; } else if ((PyArray_SIZE(ainput)) != PyArray_SIZE(amask)) { sameshape = 0; } } if (!sameshape) { PyErr_SetString(PyExc_TypeError, "mask array must be 1-d or same shape as input array"); goto fail; } avals = (PyArrayObject *)PyArray_FromObject(vals, PyArray_DESCR(ainput)->type_num, 0, 1); if (avals == NULL) { goto fail; } numvals = PyArray_SIZE(avals); nd = PyArray_NDIM(ainput); input_data = PyArray_DATA(ainput); mptr = PyArray_DATA(amask); melsize = PyArray_DESCR(amask)->elsize; vptr = PyArray_DATA(avals); delsize = PyArray_DESCR(avals)->elsize; zero = PyArray_Zero(amask); if (zero == NULL) { goto fail; } objarray = (PyArray_DESCR(ainput)->type_num == NPY_OBJECT); if (!numvals) { /* nothing to insert! fail unless none of mask is true */ const char *iter = mptr; const char *const last = iter + PyArray_NBYTES(amask); while (iter != last && !memcmp(iter, zero, melsize)) { iter += melsize; } if (iter != last) { PyErr_SetString(PyExc_ValueError, "Cannot insert from an empty array!"); goto fail; } goto finish; } /* Handle zero-dimensional case separately */ if (nd == 0) { if (memcmp(mptr,zero,melsize) != 0) { /* Copy value element over to input array */ memcpy(input_data,vptr,delsize); if (objarray) { Py_INCREF(*((PyObject **)vptr)); } } Py_DECREF(amask); Py_DECREF(avals); PyDataMem_FREE(zero); Py_DECREF(ainput); Py_RETURN_NONE; } totmask = (int) PyArray_SIZE(amask); instrides = PyArray_STRIDES(ainput); inshape = PyArray_DIMS(ainput); if (objarray) { /* object array, need to refcount, can't release the GIL */ arr_insert_loop(mptr, vptr, input_data, zero, PyArray_DATA(avals), melsize, delsize, objarray, totmask, numvals, nd, instrides, inshape); } else { /* No increfs take place in arr_insert_loop, so release the GIL */ NPY_BEGIN_ALLOW_THREADS; arr_insert_loop(mptr, vptr, input_data, zero, PyArray_DATA(avals), melsize, delsize, objarray, totmask, numvals, nd, instrides, inshape); NPY_END_ALLOW_THREADS; } finish: Py_DECREF(amask); Py_DECREF(avals); PyDataMem_FREE(zero); Py_DECREF(ainput); Py_RETURN_NONE; fail: PyDataMem_FREE(zero); Py_XDECREF(ainput); Py_XDECREF(amask); Py_XDECREF(avals); return NULL; }
static PyObject *IIRsymorder1(PyObject *NPY_UNUSED(dummy), PyObject *args) { PyObject *sig=NULL; PyArrayObject *a_sig=NULL, *out=NULL; Py_complex c0, z1; double precision = -1.0; int thetype, N, ret; npy_intp outstrides, instrides; if (!PyArg_ParseTuple(args, "ODD|d", &sig, &c0, &z1, &precision)) return NULL; thetype = PyArray_ObjectType(sig, PyArray_FLOAT); thetype = NPY_MIN(thetype, PyArray_CDOUBLE); a_sig = (PyArrayObject *)PyArray_FromObject(sig, thetype, 1, 1); if ((a_sig == NULL)) goto fail; out = (PyArrayObject *)PyArray_SimpleNew(1,DIMS(a_sig),thetype); if (out == NULL) goto fail; N = DIMS(a_sig)[0]; convert_strides(STRIDES(a_sig), &instrides, ELSIZE(a_sig), 1); outstrides = 1; switch (thetype) { case PyArray_FLOAT: { float rc0 = c0.real; float rz1 = z1.real; if ((precision <= 0.0) || (precision > 1.0)) precision = 1e-6; ret = S_IIR_forback1 (rc0, rz1, (float *)DATA(a_sig), (float *)DATA(out), N, instrides, outstrides, (float )precision); } break; case PyArray_DOUBLE: { double rc0 = c0.real; double rz1 = z1.real; if ((precision <= 0.0) || (precision > 1.0)) precision = 1e-11; ret = D_IIR_forback1 (rc0, rz1, (double *)DATA(a_sig), (double *)DATA(out), N, instrides, outstrides, precision); } break; #ifdef __GNUC__ case PyArray_CFLOAT: { __complex__ float zc0 = c0.real + 1.0i*c0.imag; __complex__ float zz1 = z1.real + 1.0i*z1.imag; if ((precision <= 0.0) || (precision > 1.0)) precision = 1e-6; ret = C_IIR_forback1 (zc0, zz1, (__complex__ float *)DATA(a_sig), (__complex__ float *)DATA(out), N, instrides, outstrides, (float )precision); } break; case PyArray_CDOUBLE: { __complex__ double zc0 = c0.real + 1.0i*c0.imag; __complex__ double zz1 = z1.real + 1.0i*z1.imag; if ((precision <= 0.0) || (precision > 1.0)) precision = 1e-11; ret = Z_IIR_forback1 (zc0, zz1, (__complex__ double *)DATA(a_sig), (__complex__ double *)DATA(out), N, instrides, outstrides, precision); } break; #endif default: PYERR("Incorrect type."); } if (ret == 0) { Py_DECREF(a_sig); return PyArray_Return(out); } if (ret == -1) PYERR("Could not allocate enough memory."); if (ret == -2) PYERR("|z1| must be less than 1.0"); if (ret == -3) PYERR("Sum to find symmetric boundary conditions did not converge."); PYERR("Unknown error."); fail: Py_XDECREF(a_sig); Py_XDECREF(out); return NULL; }