static PyObject* libtfr_stft(PyObject *self, PyObject *args) { /* arguments */ PyObject *o = NULL; PyArrayObject *signal = NULL; PyArrayObject *signal_cast = NULL; PyObject *o2 = NULL; PyArrayObject *window = NULL; int step; int N = 0; int Npoints, Ntapers; /* output data */ npy_intp out_shape[3]; PyArrayObject *outdata = NULL; int do_complex = 0; double *spec; complex double *zspec_tmp; npy_cdouble *zspec; /* internal stuff */ mfft *mtmh; double *samples = NULL; double *windowp; /* parse arguments */ if (!PyArg_ParseTuple(args, "OOi|ii", &o, &o2, &step, &N, &do_complex)) return NULL; signal = (PyArrayObject*) PyArray_FromAny(o, NULL, 1, 1, NPY_CONTIGUOUS, NULL); if (signal==NULL) { PyErr_SetString(PyExc_TypeError, "Input signal must be an ndarray"); return NULL; } window = (PyArrayObject*) PyArray_FromAny(o2, NULL, 1, 2, NPY_CONTIGUOUS, NULL); if (window==NULL) { PyErr_SetString(PyExc_TypeError, "Window must be a 1D or 2D ndarray"); goto fail; } /* determine dimensions of window */ if (PyArray_NDIM(window)==1) { Ntapers = 1; Npoints = PyArray_DIM(window, 0); } else { Ntapers = PyArray_DIM(window, 0); Npoints = PyArray_DIM(window, 1); } /* coerce data to proper type */ samples = coerce_ndarray_double(signal, &signal_cast); if (samples==NULL) { PyErr_SetString(PyExc_TypeError, "Unable to cast signal to supported data type"); goto fail; } /* need to copy the window function b/c mtm_destroy() will demalloc it */ if (PyArray_TYPE(window)!=NPY_DOUBLE) { PyErr_SetString(PyExc_TypeError, "Window function must be double precision float"); goto fail; } windowp = malloc(Npoints * Ntapers * sizeof(double)); memcpy(windowp, PyArray_DATA(window), Npoints * Ntapers * sizeof(double)); /* allocate outputs and do the transform */ if (N < 1) N = Npoints; mtmh = mtm_init(N, Npoints, Ntapers, windowp, NULL); out_shape[0] = N/2+1; if (do_complex) { out_shape[1] = Ntapers; out_shape[2] = SPEC_NFRAMES(mtmh, PyArray_SIZE(signal), step); outdata = (PyArrayObject*) PyArray_ZEROS(3,out_shape,NPY_CDOUBLE,1); // fortran-order zspec = (npy_cdouble*) PyArray_DATA(outdata); //printf("output dimensions: %d, %d, %d\n", out_shape[0], out_shape[1], out_shape[2]); zspec_tmp = (complex double*)malloc(PyArray_SIZE(outdata) * sizeof(complex double)); mtm_zspec(mtmh, zspec_tmp, samples, PyArray_SIZE(signal), step); cmplx_c99tonpy(zspec_tmp, zspec, PyArray_SIZE(outdata)); free(zspec_tmp); } else { out_shape[1] = SPEC_NFRAMES(mtmh, PyArray_SIZE(signal), step); outdata = (PyArrayObject*) PyArray_ZEROS(2,out_shape,NPY_DOUBLE,1); // fortran-order spec = (double*) PyArray_DATA(outdata); mtm_spec(mtmh, spec, samples, PyArray_SIZE(signal), step, 0); } mtm_destroy(mtmh); Py_DECREF(signal); Py_DECREF(window); Py_XDECREF(signal_cast); return PyArray_Return(outdata); fail: Py_XDECREF(signal_cast); Py_XDECREF(signal); Py_XDECREF(window); Py_XDECREF(outdata); return NULL; }
NPY_NO_EXPORT PyObject * __New_PyArray_Std(PyArrayObject *self, int axis, int rtype, PyArrayObject *out, int variance, int num) { PyObject *obj1 = NULL, *obj2 = NULL, *obj3 = NULL; PyArrayObject *arr1 = NULL, *arr2 = NULL, *arrnew = NULL; PyObject *ret = NULL, *newshape = NULL; int i, n; npy_intp val; arrnew = (PyArrayObject *)PyArray_CheckAxis(self, &axis, 0); if (arrnew == NULL) { return NULL; } /* Compute and reshape mean */ arr1 = (PyArrayObject *)PyArray_EnsureAnyArray( PyArray_Mean(arrnew, axis, rtype, NULL)); if (arr1 == NULL) { Py_DECREF(arrnew); return NULL; } n = PyArray_NDIM(arrnew); newshape = PyTuple_New(n); if (newshape == NULL) { Py_DECREF(arr1); Py_DECREF(arrnew); return NULL; } for (i = 0; i < n; i++) { if (i == axis) { val = 1; } else { val = PyArray_DIM(arrnew,i); } PyTuple_SET_ITEM(newshape, i, PyInt_FromLong((long)val)); } arr2 = (PyArrayObject *)PyArray_Reshape(arr1, newshape); Py_DECREF(arr1); Py_DECREF(newshape); if (arr2 == NULL) { Py_DECREF(arrnew); return NULL; } /* Compute x = x - mx */ arr1 = (PyArrayObject *)PyArray_EnsureAnyArray( PyNumber_Subtract((PyObject *)arrnew, (PyObject *)arr2)); Py_DECREF(arr2); if (arr1 == NULL) { Py_DECREF(arrnew); return NULL; } /* Compute x * x */ if (PyArray_ISCOMPLEX(arr1)) { obj3 = PyArray_Conjugate(arr1, NULL); } else { obj3 = (PyObject *)arr1; Py_INCREF(arr1); } if (obj3 == NULL) { Py_DECREF(arrnew); return NULL; } arr2 = (PyArrayObject *)PyArray_EnsureAnyArray( PyArray_GenericBinaryFunction(arr1, obj3, n_ops.multiply)); Py_DECREF(arr1); Py_DECREF(obj3); if (arr2 == NULL) { Py_DECREF(arrnew); return NULL; } if (PyArray_ISCOMPLEX(arr2)) { obj3 = PyObject_GetAttrString((PyObject *)arr2, "real"); switch(rtype) { case NPY_CDOUBLE: rtype = NPY_DOUBLE; break; case NPY_CFLOAT: rtype = NPY_FLOAT; break; case NPY_CLONGDOUBLE: rtype = NPY_LONGDOUBLE; break; } } else { obj3 = (PyObject *)arr2; Py_INCREF(arr2); } if (obj3 == NULL) { Py_DECREF(arrnew); return NULL; } /* Compute add.reduce(x*x,axis) */ obj1 = PyArray_GenericReduceFunction((PyArrayObject *)obj3, n_ops.add, axis, rtype, NULL); Py_DECREF(obj3); Py_DECREF(arr2); if (obj1 == NULL) { Py_DECREF(arrnew); return NULL; } n = PyArray_DIM(arrnew,axis); Py_DECREF(arrnew); n = (n-num); if (n == 0) { n = 1; } obj2 = PyFloat_FromDouble(1.0/((double )n)); if (obj2 == NULL) { Py_DECREF(obj1); return NULL; } ret = PyNumber_Multiply(obj1, obj2); Py_DECREF(obj1); Py_DECREF(obj2); if (!variance) { arr1 = (PyArrayObject *)PyArray_EnsureAnyArray(ret); /* sqrt() */ ret = PyArray_GenericUnaryFunction(arr1, n_ops.sqrt); Py_DECREF(arr1); } if (ret == NULL) { return NULL; } if (PyArray_CheckExact(self)) { goto finish; } if (PyArray_Check(self) && Py_TYPE(self) == Py_TYPE(ret)) { goto finish; } arr1 = (PyArrayObject *)PyArray_EnsureArray(ret); if (arr1 == NULL) { return NULL; } ret = PyArray_View(arr1, NULL, Py_TYPE(self)); Py_DECREF(arr1); finish: if (out) { if (PyArray_AssignArray(out, (PyArrayObject *)ret, NULL, NPY_DEFAULT_ASSIGN_CASTING) < 0) { Py_DECREF(ret); return NULL; } Py_DECREF(ret); Py_INCREF(out); return (PyObject *)out; } return ret; }
/*NUMPY_API * Round */ NPY_NO_EXPORT PyObject * PyArray_Round(PyArrayObject *a, int decimals, PyArrayObject *out) { PyObject *f, *ret = NULL, *tmp, *op1, *op2; int ret_int=0; PyArray_Descr *my_descr; if (out && (PyArray_SIZE(out) != PyArray_SIZE(a))) { PyErr_SetString(PyExc_ValueError, "invalid output shape"); return NULL; } if (PyArray_ISCOMPLEX(a)) { PyObject *part; PyObject *round_part; PyObject *arr; int res; if (out) { arr = (PyObject *)out; Py_INCREF(arr); } else { arr = PyArray_Copy(a); if (arr == NULL) { return NULL; } } /* arr.real = a.real.round(decimals) */ part = PyObject_GetAttrString(arr, "real"); if (part == NULL) { Py_DECREF(arr); return NULL; } part = PyArray_EnsureAnyArray(part); round_part = PyArray_Round((PyArrayObject *)part, decimals, NULL); Py_DECREF(part); if (round_part == NULL) { Py_DECREF(arr); return NULL; } res = PyObject_SetAttrString(arr, "real", round_part); Py_DECREF(round_part); if (res < 0) { Py_DECREF(arr); return NULL; } /* arr.imag = a.imag.round(decimals) */ part = PyObject_GetAttrString(arr, "imag"); if (part == NULL) { Py_DECREF(arr); return NULL; } part = PyArray_EnsureAnyArray(part); round_part = PyArray_Round((PyArrayObject *)part, decimals, NULL); Py_DECREF(part); if (round_part == NULL) { Py_DECREF(arr); return NULL; } res = PyObject_SetAttrString(arr, "imag", round_part); Py_DECREF(round_part); if (res < 0) { Py_DECREF(arr); return NULL; } return arr; } /* do the most common case first */ if (decimals >= 0) { if (PyArray_ISINTEGER(a)) { if (out) { if (PyArray_AssignArray(out, a, NULL, NPY_DEFAULT_ASSIGN_CASTING) < 0) { return NULL; } Py_INCREF(out); return (PyObject *)out; } else { Py_INCREF(a); return (PyObject *)a; } } if (decimals == 0) { if (out) { return PyObject_CallFunction(n_ops.rint, "OO", a, out); } return PyObject_CallFunction(n_ops.rint, "O", a); } op1 = n_ops.multiply; op2 = n_ops.true_divide; } else { op1 = n_ops.true_divide; op2 = n_ops.multiply; decimals = -decimals; } if (!out) { if (PyArray_ISINTEGER(a)) { ret_int = 1; my_descr = PyArray_DescrFromType(NPY_DOUBLE); } else { Py_INCREF(PyArray_DESCR(a)); my_descr = PyArray_DESCR(a); } out = (PyArrayObject *)PyArray_Empty(PyArray_NDIM(a), PyArray_DIMS(a), my_descr, PyArray_ISFORTRAN(a)); if (out == NULL) { return NULL; } } else { Py_INCREF(out); } f = PyFloat_FromDouble(power_of_ten(decimals)); if (f == NULL) { return NULL; } ret = PyObject_CallFunction(op1, "OOO", a, f, out); if (ret == NULL) { goto finish; } tmp = PyObject_CallFunction(n_ops.rint, "OO", ret, ret); if (tmp == NULL) { Py_DECREF(ret); ret = NULL; goto finish; } Py_DECREF(tmp); tmp = PyObject_CallFunction(op2, "OOO", ret, f, ret); if (tmp == NULL) { Py_DECREF(ret); ret = NULL; goto finish; } Py_DECREF(tmp); finish: Py_DECREF(f); Py_DECREF(out); if (ret_int) { Py_INCREF(PyArray_DESCR(a)); tmp = PyArray_CastToType((PyArrayObject *)ret, PyArray_DESCR(a), PyArray_ISFORTRAN(a)); Py_DECREF(ret); return tmp; } return ret; }
int NI_FourierShift(PyArrayObject *input, PyArrayObject* shift_array, npy_intp n, int axis, PyArrayObject* output) { NI_Iterator ii, io; char *pi, *po; double *shifts = NULL, **params = NULL; npy_intp kk, hh, size; npy_double *ishifts = (void *)PyArray_DATA(shift_array); NPY_BEGIN_THREADS_DEF; /* precalculate the shifts: */ shifts = malloc(PyArray_NDIM(input) * sizeof(double)); if (!shifts) { PyErr_NoMemory(); goto exit; } for (kk = 0; kk < PyArray_NDIM(input); kk++) { /* along the direction of the real transform we must use the given length of that dimensons, unless a complex transform is assumed (n < 0): */ int shape = kk == axis ? (n < 0 ? PyArray_DIM(input, kk) : n) : PyArray_DIM(input, kk); shifts[kk] = -2.0 * M_PI * *ishifts++ / (double)shape; } /* allocate memory for tables: */ params = malloc(PyArray_NDIM(input) * sizeof(double*)); if (!params) { PyErr_NoMemory(); goto exit; } for (kk = 0; kk < PyArray_NDIM(input); kk++) { params[kk] = NULL; } for (kk = 0; kk < PyArray_NDIM(input); kk++) { if (PyArray_DIM(input, kk) > 1) { params[kk] = malloc(PyArray_DIM(input, kk) * sizeof(double)); if (!params[kk]) { PyErr_NoMemory(); goto exit; } } } NPY_BEGIN_THREADS; for (hh = 0; hh < PyArray_NDIM(input); hh++) { if (params[hh]) { if (hh == axis && n >= 0) { for (kk = 0; kk < PyArray_DIM(input, hh); kk++) { params[hh][kk] = shifts[hh] * kk; } } else { int jj = 0; for (kk = 0; kk < (PyArray_DIM(input, hh) + 1) / 2; kk++) { params[hh][jj++] = shifts[hh] * kk; } for (kk = -(PyArray_DIM(input, hh) / 2); kk < 0; kk++) { params[hh][jj++] = shifts[hh] * kk; } } } } /* initialize input element iterator: */ if (!NI_InitPointIterator(input, &ii)) goto exit; /* initialize output element iterator: */ if (!NI_InitPointIterator(output, &io)) goto exit; pi = (void *)PyArray_DATA(input); po = (void *)PyArray_DATA(output); size = PyArray_SIZE(input); /* iterator over the elements: */ for(hh = 0; hh < size; hh++) { double tmp = 0.0, sint, cost, r = 0.0, i = 0.0; for (kk = 0; kk < PyArray_NDIM(input); kk++) { if (params[kk]) tmp += params[kk][ii.coordinates[kk]]; } sint = sin(tmp); cost = cos(tmp); switch (PyArray_TYPE(input)) { CASE_FOURIER_SHIFT_R(NPY_BOOL, npy_bool, pi, tmp, r, i, cost, sint); CASE_FOURIER_SHIFT_R(NPY_UBYTE, npy_ubyte, pi, tmp, r, i, cost, sint); CASE_FOURIER_SHIFT_R(NPY_USHORT, npy_ushort, pi, tmp, r, i, cost, sint); CASE_FOURIER_SHIFT_R(NPY_UINT, npy_uint, pi, tmp, r, i, cost, sint); CASE_FOURIER_SHIFT_R(NPY_ULONG, npy_ulong, pi, tmp, r, i, cost, sint); CASE_FOURIER_SHIFT_R(NPY_ULONGLONG, npy_ulonglong, pi, tmp, r, i, cost, sint); CASE_FOURIER_SHIFT_R(NPY_BYTE, npy_byte, pi, tmp, r, i, cost, sint); CASE_FOURIER_SHIFT_R(NPY_SHORT, npy_short, pi, tmp, r, i, cost, sint); CASE_FOURIER_SHIFT_R(NPY_INT, npy_int, pi, tmp, r, i, cost, sint); CASE_FOURIER_SHIFT_R(NPY_LONG, npy_long, pi, tmp, r, i, cost, sint); CASE_FOURIER_SHIFT_R(NPY_LONGLONG, npy_longlong, pi, tmp, r, i, cost, sint); CASE_FOURIER_SHIFT_R(NPY_FLOAT, npy_float, pi, tmp, r, i, cost, sint); CASE_FOURIER_SHIFT_R(NPY_DOUBLE, npy_double, pi, tmp, r, i, cost, sint); CASE_FOURIER_SHIFT_C(NPY_CFLOAT, npy_cfloat, pi, r, i, cost, sint); CASE_FOURIER_SHIFT_C(NPY_CDOUBLE, npy_cdouble, pi, r, i, cost, sint); default: NPY_END_THREADS; PyErr_SetString(PyExc_RuntimeError, "data type not supported"); goto exit; } switch (PyArray_TYPE(output)) { CASE_FOURIER_OUT_CC(NPY_CFLOAT, npy_cfloat, po, r, i); CASE_FOURIER_OUT_CC(NPY_CDOUBLE, npy_cdouble, po, r, i); default: NPY_END_THREADS; PyErr_SetString(PyExc_RuntimeError, "data type not supported"); goto exit; } NI_ITERATOR_NEXT2(ii, io, pi, po); } exit: NPY_END_THREADS; free(shifts); if (params) { for (kk = 0; kk < PyArray_NDIM(input); kk++) { free(params[kk]); } free(params); } return PyErr_Occurred() ? 0 : 1; }
static PyObject *nfft(PyObject *self, PyObject *args, PyObject *kwargs) { PyObject *in_obj, *coord_obj; static char *kwlist[] = {"real_space", "coordinates", NULL}; if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO", kwlist, &in_obj, &coord_obj)) { return NULL; } PyObject *coord_array = PyArray_FROM_OTF(coord_obj, NPY_DOUBLE, NPY_IN_ARRAY); PyObject *in_array = PyArray_FROM_OTF(in_obj, NPY_COMPLEX128, NPY_IN_ARRAY); if (coord_array == NULL || in_array == NULL) { Py_XDECREF(coord_array); Py_XDECREF(in_array); return NULL; } int ndim = PyArray_NDIM(in_array); if (ndim <= 0) { PyErr_SetString(PyExc_ValueError, "Input array can't be 0 dimensional\n"); return NULL; } if ((PyArray_NDIM(coord_array) != 2 || PyArray_DIM(coord_array, 1) != ndim) && (ndim != 1 || PyArray_NDIM(coord_array) != 1)) { PyErr_SetString(PyExc_ValueError, "Coordinates must be given as array of dimensions [NUMBER_OF_POINTS, NUMBER_OF_DIMENSIONS] of [NUMBER_OF_POINTS for 1D transforms.\n"); Py_XDECREF(coord_array); Py_XDECREF(in_array); return NULL; } int number_of_points = (int) PyArray_DIM(coord_array, 0); nfft_plan my_plan; int total_number_of_pixels = 1; int dims[ndim]; int dim; for (dim = 0; dim < ndim; ++dim) { dims[dim] = (int)PyArray_DIM(in_array, dim); total_number_of_pixels *= dims[dim]; } #if defined(ENABLE_THREADS) printf("OMP_NUM_THREADS=%s\n",getenv("OMP_NUM_THREADS")); printf("nthreads = %d\n", nfft_get_num_threads()); fftw_init_threads(); #endif nfft_init(&my_plan, ndim, dims, number_of_points); memcpy(my_plan.f_hat, PyArray_DATA(in_array), total_number_of_pixels*sizeof(fftw_complex)); memcpy(my_plan.x, PyArray_DATA(coord_array), ndim*number_of_points*sizeof(double)); if (my_plan.nfft_flags &PRE_PSI) { nfft_precompute_one_psi(&my_plan); } nfft_trafo(&my_plan); int out_dim[] = {number_of_points}; PyObject *out_array = (PyObject *)PyArray_FromDims(1, out_dim, NPY_COMPLEX128); memcpy(PyArray_DATA(out_array), my_plan.f, number_of_points*sizeof(fftw_complex)); // Clean up memory nfft_finalize(&my_plan); #if defined(ENABLE_THREADS) fftw_cleanup_threads(); #endif Py_XDECREF(coord_array); Py_XDECREF(in_array); return out_array; }
// ============================================================================= int Epetra_NumPySerialDenseVector::getVectorSize(PyObject * pyObject) { if (!tmp_array) getArray(pyObject); return (int) PyArray_MultiplyList(PyArray_DIMS(tmp_array), PyArray_NDIM(tmp_array)); }
static PyObject *spa_calc(PyObject *self, PyObject *args) { int N_IN, N_DOUBLE_IN, N_ARRAY_IN, N_DOUBLE_OUT, N_ARRAY_OUT, N; PyObject *input_obj[PYSPA_MAX_ARGS]; double input_double[PYSPA_MAX_ARGS]; PyArrayObject *input_arr[PYSPA_MAX_ARGS], *output_arr[PYSPA_MAX_ARGS]; double *input_arr_ptr[PYSPA_MAX_ARGS], *output_arr_ptr[PYSPA_MAX_ARGS]; int input_arr_map[PYSPA_MAX_ARGS], input_double_map[PYSPA_MAX_ARGS], input_type[PYSPA_MAX_ARGS]; double year=0, month=0, day=0, hour=0, minute=0, second=0, latitude=0, longitude=0, elevation=0, slope=0, aspect=0; double zenith, azimuth, incidence; double value; int flag; int i, j, ndim, dims[NPY_MAXDIMS], rc=0; spa_data spa; static const double m_air = 0.02896; // molecular mass of air, kg mol^-1 static const double R_const = 8.3143; // gas constant, N M mol^-1 K^-1 static const double g_const = 9.807; // gravity constant, m s^-2 static const double T_const = 288.15; // "default" air temperature, K /* Parse the input tuple */ for (i=0; i<64; i++) input_obj[i] = NULL; if (!PyArg_ParseTuple(args, "OOOOOOOO|OOO", &input_obj[0], &input_obj[1], &input_obj[2], &input_obj[3], &input_obj[4], &input_obj[5], &input_obj[6], &input_obj[7], &input_obj[8], &input_obj[9], &input_obj[10])) return NULL; if (input_obj[8] == NULL) { // fprintf(stderr, "Running SPA_ZA mode ...\n"); spa.function = SPA_ZA; N_IN = 8; N_DOUBLE_OUT = 0; N_ARRAY_OUT = 2; } else { // fprintf(stderr, "Running SPA_ZA_INC mode ...\n"); spa.function = SPA_ZA_INC; N_IN = 11; N_DOUBLE_OUT = 0; N_ARRAY_OUT = 3; } N_DOUBLE_IN = 0; N_ARRAY_IN = 0; for (i=0; i<N_IN; i++) { /* Interpret the input objects as numpy arrays. */ input_arr[i] = (PyArrayObject *) PyArray_FROM_OTF(input_obj[i], NPY_DOUBLE, NPY_IN_ARRAY); /* Is is really a numpy array? */ if (PyArray_NDIM(input_arr[i])==0) { input_type[i] = 0; input_double_map[N_DOUBLE_IN] = i; N_DOUBLE_IN++; input_double[i] = PyFloat_AsDouble(input_obj[i]); Py_XDECREF(input_arr[i]); } else { input_type[i] = 1; input_arr_map[N_ARRAY_IN] = i; N_ARRAY_IN++; } } /* If that didn't work, throw an exception. */ flag = 0; for (i=0; i<N_ARRAY_IN; i++) if (input_arr[input_arr_map[i]]==NULL) flag = 1; if (flag==1) { for (i=0; i<N_ARRAY_IN; i++) Py_XDECREF(input_arr[input_arr_map[i]]); return NULL; } /* Get pointers to the data as C-types. */ for (i=0; i<N_ARRAY_IN; i++) input_arr_ptr[input_arr_map[i]] = (double*) PyArray_DATA(input_arr[input_arr_map[i]]); /* How many data points are there? */ ndim = (int)PyArray_NDIM(input_arr[input_arr_map[0]]); N=1; for (j=0; j<ndim; j++) { dims[j] = PyArray_DIM(input_arr[input_arr_map[0]], j); N *= dims[j]; /* check for dimension size compatibility */ flag = 0; for (i=1; i<N_ARRAY_IN; i++) if (dims[j] != PyArray_DIM(input_arr[input_arr_map[i]], j)) flag = 1; if (flag==1) { for (i=0; i<N_ARRAY_IN; i++) Py_XDECREF(input_arr[input_arr_map[i]]); PyErr_SetString(PyExc_RuntimeError, "different dimensions of input arrays."); return NULL; } } for (i=0; i<N_ARRAY_OUT; i++) { output_arr[i] = (PyArrayObject *) PyArray_FromDims(ndim, dims, NPY_DOUBLE); output_arr_ptr[i] = (double*) PyArray_DATA(output_arr[i]); } /* Call the external C function to compute the results. */ for (j=0; j<N; j++) { for (i=0; i<N_IN; i++) { if (input_type[i] == 0) value = input_double[i]; else value = input_arr_ptr[i][j]; switch (i) { case 0: year = value; case 1: month = value; case 2: day = value; case 3: hour = value; case 4: minute = value; case 5: second = value; case 6: latitude = value; case 7: longitude = value; case 8: elevation = value; case 9: slope = value; case 10: aspect = value; } } /* some checks */ if (longitude>180) longitude -= 360; /* SPA's azm_rotation angle is measured from south and most aspect angle is measured from north */ aspect -= 180; if (aspect<-360) aspect += 360; spa.year = (int) year; spa.month = (int) month; spa.day = (int) day; spa.hour = (int) hour; spa.minute = (int) minute; spa.second = (int) second; spa.latitude = latitude; spa.longitude = longitude; spa.timezone = 0.0; spa.delta_t = 0; spa.elevation = elevation; spa.pressure = 1000*exp(-m_air*g_const*elevation/(R_const*T_const)); spa.temperature = 0; spa.slope = slope; spa.azm_rotation = aspect; spa.atmos_refract = 0.5667; rc = spa_calculate(&spa); if (rc == 0) { zenith = spa.zenith; azimuth = spa.azimuth; incidence = spa.incidence; } else { zenith = -9999; azimuth = -9999; incidence = -9999; } output_arr_ptr[0][j] = zenith; output_arr_ptr[1][j] = azimuth; if (spa.function == SPA_ZA_INC) output_arr_ptr[2][j] = incidence; } /* Clean up. */ for (i=0; i<N_ARRAY_IN; i++) Py_XDECREF(input_arr[input_arr_map[i]]); /* Build the output tuple */ if (spa.function == SPA_ZA) return Py_BuildValue("OO", output_arr[0], output_arr[1]); else return Py_BuildValue("OOO", output_arr[0], output_arr[1], output_arr[2]); }
int NI_UniformFilter1D(PyArrayObject *input, npy_intp filter_size, int axis, PyArrayObject *output, NI_ExtendMode mode, double cval, npy_intp origin) { npy_intp lines, kk, ll, length, size1, size2; int more; double *ibuffer = NULL, *obuffer = NULL; NI_LineBuffer iline_buffer, oline_buffer; NPY_BEGIN_THREADS_DEF; size1 = filter_size / 2; size2 = filter_size - size1 - 1; /* allocate and initialize the line buffers: */ lines = -1; if (!NI_AllocateLineBuffer(input, axis, size1 + origin, size2 - origin, &lines, BUFFER_SIZE, &ibuffer)) goto exit; if (!NI_AllocateLineBuffer(output, axis, 0, 0, &lines, BUFFER_SIZE, &obuffer)) goto exit; if (!NI_InitLineBuffer(input, axis, size1 + origin, size2 - origin, lines, ibuffer, mode, cval, &iline_buffer)) goto exit; if (!NI_InitLineBuffer(output, axis, 0, 0, lines, obuffer, mode, 0.0, &oline_buffer)) goto exit; NPY_BEGIN_THREADS; length = PyArray_NDIM(input) > 0 ? PyArray_DIM(input, axis) : 1; /* iterate over all the array lines: */ do { /* copy lines from array to buffer: */ if (!NI_ArrayToLineBuffer(&iline_buffer, &lines, &more)) { goto exit; } /* iterate over the lines in the buffers: */ for(kk = 0; kk < lines; kk++) { /* get lines: */ double *iline = NI_GET_LINE(iline_buffer, kk); double *oline = NI_GET_LINE(oline_buffer, kk); /* do the uniform filter: */ double tmp = 0.0; double *l1 = iline; double *l2 = iline + filter_size; for (ll = 0; ll < filter_size; ++ll) { tmp += iline[ll]; } oline[0] = tmp / filter_size; for (ll = 1; ll < length; ++ll) { tmp += *l2++ - *l1++; oline[ll] = tmp / filter_size; } } /* copy lines from buffer to array: */ if (!NI_LineBufferToArray(&oline_buffer)) { goto exit; } } while(more); exit: NPY_END_THREADS; free(ibuffer); free(obuffer); return PyErr_Occurred() ? 0 : 1; }
int NI_Correlate1D(PyArrayObject *input, PyArrayObject *weights, int axis, PyArrayObject *output, NI_ExtendMode mode, double cval, npy_intp origin) { int symmetric = 0, more; npy_intp ii, jj, ll, lines, length, size1, size2, filter_size; double *ibuffer = NULL, *obuffer = NULL; npy_double *fw; NI_LineBuffer iline_buffer, oline_buffer; NPY_BEGIN_THREADS_DEF; /* test for symmetry or anti-symmetry: */ filter_size = PyArray_SIZE(weights); size1 = filter_size / 2; size2 = filter_size - size1 - 1; fw = (void *)PyArray_DATA(weights); if (filter_size & 0x1) { symmetric = 1; for(ii = 1; ii <= filter_size / 2; ii++) { if (fabs(fw[ii + size1] - fw[size1 - ii]) > DBL_EPSILON) { symmetric = 0; break; } } if (symmetric == 0) { symmetric = -1; for(ii = 1; ii <= filter_size / 2; ii++) { if (fabs(fw[size1 + ii] + fw[size1 - ii]) > DBL_EPSILON) { symmetric = 0; break; } } } } /* allocate and initialize the line buffers: */ lines = -1; if (!NI_AllocateLineBuffer(input, axis, size1 + origin, size2 - origin, &lines, BUFFER_SIZE, &ibuffer)) goto exit; if (!NI_AllocateLineBuffer(output, axis, 0, 0, &lines, BUFFER_SIZE, &obuffer)) goto exit; if (!NI_InitLineBuffer(input, axis, size1 + origin, size2 - origin, lines, ibuffer, mode, cval, &iline_buffer)) goto exit; if (!NI_InitLineBuffer(output, axis, 0, 0, lines, obuffer, mode, 0.0, &oline_buffer)) goto exit; NPY_BEGIN_THREADS; length = PyArray_NDIM(input) > 0 ? PyArray_DIM(input, axis) : 1; fw += size1; /* iterate over all the array lines: */ do { /* copy lines from array to buffer: */ if (!NI_ArrayToLineBuffer(&iline_buffer, &lines, &more)) { goto exit; } /* iterate over the lines in the buffers: */ for(ii = 0; ii < lines; ii++) { /* get lines: */ double *iline = NI_GET_LINE(iline_buffer, ii) + size1; double *oline = NI_GET_LINE(oline_buffer, ii); /* the correlation calculation: */ if (symmetric > 0) { for(ll = 0; ll < length; ll++) { oline[ll] = iline[0] * fw[0]; for(jj = -size1 ; jj < 0; jj++) oline[ll] += (iline[jj] + iline[-jj]) * fw[jj]; ++iline; } } else if (symmetric < 0) { for(ll = 0; ll < length; ll++) { oline[ll] = iline[0] * fw[0]; for(jj = -size1 ; jj < 0; jj++) oline[ll] += (iline[jj] - iline[-jj]) * fw[jj]; ++iline; } } else { for(ll = 0; ll < length; ll++) { oline[ll] = iline[size2] * fw[size2]; for(jj = -size1; jj < size2; jj++) oline[ll] += iline[jj] * fw[jj]; ++iline; } } } /* copy lines from buffer to array: */ if (!NI_LineBufferToArray(&oline_buffer)) { goto exit; } } while(more); exit: NPY_END_THREADS; free(ibuffer); free(obuffer); return PyErr_Occurred() ? 0 : 1; }
int NI_FindObjects(PyArrayObject* input, npy_intp max_label, npy_intp* regions) { npy_intp size, jj; NI_Iterator ii; char *pi; NPY_BEGIN_THREADS_DEF; NPY_BEGIN_THREADS; /* get input data, size and iterator: */ pi = (void *)PyArray_DATA(input); size = PyArray_SIZE(input); if (!NI_InitPointIterator(input, &ii)) goto exit; if (PyArray_NDIM(input) > 0) { for (jj = 0; jj < 2 * PyArray_NDIM(input) * max_label; jj++) { regions[jj] = -1; } } else { for(jj = 0; jj < max_label; jj++) regions[jj] = -1; } /* iterate over all points: */ for(jj = 0 ; jj < size; jj++) { switch (PyArray_TYPE(input)) { CASE_FIND_OBJECT_POINT(NPY_BOOL, npy_bool, pi, regions, input, max_label, ii); CASE_FIND_OBJECT_POINT(NPY_UBYTE, npy_ubyte, pi, regions, input, max_label, ii); CASE_FIND_OBJECT_POINT(NPY_USHORT, npy_ushort, pi, regions, input, max_label, ii); CASE_FIND_OBJECT_POINT(NPY_UINT, npy_uint, pi, regions, input, max_label, ii); CASE_FIND_OBJECT_POINT(NPY_ULONG, npy_ulong, pi, regions, input, max_label, ii); CASE_FIND_OBJECT_POINT(NPY_ULONGLONG, npy_ulonglong, pi, regions, input, max_label, ii); CASE_FIND_OBJECT_POINT(NPY_BYTE, npy_byte, pi, regions, input, max_label, ii); CASE_FIND_OBJECT_POINT(NPY_SHORT, npy_short, pi, regions, input, max_label, ii); CASE_FIND_OBJECT_POINT(NPY_INT, npy_int, pi, regions, input, max_label, ii); CASE_FIND_OBJECT_POINT(NPY_LONG, npy_long, pi, regions, input, max_label, ii); CASE_FIND_OBJECT_POINT(NPY_LONGLONG, npy_longlong, pi, regions, input, max_label, ii); CASE_FIND_OBJECT_POINT(NPY_FLOAT, npy_float, pi, regions, input, max_label, ii); CASE_FIND_OBJECT_POINT(NPY_DOUBLE, npy_double, pi, regions, input, max_label, ii); default: NPY_END_THREADS; PyErr_SetString(PyExc_RuntimeError, "data type not supported"); goto exit; } NI_ITERATOR_NEXT(ii, pi); } exit: NPY_END_THREADS; return PyErr_Occurred() ? 0 : 1; }
int NI_Correlate(PyArrayObject* input, PyArrayObject* weights, PyArrayObject* output, NI_ExtendMode mode, double cvalue, npy_intp *origins) { npy_bool *pf = NULL; npy_intp fsize, jj, kk, filter_size = 0, border_flag_value; npy_intp *offsets = NULL, *oo, size; NI_FilterIterator fi; NI_Iterator ii, io; char *pi, *po; npy_double *pw; npy_double *ww = NULL; int err = 0; NPY_BEGIN_THREADS_DEF; /* get the the footprint: */ fsize = PyArray_SIZE(weights); pw = (npy_double*)PyArray_DATA(weights); pf = malloc(fsize * sizeof(npy_bool)); if (!pf) { PyErr_NoMemory(); goto exit; } for(jj = 0; jj < fsize; jj++) { if (fabs(pw[jj]) > DBL_EPSILON) { pf[jj] = 1; ++filter_size; } else { pf[jj] = 0; } } /* copy the weights to contiguous memory: */ ww = malloc(filter_size * sizeof(npy_double)); if (!ww) { PyErr_NoMemory(); goto exit; } jj = 0; for(kk = 0; kk < fsize; kk++) { if (pf[kk]) { ww[jj++] = pw[kk]; } } /* initialize filter offsets: */ if (!NI_InitFilterOffsets(input, pf, PyArray_DIMS(weights), origins, mode, &offsets, &border_flag_value, NULL)) { goto exit; } /* initialize filter iterator: */ if (!NI_InitFilterIterator(PyArray_NDIM(input), PyArray_DIMS(weights), filter_size, PyArray_DIMS(input), origins, &fi)) { goto exit; } /* initialize input element iterator: */ if (!NI_InitPointIterator(input, &ii)) goto exit; /* initialize output element iterator: */ if (!NI_InitPointIterator(output, &io)) goto exit; NPY_BEGIN_THREADS; /* get data pointers an array size: */ pi = (void *)PyArray_DATA(input); po = (void *)PyArray_DATA(output); size = PyArray_SIZE(input); /* iterator over the elements: */ oo = offsets; for(jj = 0; jj < size; jj++) { double tmp = 0.0; switch (PyArray_TYPE(input)) { CASE_CORRELATE_POINT(NPY_BOOL, npy_bool, pi, ww, oo, filter_size, cvalue, tmp, border_flag_value); CASE_CORRELATE_POINT(NPY_UBYTE, npy_ubyte, pi, ww, oo, filter_size, cvalue, tmp, border_flag_value); CASE_CORRELATE_POINT(NPY_USHORT, npy_ushort, pi, ww, oo, filter_size, cvalue, tmp, border_flag_value); CASE_CORRELATE_POINT(NPY_UINT, npy_uint, pi, ww, oo, filter_size, cvalue, tmp, border_flag_value); CASE_CORRELATE_POINT(NPY_ULONG, npy_ulong, pi, ww, oo, filter_size, cvalue, tmp, border_flag_value); CASE_CORRELATE_POINT(NPY_ULONGLONG, npy_ulonglong, pi, ww, oo, filter_size, cvalue, tmp, border_flag_value); CASE_CORRELATE_POINT(NPY_BYTE, npy_byte, pi, ww, oo, filter_size, cvalue, tmp, border_flag_value); CASE_CORRELATE_POINT(NPY_SHORT, npy_short, pi, ww, oo, filter_size, cvalue, tmp, border_flag_value); CASE_CORRELATE_POINT(NPY_INT, npy_int, pi, ww, oo, filter_size, cvalue, tmp, border_flag_value); CASE_CORRELATE_POINT(NPY_LONG, npy_long, pi, ww, oo, filter_size, cvalue, tmp, border_flag_value); CASE_CORRELATE_POINT(NPY_LONGLONG, npy_longlong, pi, ww, oo, filter_size, cvalue, tmp, border_flag_value); CASE_CORRELATE_POINT(NPY_FLOAT, npy_float, pi, ww, oo, filter_size, cvalue, tmp, border_flag_value); CASE_CORRELATE_POINT(NPY_DOUBLE, npy_double, pi, ww, oo, filter_size, cvalue, tmp, border_flag_value); default: err = 1; goto exit; } switch (PyArray_TYPE(output)) { CASE_FILTER_OUT(NPY_BOOL, npy_bool, po, tmp); CASE_FILTER_OUT(NPY_UBYTE, npy_ubyte, po, tmp); CASE_FILTER_OUT(NPY_USHORT, npy_ushort, po, tmp); CASE_FILTER_OUT(NPY_UINT, npy_uint, po, tmp); CASE_FILTER_OUT(NPY_ULONG, npy_ulong, po, tmp); CASE_FILTER_OUT(NPY_ULONGLONG, npy_ulonglong, po, tmp); CASE_FILTER_OUT(NPY_BYTE, npy_byte, po, tmp); CASE_FILTER_OUT(NPY_SHORT, npy_short, po, tmp); CASE_FILTER_OUT(NPY_INT, npy_int, po, tmp); CASE_FILTER_OUT(NPY_LONG, npy_long, po, tmp); CASE_FILTER_OUT(NPY_LONGLONG, npy_longlong, po, tmp); CASE_FILTER_OUT(NPY_FLOAT, npy_float, po, tmp); CASE_FILTER_OUT(NPY_DOUBLE, npy_double, po, tmp); default: err = 1; goto exit; } NI_FILTER_NEXT2(fi, ii, io, oo, pi, po); } exit: NPY_END_THREADS; if (err == 1) { PyErr_SetString(PyExc_RuntimeError, "array type not supported"); } free(offsets); free(ww); free(pf); return PyErr_Occurred() ? 0 : 1; }
int NI_WatershedIFT(PyArrayObject* input, PyArrayObject* markers, PyArrayObject* strct, PyArrayObject* output) { char *pl, *pm, *pi; int ll; npy_intp size, jj, hh, kk, maxval; npy_intp strides[WS_MAXDIM], coordinates[WS_MAXDIM]; npy_intp *nstrides = NULL, nneigh, ssize; int i_contiguous, o_contiguous; NI_WatershedElement *temp = NULL, **first = NULL, **last = NULL; npy_bool *ps = NULL; NI_Iterator mi, ii, li; NPY_BEGIN_THREADS_DEF; i_contiguous = PyArray_ISCONTIGUOUS(input); o_contiguous = PyArray_ISCONTIGUOUS(output); ssize = PyArray_SIZE(strct); if (PyArray_NDIM(input) > WS_MAXDIM) { PyErr_SetString(PyExc_RuntimeError, "too many dimensions"); goto exit; } size = PyArray_SIZE(input); /* Storage for the temporary queue data. */ temp = malloc(size * sizeof(NI_WatershedElement)); if (!temp) { PyErr_NoMemory(); goto exit; } NPY_BEGIN_THREADS; pi = (void *)PyArray_DATA(input); if (!NI_InitPointIterator(input, &ii)) goto exit; /* Initialization and find the maximum of the input. */ maxval = 0; for(jj = 0; jj < size; jj++) { npy_intp ival = 0; switch (PyArray_TYPE(input)) { CASE_GET_INPUT(NPY_UINT8, npy_uint8, ival, pi); CASE_GET_INPUT(NPY_UINT16, npy_uint16, ival, pi); default: NPY_END_THREADS; PyErr_SetString(PyExc_RuntimeError, "data type not supported"); goto exit; } temp[jj].index = jj; temp[jj].done = 0; if (ival > maxval) maxval = ival; NI_ITERATOR_NEXT(ii, pi); } pi = (void *)PyArray_DATA(input); /* Allocate and initialize the storage for the queue. */ first = malloc((maxval + 1) * sizeof(NI_WatershedElement*)); last = malloc((maxval + 1) * sizeof(NI_WatershedElement*)); if (NPY_UNLIKELY(!first || !last)) { NPY_END_THREADS; PyErr_NoMemory(); goto exit; } for(hh = 0; hh <= maxval; hh++) { first[hh] = NULL; last[hh] = NULL; } if (!NI_InitPointIterator(markers, &mi)) goto exit; if (!NI_InitPointIterator(output, &li)) goto exit; pm = (void *)PyArray_DATA(markers); pl = (void *)PyArray_DATA(output); /* initialize all nodes */ for (ll = 0; ll < PyArray_NDIM(input); ll++) { coordinates[ll] = 0; } for(jj = 0; jj < size; jj++) { /* get marker */ int label = 0; switch (PyArray_TYPE(markers)) { CASE_GET_LABEL(NPY_UBYTE, npy_ubyte, label, pm); CASE_GET_LABEL(NPY_USHORT, npy_ushort, label, pm); CASE_GET_LABEL(NPY_UINT, npy_uint, label, pm); CASE_GET_LABEL(NPY_ULONG, npy_ulong, label, pm); CASE_GET_LABEL(NPY_ULONGLONG, npy_ulonglong, label, pm); CASE_GET_LABEL(NPY_BYTE, npy_byte, label, pm); CASE_GET_LABEL(NPY_SHORT, npy_short, label, pm); CASE_GET_LABEL(NPY_INT, npy_int, label, pm); CASE_GET_LABEL(NPY_LONG, npy_long, label, pm); CASE_GET_LABEL(NPY_LONGLONG, npy_longlong, label, pm); default: NPY_END_THREADS; PyErr_SetString(PyExc_RuntimeError, "data type not supported"); goto exit; } switch (PyArray_TYPE(output)) { CASE_PUT_LABEL(NPY_UBYTE, npy_ubyte, label, pl); CASE_PUT_LABEL(NPY_USHORT, npy_ushort, label, pl); CASE_PUT_LABEL(NPY_UINT, npy_uint, label, pl); CASE_PUT_LABEL(NPY_ULONG, npy_ulong, label, pl); CASE_PUT_LABEL(NPY_ULONGLONG, npy_ulonglong, label, pl); CASE_PUT_LABEL(NPY_BYTE, npy_byte, label, pl); CASE_PUT_LABEL(NPY_SHORT, npy_short, label, pl); CASE_PUT_LABEL(NPY_INT, npy_int, label, pl); CASE_PUT_LABEL(NPY_LONG, npy_long, label, pl); CASE_PUT_LABEL(NPY_LONGLONG, npy_longlong, label, pl); default: NPY_END_THREADS; PyErr_SetString(PyExc_RuntimeError, "data type not supported"); goto exit; } NI_ITERATOR_NEXT2(mi, li, pm, pl); if (label != 0) { /* This node is a marker */ temp[jj].cost = 0; if (!first[0]) { first[0] = &(temp[jj]); first[0]->next = NULL; first[0]->prev = NULL; last[0] = first[0]; } else { if (label > 0) { /* object markers are enqueued at the beginning, so they are processed first. */ temp[jj].next = first[0]; temp[jj].prev = NULL; first[0]->prev = &(temp[jj]); first[0] = &(temp[jj]); } else { /* background markers are enqueued at the end, so they are processed after the object markers. */ temp[jj].next = NULL; temp[jj].prev = last[0]; last[0]->next = &(temp[jj]); last[0] = &(temp[jj]); } } } else { /* This node is not a marker */ temp[jj].cost = maxval + 1; temp[jj].next = NULL; temp[jj].prev = NULL; } for (ll = PyArray_NDIM(input) - 1; ll >= 0; ll--) { if (coordinates[ll] < PyArray_DIMS(input)[ll] - 1) { coordinates[ll]++; break; } else { coordinates[ll] = 0; } } } pl = (void *)PyArray_DATA(output); ps = (npy_bool*)PyArray_DATA(strct); nneigh = 0; for (kk = 0; kk < ssize; kk++) if (ps[kk] && kk != (ssize / 2)) ++nneigh; nstrides = malloc(nneigh * sizeof(npy_intp)); if (NPY_UNLIKELY(!nstrides)) { NPY_END_THREADS; PyErr_NoMemory(); goto exit; } strides[PyArray_NDIM(input) - 1] = 1; for (ll = PyArray_NDIM(input) - 2; ll >= 0; ll--) { strides[ll] = PyArray_DIM(input, ll + 1) * strides[ll + 1]; } for (ll = 0; ll < PyArray_NDIM(input); ll++) { coordinates[ll] = -1; } for(kk = 0; kk < nneigh; kk++) nstrides[kk] = 0; jj = 0; for(kk = 0; kk < ssize; kk++) { if (ps[kk]) { int offset = 0; for (ll = 0; ll < PyArray_NDIM(input); ll++) { offset += coordinates[ll] * strides[ll]; } if (offset != 0) nstrides[jj++] += offset; } for (ll = PyArray_NDIM(input) - 1; ll >= 0; ll--) { if (coordinates[ll] < 1) { coordinates[ll]++; break; } else { coordinates[ll] = -1; } } } /* Propagation phase: */ for(jj = 0; jj <= maxval; jj++) { while (first[jj]) { /* dequeue first element: */ NI_WatershedElement *v = first[jj]; first[jj] = first[jj]->next; if (first[jj]) first[jj]->prev = NULL; v->prev = NULL; v->next = NULL; /* Mark element as done: */ v->done = 1; /* Iterate over the neighbors of the element: */ for(hh = 0; hh < nneigh; hh++) { npy_intp v_index = v->index, p_index = v->index, idx, cc; int qq, outside = 0; p_index += nstrides[hh]; /* check if the neighbor is within the extent of the array: */ idx = p_index; for (qq = 0; qq < PyArray_NDIM(input); qq++) { cc = idx / strides[qq]; if (cc < 0 || cc >= PyArray_DIM(input, qq)) { outside = 1; break; } idx -= cc * strides[qq]; } if (!outside) { NI_WatershedElement *p = &(temp[p_index]); if (!(p->done)) { /* If the neighbor was not processed yet: */ int max, pval, vval, wvp, pcost, label, p_idx, v_idx; switch (PyArray_TYPE(input)) { CASE_WINDEX1(NPY_UBYTE, npy_ubyte, v_index, p_index, strides, PyArray_STRIDES(input), PyArray_NDIM(input), i_contiguous, p_idx, v_idx, pi, vval, pval); CASE_WINDEX1(NPY_USHORT, npy_ushort, v_index, p_index, strides, PyArray_STRIDES(input), PyArray_NDIM(input), i_contiguous, p_idx, v_idx, pi, vval, pval); default: NPY_END_THREADS; PyErr_SetString(PyExc_RuntimeError, "data type not supported"); goto exit; } /* Calculate cost: */ wvp = pval - vval; if (wvp < 0) wvp = -wvp; /* Find the maximum of this cost and the current element cost: */ pcost = p->cost; max = v->cost > wvp ? v->cost : wvp; if (max < pcost) { /* If this maximum is less than the neighbors cost, adapt the cost and the label of the neighbor: */ int idx; p->cost = max; switch (PyArray_TYPE(output)) { CASE_WINDEX2(NPY_UBYTE, npy_ubyte, v_index, strides, PyArray_STRIDES(output), PyArray_NDIM(input), idx, o_contiguous, label, pl); CASE_WINDEX2(NPY_USHORT, npy_ushort, v_index, strides, PyArray_STRIDES(output), PyArray_NDIM(input), idx, o_contiguous, label, pl); CASE_WINDEX2(NPY_UINT, npy_uint, v_index, strides, PyArray_STRIDES(output), PyArray_NDIM(input), idx, o_contiguous, label, pl); CASE_WINDEX2(NPY_ULONG, npy_ulong, v_index, strides, PyArray_STRIDES(output), PyArray_NDIM(input), idx, o_contiguous, label, pl); CASE_WINDEX2(NPY_ULONGLONG, npy_ulonglong, v_index, strides, PyArray_STRIDES(output), PyArray_NDIM(input), idx, o_contiguous, label, pl); CASE_WINDEX2(NPY_BYTE, npy_byte, v_index, strides, PyArray_STRIDES(output), PyArray_NDIM(input), idx, o_contiguous, label, pl); CASE_WINDEX2(NPY_SHORT, npy_short, v_index, strides, PyArray_STRIDES(output), PyArray_NDIM(input), idx, o_contiguous, label, pl); CASE_WINDEX2(NPY_INT, npy_int, v_index, strides, PyArray_STRIDES(output), PyArray_NDIM(input), idx, o_contiguous, label, pl); CASE_WINDEX2(NPY_LONG, npy_long, v_index, strides, PyArray_STRIDES(output), PyArray_NDIM(input), idx, o_contiguous, label, pl); CASE_WINDEX2(NPY_LONGLONG, npy_longlong, v_index, strides, PyArray_STRIDES(output), PyArray_NDIM(input), idx, o_contiguous, label, pl); default: NPY_END_THREADS; PyErr_SetString(PyExc_RuntimeError, "data type not supported"); goto exit; } switch (PyArray_TYPE(output)) { CASE_WINDEX3(NPY_UBYTE, npy_ubyte, p_index, strides, PyArray_STRIDES(output), PyArray_NDIM(input), idx, o_contiguous, label, pl); CASE_WINDEX3(NPY_USHORT, npy_ushort, p_index, strides, PyArray_STRIDES(output), PyArray_NDIM(input), idx, o_contiguous, label, pl); CASE_WINDEX3(NPY_UINT, npy_uint, p_index, strides, PyArray_STRIDES(output), PyArray_NDIM(input), idx, o_contiguous, label, pl); CASE_WINDEX3(NPY_ULONG, npy_ulong, p_index, strides, PyArray_STRIDES(output), PyArray_NDIM(input), idx, o_contiguous, label, pl); CASE_WINDEX3(NPY_ULONGLONG, npy_ulonglong, p_index, strides, PyArray_STRIDES(output), PyArray_NDIM(input), idx, o_contiguous, label, pl); CASE_WINDEX3(NPY_BYTE, npy_byte, p_index, strides, PyArray_STRIDES(output), PyArray_NDIM(input), idx, o_contiguous, label, pl); CASE_WINDEX3(NPY_SHORT, npy_short, p_index, strides, PyArray_STRIDES(output), PyArray_NDIM(input), idx, o_contiguous, label, pl); CASE_WINDEX3(NPY_INT, npy_int, p_index, strides, PyArray_STRIDES(output), PyArray_NDIM(input), idx, o_contiguous, label, pl); CASE_WINDEX3(NPY_LONG, npy_long, p_index, strides, PyArray_STRIDES(output), PyArray_NDIM(input), idx, o_contiguous, label, pl); CASE_WINDEX3(NPY_LONGLONG, npy_longlong, p_index, strides, PyArray_STRIDES(output), PyArray_NDIM(input), idx, o_contiguous, label, pl); default: NPY_END_THREADS; PyErr_SetString(PyExc_RuntimeError, "data type not supported"); goto exit; } /* If the neighbor is in a queue, remove it: */ if (p->next || p->prev) { NI_WatershedElement *prev = p->prev, *next = p->next; if (first[pcost] == p) first[pcost] = next; if (last[pcost] == p) last[pcost] = prev; if (prev) prev->next = next; if (next) next->prev = prev; } /* Insert the neighbor in the appropriate queue: */ if (label < 0) { p->prev = last[max]; p->next = NULL; if (last[max]) last[max]->next = p; last[max] = p; if (!first[max]) first[max] = p; } else { p->next = first[max]; p->prev = NULL; if (first[max]) first[max]->prev = p; first[max] = p; if (!last[max]) last[max] = p; } } } } } } } exit: NPY_END_THREADS; free(temp); free(first); free(last); free(nstrides); return PyErr_Occurred() ? 0 : 1; }
static PyObject *div_unit_grad1(PyObject *self, PyObject *args) { PyObject* f = NULL; npy_intp Nx; int i, im1, im2, ip1; npy_float64* f_data_dp = NULL; npy_float64* r_data_dp = NULL; double hx; double hx2; PyArrayObject* r = NULL; double fip, fim, fijk; double aim, aijk; double Dxpf, Dxmf; double Dxma; if (!PyArg_ParseTuple(args, "Od", &f, &hx)) return NULL; hx2 = 2*hx; if (!PyArray_Check(f)) { PyErr_SetString(PyExc_TypeError,"first argument must be array"); return NULL; } if (PyArray_NDIM(f) != 1) { PyErr_SetString(PyExc_TypeError,"array argument must have rank 1"); return NULL; } Nx = PyArray_DIM(f, 0); r = (PyArrayObject*)PyArray_SimpleNew(1, PyArray_DIMS(f), PyArray_TYPE(f)); if (PyArray_TYPE(f) == PyArray_FLOAT64) { f_data_dp = (npy_float64*)PyArray_DATA(f); r_data_dp = (npy_float64*)PyArray_DATA(r); for (i=0; i<Nx; ++i) { im1 = (i?i-1:0); ip1 = (i+1==Nx?i:i+1); fim = *((npy_float64*)PyArray_GETPTR1(f, im1)); fijk = *((npy_float64*)PyArray_GETPTR1(f, i)); fip = *((npy_float64*)PyArray_GETPTR1(f, ip1)); Dxpf = (fip - fijk) / hx; //if (Dxpf==0.0) aijk = 0.0; //else if (Dxpf<0.0) aijk = -1.0; //else aijk = 1.0; aijk = sqrt(Dxpf*Dxpf); aijk = (aijk>FLOAT64_EPS?Dxpf / aijk:0.0); //aijk = abs(Dxpf); //aijk = (aijk>FLOAT64_EPS?Dxpf / aijk:0.0); Dxpf = (fijk - fim) / hx; //if (Dxpf==0.0) aim = 0.0; //else if (Dxpf<0.0) aim = -1.0; //else aim = 1.0; //aim = abs(Dxpf); //aim = (aim>FLOAT64_EPS?Dxpf/aim:0.0); aim = sqrt(Dxpf*Dxpf); aim = (aim>FLOAT64_EPS?Dxpf/aim:0.0); Dxma = (aijk - aim) / hx; *((npy_float64*)PyArray_GETPTR1(r, i)) = Dxma; } } else { PyErr_SetString(PyExc_TypeError,"array argument type must be float64"); return NULL; } return Py_BuildValue("N", r); }
static PyObject *div_unit_grad(PyObject *self, PyObject *args) { PyObject* f = NULL; npy_intp Nx, Ny, Nz; int i, j, k, im1, im2, ip1, jm1, jm2, jp1, km1, km2, kp1; npy_float64* f_data_dp = NULL; npy_float64* r_data_dp = NULL; npy_float32* f_data_sp = NULL; npy_float32* r_data_sp = NULL; double hx, hy, hz; double hx2, hy2, hz2; PyArrayObject* r = NULL; double fip, fim, fjp, fjm, fkp, fkm, fijk; double fimkm, fipkm, fjmkm, fjpkm, fimjm, fipjm, fimkp, fjmkp, fimjp; double aim, bjm, ckm, aijk, bijk, cijk; double Dxpf, Dxmf, Dypf, Dymf, Dzpf, Dzmf; double Dxma, Dymb, Dzmc; if (!PyArg_ParseTuple(args, "O(ddd)", &f, &hx, &hy, &hz)) return NULL; hx2 = 2*hx; hy2 = 2*hy; hz2 = 2*hz; if (!PyArray_Check(f)) { PyErr_SetString(PyExc_TypeError,"first argument must be array"); return NULL; } if (PyArray_NDIM(f) != 3) { PyErr_SetString(PyExc_TypeError,"array argument must have rank 3"); return NULL; } Nx = PyArray_DIM(f, 0); Ny = PyArray_DIM(f, 1); Nz = PyArray_DIM(f, 2); r = (PyArrayObject*)PyArray_SimpleNew(3, PyArray_DIMS(f), PyArray_TYPE(f)); if (PyArray_TYPE(f) == PyArray_FLOAT32) { f_data_sp = (npy_float32*)PyArray_DATA(f); r_data_sp = (npy_float32*)PyArray_DATA(r); for (i=0; i<Nx; ++i) { im1 = (i?i-1:0); im2 = (im1?im1-1:0); ip1 = (i+1==Nx?i:i+1); for (j=0; j<Ny; ++j) { jm1 = (j?j-1:0); jm2 = (jm1?jm1-1:0); jp1 = (j+1==Ny?j:j+1); for (k=0; k<Nz; ++k) { km1 = (k?k-1:0); km2 = (km1?km1-1:0); kp1 = (k+1==Nz?k:k+1); fimjm = *((npy_float32*)PyArray_GETPTR3(f, im1, jm1, k)); fim = *((npy_float32*)PyArray_GETPTR3(f, im1, j, k)); fimkm = *((npy_float32*)PyArray_GETPTR3(f, im1, j, km1)); fimkp = *((npy_float32*)PyArray_GETPTR3(f, im1, j, kp1)); fimjp = *((npy_float32*)PyArray_GETPTR3(f, im1, jp1, k)); fjmkm = *((npy_float32*)PyArray_GETPTR3(f, i, jm1, km1)); fjm = *((npy_float32*)PyArray_GETPTR3(f, i, jm1, k)); fjmkp = *((npy_float32*)PyArray_GETPTR3(f, i, jm1, kp1)); fkm = *((npy_float32*)PyArray_GETPTR3(f, i, j, km1)); fijk = *((npy_float32*)PyArray_GETPTR3(f, i, j, k)); fkp = *((npy_float32*)PyArray_GETPTR3(f, i, j, kp1)); fjpkm = *((npy_float32*)PyArray_GETPTR3(f, i, jp1, km1)); fjp = *((npy_float32*)PyArray_GETPTR3(f, i, jp1, k)); fipjm = *((npy_float32*)PyArray_GETPTR3(f, ip1, jm1, k)); fipkm = *((npy_float32*)PyArray_GETPTR3(f, ip1, j, km1)); fip = *((npy_float32*)PyArray_GETPTR3(f, ip1, j, k)); Dxpf = (fip - fijk) / hx; Dxmf = (fijk - fim) / hx; Dypf = (fjp - fijk) / hy; Dymf = (fijk - fjm) / hy; Dzpf = (fkp - fijk) / hz; Dzmf = (fijk - fkm) / hz; aijk = hypot3(Dxpf, m(Dypf, Dymf), m(Dzpf, Dzmf)); bijk = hypot3(Dypf, m(Dxpf, Dxmf), m(Dzpf, Dzmf)); cijk = hypot3(Dzpf, m(Dypf, Dymf), m(Dxpf, Dxmf)); aijk = (aijk>FLOAT32_EPS?Dxpf / aijk:0.0); bijk = (bijk>FLOAT32_EPS?Dypf / bijk: 0.0); cijk = (cijk>FLOAT32_EPS?Dzpf / cijk:0.0); Dxpf = (fijk - fim) / hx; Dypf = (fimjp - fim) / hy; Dymf = (fim - fimjm) / hy; Dzpf = (fimkp - fim) / hz; Dzmf = (fim - fimkm) / hz; aim = hypot3(Dxpf, m(Dypf, Dymf), m(Dzpf, Dzmf)); aim = (aim>FLOAT32_EPS?Dxpf/aim:0.0); Dxpf = (fipjm - fjm) / hx; Dxmf = (fjm - fimjm) / hx; Dypf = (fijk - fjm) / hy; Dzpf = (fjmkp - fjm) / hz; Dzmf = (fjm - fjmkm) / hz; bjm = hypot3(Dypf, m(Dxpf, Dxmf), m(Dzpf, Dzmf)); bjm = (bjm>FLOAT32_EPS?Dypf/bjm:0.0); Dxpf = (fipkm - fkm) / hx; Dxmf = (fjm - fimkm) / hx; Dypf = (fjpkm - fkm) / hy; Dymf = (fkm - fjmkm) / hy; Dzpf = (fijk - fkm) / hz; ckm = hypot3(Dzpf, m(Dypf, Dymf), m(Dxpf, Dxmf)); ckm = (ckm>FLOAT32_EPS?Dzpf/ckm:0.0); Dxma = (aijk - aim) / hx; Dymb = (bijk - bjm) / hy; Dzmc = (cijk - ckm) / hz; //*((npy_float32*)PyArray_GETPTR3(r, i, j, k)) = Dxma/hx + Dymb/hy + Dzmc/hz; *((npy_float32*)PyArray_GETPTR3(r, i, j, k)) = Dxma + Dymb + Dzmc; } } } } else if (PyArray_TYPE(f) == PyArray_FLOAT64) { f_data_dp = (npy_float64*)PyArray_DATA(f); r_data_dp = (npy_float64*)PyArray_DATA(r); for (i=0; i<Nx; ++i) { im1 = (i?i-1:0); im2 = (im1?im1-1:0); ip1 = (i+1==Nx?i:i+1); for (j=0; j<Ny; ++j) { jm1 = (j?j-1:0); jm2 = (jm1?jm1-1:0); jp1 = (j+1==Ny?j:j+1); for (k=0; k<Nz; ++k) { km1 = (k?k-1:0); km2 = (km1?km1-1:0); kp1 = (k+1==Nz?k:k+1); fimjm = *((npy_float64*)PyArray_GETPTR3(f, im1, jm1, k)); fim = *((npy_float64*)PyArray_GETPTR3(f, im1, j, k)); fimkm = *((npy_float64*)PyArray_GETPTR3(f, im1, j, km1)); fimkp = *((npy_float64*)PyArray_GETPTR3(f, im1, j, kp1)); fimjp = *((npy_float64*)PyArray_GETPTR3(f, im1, jp1, k)); fjmkm = *((npy_float64*)PyArray_GETPTR3(f, i, jm1, km1)); fjm = *((npy_float64*)PyArray_GETPTR3(f, i, jm1, k)); fjmkp = *((npy_float64*)PyArray_GETPTR3(f, i, jm1, kp1)); fkm = *((npy_float64*)PyArray_GETPTR3(f, i, j, km1)); fijk = *((npy_float64*)PyArray_GETPTR3(f, i, j, k)); fkp = *((npy_float64*)PyArray_GETPTR3(f, i, j, kp1)); fjpkm = *((npy_float64*)PyArray_GETPTR3(f, i, jp1, km1)); fjp = *((npy_float64*)PyArray_GETPTR3(f, i, jp1, k)); fipjm = *((npy_float64*)PyArray_GETPTR3(f, ip1, jm1, k)); fipkm = *((npy_float64*)PyArray_GETPTR3(f, ip1, j, km1)); fip = *((npy_float64*)PyArray_GETPTR3(f, ip1, j, k)); Dxpf = (fip - fijk) / hx; Dxmf = (fijk - fim) / hx; Dypf = (fjp - fijk) / hy; Dymf = (fijk - fjm) / hy; Dzpf = (fkp - fijk) / hz; Dzmf = (fijk - fkm) / hz; aijk = hypot3(Dxpf, m(Dypf, Dymf), m(Dzpf, Dzmf)); aijk = (aijk>FLOAT64_EPS?Dxpf / aijk:0.0); bijk = hypot3(Dypf, m(Dxpf, Dxmf), m(Dzpf, Dzmf)); bijk = (bijk>FLOAT64_EPS?Dypf / bijk: 0.0); cijk = hypot3(Dzpf, m(Dypf, Dymf), m(Dxpf, Dxmf)); cijk = (cijk>FLOAT64_EPS?Dzpf/cijk:0.0); Dxpf = (fijk - fim) / hx; Dypf = (fimjp - fim) / hy; Dymf = (fim - fimjm) / hy; Dzpf = (fimkp - fim) / hz; Dzmf = (fim - fimkm) / hz; aim = hypot3(Dxpf, m(Dypf, Dymf), m(Dzpf, Dzmf)); aim = (aim>FLOAT64_EPS?Dxpf/aim:0.0); Dxpf = (fipjm - fjm) / hx; Dxmf = (fjm - fimjm) / hx; Dypf = (fijk - fjm) / hy; Dzpf = (fjmkp - fjm) / hz; Dzmf = (fjm - fjmkm) / hz; bjm = hypot3(Dypf, m(Dxpf, Dxmf), m(Dzpf, Dzmf)); bjm = (bjm>FLOAT64_EPS?Dypf/bjm:0.0); Dxpf = (fipkm - fkm) / hx; Dxmf = (fjm - fimkm) / hx; Dypf = (fjpkm - fkm) / hy; Dymf = (fkm - fjmkm) / hy; Dzpf = (fijk - fkm) / hz; ckm = hypot3(Dzpf, m(Dypf, Dymf), m(Dxpf, Dxmf)); ckm = (ckm>FLOAT64_EPS?Dzpf/ckm:0.0); Dxma = (aijk - aim) / hx; Dymb = (bijk - bjm) / hy; Dzmc = (cijk - ckm) / hz; //*((npy_float64*)PyArray_GETPTR3(r, i, j, k)) = Dxma/hx + Dymb/hy + Dzmc/hz; *((npy_float64*)PyArray_GETPTR3(r, i, j, k)) = Dxma + Dymb + Dzmc; } } } } else { PyErr_SetString(PyExc_TypeError,"array argument type must be float64"); return NULL; } return Py_BuildValue("N", r); }
/* * 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; }
int NI_MinOrMaxFilter1D(PyArrayObject *input, npy_intp filter_size, int axis, PyArrayObject *output, NI_ExtendMode mode, double cval, npy_intp origin, int minimum) { npy_intp lines, kk, ll, length, size1, size2; int more; double *ibuffer = NULL, *obuffer = NULL; NI_LineBuffer iline_buffer, oline_buffer; struct pairs { double value; npy_intp death; } *ring = NULL, *minpair, *end, *last; NPY_BEGIN_THREADS_DEF; size1 = filter_size / 2; size2 = filter_size - size1 - 1; /* allocate and initialize the line buffers: */ lines = -1; if (!NI_AllocateLineBuffer(input, axis, size1 + origin, size2 - origin, &lines, BUFFER_SIZE, &ibuffer)) goto exit; if (!NI_AllocateLineBuffer(output, axis, 0, 0, &lines, BUFFER_SIZE, &obuffer)) goto exit; if (!NI_InitLineBuffer(input, axis, size1 + origin, size2 - origin, lines, ibuffer, mode, cval, &iline_buffer)) goto exit; if (!NI_InitLineBuffer(output, axis, 0, 0, lines, obuffer, mode, 0.0, &oline_buffer)) goto exit; NPY_BEGIN_THREADS; length = PyArray_NDIM(input) > 0 ? PyArray_DIM(input, axis) : 1; /* ring is a dequeue of pairs implemented as a circular array */ ring = malloc(filter_size * sizeof(struct pairs)); if (!ring) { goto exit; } end = ring + filter_size; /* iterate over all the array lines: */ do { /* copy lines from array to buffer: */ if (!NI_ArrayToLineBuffer(&iline_buffer, &lines, &more)) { goto exit; } /* iterate over the lines in the buffers: */ for(kk = 0; kk < lines; kk++) { /* get lines: */ double *iline = NI_GET_LINE(iline_buffer, kk); double *oline = NI_GET_LINE(oline_buffer, kk); /* This check could be moved out to the Python wrapper */ if (filter_size == 1) { memcpy(oline, iline, sizeof(double) * length); } else { /* * Original code by Richard Harter, adapted from: * http://www.richardhartersworld.com/cri/2001/slidingmin.html */ minpair = ring; minpair->value = *iline++; minpair->death = filter_size; last = ring; for (ll = 1; ll < filter_size + length - 1; ll++) { double val = *iline++; if (minpair->death == ll) { INCREASE_RING_PTR(minpair) } if ((minimum && val <= minpair->value) || (!minimum && val >= minpair->value)) { minpair->value = val; minpair->death = ll + filter_size; last = minpair; } else { while ((minimum && last->value >= val) || (!minimum && last->value <= val)) { DECREASE_RING_PTR(last) } INCREASE_RING_PTR(last) last->value = val; last->death = ll + filter_size; } if (ll >= filter_size - 1) { *oline++ = minpair->value; } } } } /* copy lines from buffer to array: */ if (!NI_LineBufferToArray(&oline_buffer)) { goto exit; } } while(more); exit: NPY_END_THREADS; free(ibuffer); free(obuffer); free(ring); return PyErr_Occurred() ? 0 : 1; }
static PyObject *fit_ellipse_double_func(PyObject *self, PyObject *args) { PyObject *points=NULL; PyObject *points_arr=NULL; /* Local variables for handling the dimensions of the ndarrays. */ long *points_arr_dims=NULL; int points_arr_nd=0; /* Pointers into the ndarrays. */ npy_int32 *points_arr_ptr=NULL; /* Loop counters and other local variables. */ int i; /* Parse the input to correct pointers. */ if (!PyArg_ParseTuple(args, "O", &points)) return NULL; points_arr = PyArray_FROM_OTF(points, NPY_INT32, NPY_IN_ARRAY); if (points_arr == NULL) goto fail; /* Dimensions of the arrays. */ points_arr_nd = PyArray_NDIM(points_arr); points_arr_dims = PyArray_DIMS(points_arr); if (points_arr_nd != 2) { printf("Dimension of coordinates array must be equal to zero. (%d != 2).\n", points_arr_nd); goto fail; } int32_t *x = (int32_t*) malloc(sizeof(int32_t) * points_arr_dims[0]); int32_t *y = (int32_t*) malloc(sizeof(int32_t) * points_arr_dims[0]); for (i = 0; i < points_arr_dims[0]; i++) { points_arr_ptr = PyArray_GETPTR2(points_arr, i, 0); x[i] = points_arr_ptr[0]; y[i] = points_arr_ptr[1]; } // Call the actual ellipse fitting function. EllipseDouble ellipse = FitEllipse_double(x, y, (int16_t) points_arr_dims[0]); /* Decrease reference counters and free memory to avoid memory leaks. */ free(x); free(y); Py_DECREF(points_arr); if (ellipse.isValid) { int out_dims[1] = {2}; PyArrayObject *xy; npy_float64 *xy_ptr; xy = (PyArrayObject *) PyArray_FromDims(1, out_dims, NPY_FLOAT64); xy_ptr = (npy_float64 *)PyArray_GETPTR1(xy, 0); xy_ptr[0] = ellipse.centerX; xy_ptr[1] = ellipse.centerY; PyArrayObject *axes; npy_float64 *axes_ptr; axes = (PyArrayObject *) PyArray_FromDims(1, out_dims, NPY_FLOAT64); axes_ptr = (npy_float64 *)PyArray_GETPTR1(axes, 0); axes_ptr[0] = ellipse.xAxis; axes_ptr[1] = ellipse.yAxis; PyObject *tuple_result = PyTuple_New(3); PyTuple_SetItem(tuple_result, 0, PyArray_Return(xy)); PyTuple_SetItem(tuple_result, 1, PyArray_Return(axes)); PyTuple_SetItem(tuple_result, 2, PyFloat_FromDouble(ellipse.rotationAngle)); return (PyObject *)tuple_result; } else { Py_RETURN_NONE; } fail: /* If error occurs, decrease reference counters to avoid memory leaks. */ Py_XDECREF(points_arr); /* Return error indication. */ return NULL; }
int NI_MinOrMaxFilter(PyArrayObject* input, PyArrayObject* footprint, PyArrayObject* structure, PyArrayObject* output, NI_ExtendMode mode, double cvalue, npy_intp *origins, int minimum) { npy_bool *pf = NULL; npy_intp fsize, jj, kk, filter_size = 0, border_flag_value; npy_intp *offsets = NULL, *oo, size; NI_FilterIterator fi; NI_Iterator ii, io; char *pi, *po; int err = 0; double *ss = NULL; npy_double *ps; NPY_BEGIN_THREADS_DEF; /* get the the footprint: */ fsize = PyArray_SIZE(footprint); pf = (npy_bool*)PyArray_DATA(footprint); for(jj = 0; jj < fsize; jj++) { if (pf[jj]) { ++filter_size; } } /* get the structure: */ if (structure) { ss = malloc(filter_size * sizeof(double)); if (!ss) { PyErr_NoMemory(); goto exit; } /* copy the weights to contiguous memory: */ ps = (npy_double*)PyArray_DATA(structure); jj = 0; for(kk = 0; kk < fsize; kk++) if (pf[kk]) ss[jj++] = minimum ? -ps[kk] : ps[kk]; } /* initialize filter offsets: */ if (!NI_InitFilterOffsets(input, pf, PyArray_DIMS(footprint), origins, mode, &offsets, &border_flag_value, NULL)) { goto exit; } /* initialize filter iterator: */ if (!NI_InitFilterIterator(PyArray_NDIM(input), PyArray_DIMS(footprint), filter_size, PyArray_DIMS(input), origins, &fi)) { goto exit; } /* initialize input element iterator: */ if (!NI_InitPointIterator(input, &ii)) goto exit; /* initialize output element iterator: */ if (!NI_InitPointIterator(output, &io)) goto exit; NPY_BEGIN_THREADS; /* get data pointers an array size: */ pi = (void *)PyArray_DATA(input); po = (void *)PyArray_DATA(output); size = PyArray_SIZE(input); /* iterator over the elements: */ oo = offsets; for(jj = 0; jj < size; jj++) { double tmp = 0.0; switch (PyArray_TYPE(input)) { CASE_MIN_OR_MAX_POINT(NPY_BOOL, npy_bool, pi, oo, filter_size, cvalue, minimum, tmp, border_flag_value, ss); CASE_MIN_OR_MAX_POINT(NPY_UBYTE, npy_ubyte, pi, oo, filter_size, cvalue, minimum, tmp, border_flag_value, ss); CASE_MIN_OR_MAX_POINT(NPY_USHORT, npy_ushort, pi, oo, filter_size, cvalue, minimum, tmp, border_flag_value, ss); CASE_MIN_OR_MAX_POINT(NPY_UINT, npy_uint, pi, oo, filter_size, cvalue, minimum, tmp, border_flag_value, ss); CASE_MIN_OR_MAX_POINT(NPY_ULONG, npy_ulong, pi, oo, filter_size, cvalue, minimum, tmp, border_flag_value, ss); CASE_MIN_OR_MAX_POINT(NPY_ULONGLONG, npy_ulonglong, pi, oo, filter_size, cvalue, minimum, tmp, border_flag_value, ss); CASE_MIN_OR_MAX_POINT(NPY_BYTE, npy_byte, pi, oo, filter_size, cvalue, minimum, tmp, border_flag_value, ss); CASE_MIN_OR_MAX_POINT(NPY_SHORT, npy_short, pi, oo, filter_size, cvalue, minimum, tmp, border_flag_value, ss); CASE_MIN_OR_MAX_POINT(NPY_INT, npy_int, pi, oo, filter_size, cvalue, minimum, tmp, border_flag_value, ss); CASE_MIN_OR_MAX_POINT(NPY_LONG, npy_long, pi, oo, filter_size, cvalue, minimum, tmp, border_flag_value, ss); CASE_MIN_OR_MAX_POINT(NPY_LONGLONG, npy_longlong, pi, oo, filter_size, cvalue, minimum, tmp, border_flag_value, ss); CASE_MIN_OR_MAX_POINT(NPY_FLOAT, npy_float, pi, oo, filter_size, cvalue, minimum, tmp, border_flag_value, ss); CASE_MIN_OR_MAX_POINT(NPY_DOUBLE, npy_double, pi, oo, filter_size, cvalue, minimum, tmp, border_flag_value, ss); default: err = 1; goto exit; } switch (PyArray_TYPE(output)) { CASE_FILTER_OUT(NPY_BOOL, npy_bool, po, tmp); CASE_FILTER_OUT(NPY_UBYTE, npy_ubyte, po, tmp); CASE_FILTER_OUT(NPY_USHORT, npy_ushort, po, tmp); CASE_FILTER_OUT(NPY_UINT, npy_uint, po, tmp); CASE_FILTER_OUT(NPY_ULONG, npy_ulong, po, tmp); CASE_FILTER_OUT(NPY_ULONGLONG, npy_ulonglong, po, tmp); CASE_FILTER_OUT(NPY_BYTE, npy_byte, po, tmp); CASE_FILTER_OUT(NPY_SHORT, npy_short, po, tmp); CASE_FILTER_OUT(NPY_INT, npy_int, po, tmp); CASE_FILTER_OUT(NPY_LONG, npy_long, po, tmp); CASE_FILTER_OUT(NPY_LONGLONG, npy_longlong, po, tmp); CASE_FILTER_OUT(NPY_FLOAT, npy_float, po, tmp); CASE_FILTER_OUT(NPY_DOUBLE, npy_double, po, tmp); default: err = 1; goto exit; } NI_FILTER_NEXT2(fi, ii, io, oo, pi, po); } exit: NPY_END_THREADS; if (err == 1) { PyErr_SetString(PyExc_RuntimeError, "array type not supported"); } free(offsets); free(ss); return PyErr_Occurred() ? 0 : 1; }
bool numpy_to_mat(const PyObject* o, cv::Mat& m, const char* name, bool allowND) { if(!o || o == Py_None) { if( !m.data ) m.allocator = &g_numpyAllocator; return true; } if( !PyArray_Check(o) ) { failmsg("%s is not a numpy array", name); return false; } int typenum = PyArray_TYPE(o); int type = typenum == NPY_UBYTE ? CV_8U : typenum == NPY_BYTE ? CV_8S : typenum == NPY_USHORT ? CV_16U : typenum == NPY_SHORT ? CV_16S : typenum == NPY_INT || typenum == NPY_LONG ? CV_32S : typenum == NPY_FLOAT ? CV_32F : typenum == NPY_DOUBLE ? CV_64F : -1; if( type < 0 ) { failmsg("%s data type = %d is not supported", name, typenum); return false; } int ndims = PyArray_NDIM(o); if(ndims >= CV_MAX_DIM) { failmsg("%s dimensionality (=%d) is too high", name, ndims); return false; } int size[CV_MAX_DIM+1]; size_t step[CV_MAX_DIM+1], elemsize = CV_ELEM_SIZE1(type); const npy_intp* _sizes = PyArray_DIMS(o); const npy_intp* _strides = PyArray_STRIDES(o); for(int i = 0; i < ndims; i++) { size[i] = (int)_sizes[i]; step[i] = (size_t)_strides[i]; } if( ndims == 0 || step[ndims-1] > elemsize ) { size[ndims] = 1; step[ndims] = elemsize; ndims++; } if( ndims == 3 && size[2] <= CV_CN_MAX && step[1] == elemsize*size[2] ) { ndims--; type |= CV_MAKETYPE(0, size[2]); } if( ndims > 2 && !allowND ) { failmsg("%s has more than 2 dimensions", name); return false; } m = Mat(ndims, size, type, PyArray_DATA(o), step); if( m.data ) { m.refcount = refcountFromPyObject(o); m.addref(); // protect the original numpy array from deallocation // (since Mat destructor will decrement the reference counter) }; m.allocator = &g_numpyAllocator; return true; }
int NI_GenericFilter(PyArrayObject* input, int (*function)(double*, npy_intp, double*, void*), void *data, PyArrayObject* footprint, PyArrayObject* output, NI_ExtendMode mode, double cvalue, npy_intp *origins) { npy_bool *pf = NULL; npy_intp fsize, jj, filter_size = 0, border_flag_value; npy_intp *offsets = NULL, *oo, size; NI_FilterIterator fi; NI_Iterator ii, io; char *pi, *po; double *buffer = NULL; /* get the the footprint: */ fsize = PyArray_SIZE(footprint); pf = (npy_bool*)PyArray_DATA(footprint); for(jj = 0; jj < fsize; jj++) { if (pf[jj]) ++filter_size; } /* initialize filter offsets: */ if (!NI_InitFilterOffsets(input, pf, PyArray_DIMS(footprint), origins, mode, &offsets, &border_flag_value, NULL)) { goto exit; } /* initialize filter iterator: */ if (!NI_InitFilterIterator(PyArray_NDIM(input), PyArray_DIMS(footprint), filter_size, PyArray_DIMS(input), origins, &fi)) { goto exit; } /* initialize input element iterator: */ if (!NI_InitPointIterator(input, &ii)) goto exit; /* initialize output element iterator: */ if (!NI_InitPointIterator(output, &io)) goto exit; /* get data pointers an array size: */ pi = (void *)PyArray_DATA(input); po = (void *)PyArray_DATA(output); size = PyArray_SIZE(input); /* buffer for filter calculation: */ buffer = malloc(filter_size * sizeof(double)); if (!buffer) { PyErr_NoMemory(); goto exit; } /* iterate over the elements: */ oo = offsets; for(jj = 0; jj < size; jj++) { double tmp = 0.0; switch (PyArray_TYPE(input)) { CASE_FILTER_POINT(NPY_BOOL, npy_bool, pi, oo, filter_size, cvalue, tmp, border_flag_value, function, data, buffer); CASE_FILTER_POINT(NPY_UBYTE, npy_ubyte, pi, oo, filter_size, cvalue, tmp, border_flag_value, function, data, buffer); CASE_FILTER_POINT(NPY_USHORT, npy_ushort, pi, oo, filter_size, cvalue, tmp, border_flag_value, function, data, buffer); CASE_FILTER_POINT(NPY_UINT, npy_uint, pi, oo, filter_size, cvalue, tmp, border_flag_value, function, data, buffer); CASE_FILTER_POINT(NPY_ULONG, npy_ulong, pi, oo, filter_size, cvalue, tmp, border_flag_value, function, data, buffer); CASE_FILTER_POINT(NPY_ULONGLONG, npy_ulonglong, pi, oo, filter_size, cvalue, tmp, border_flag_value, function, data, buffer); CASE_FILTER_POINT(NPY_BYTE, npy_byte, pi, oo, filter_size, cvalue, tmp, border_flag_value, function, data, buffer); CASE_FILTER_POINT(NPY_SHORT, npy_short, pi, oo, filter_size, cvalue, tmp, border_flag_value, function, data, buffer); CASE_FILTER_POINT(NPY_INT, npy_int, pi, oo, filter_size, cvalue, tmp, border_flag_value, function, data, buffer); CASE_FILTER_POINT(NPY_LONG, npy_long, pi, oo, filter_size, cvalue, tmp, border_flag_value, function, data, buffer); CASE_FILTER_POINT(NPY_LONGLONG, npy_longlong, pi, oo, filter_size, cvalue, tmp, border_flag_value, function, data, buffer); CASE_FILTER_POINT(NPY_FLOAT, npy_float, pi, oo, filter_size, cvalue, tmp, border_flag_value, function, data, buffer); CASE_FILTER_POINT(NPY_DOUBLE, npy_double, pi, oo, filter_size, cvalue, tmp, border_flag_value, function, data, buffer); default: PyErr_SetString(PyExc_RuntimeError, "array type not supported"); goto exit; } switch (PyArray_TYPE(output)) { CASE_FILTER_OUT(NPY_BOOL, npy_bool, po, tmp); CASE_FILTER_OUT(NPY_UBYTE, npy_ubyte, po, tmp); CASE_FILTER_OUT(NPY_USHORT, npy_ushort, po, tmp); CASE_FILTER_OUT(NPY_UINT, npy_uint, po, tmp); CASE_FILTER_OUT(NPY_ULONG, npy_ulong, po, tmp); CASE_FILTER_OUT(NPY_ULONGLONG, npy_ulonglong, po, tmp); CASE_FILTER_OUT(NPY_BYTE, npy_byte, po, tmp); CASE_FILTER_OUT(NPY_SHORT, npy_short, po, tmp); CASE_FILTER_OUT(NPY_INT, npy_int, po, tmp); CASE_FILTER_OUT(NPY_LONG, npy_long, po, tmp); CASE_FILTER_OUT(NPY_LONGLONG, npy_longlong, po, tmp); CASE_FILTER_OUT(NPY_FLOAT, npy_float, po, tmp); CASE_FILTER_OUT(NPY_DOUBLE, npy_double, po, tmp); default: PyErr_SetString(PyExc_RuntimeError, "array type not supported"); goto exit; } NI_FILTER_NEXT2(fi, ii, io, oo, pi, po); } exit: free(offsets); free(buffer); return PyErr_Occurred() ? 0 : 1; }
int NI_FourierFilter(PyArrayObject *input, PyArrayObject* parameter_array, npy_intp n, int axis, PyArrayObject* output, int filter_type) { NI_Iterator ii, io; char *pi, *po; double *parameters = NULL, **params = NULL; npy_intp kk, hh, size; npy_double *iparameters = (void *)PyArray_DATA(parameter_array); NPY_BEGIN_THREADS_DEF; /* precalculate the parameters: */ parameters = malloc(PyArray_NDIM(input) * sizeof(double)); if (!parameters) { PyErr_NoMemory(); goto exit; } for (kk = 0; kk < PyArray_NDIM(input); kk++) { /* along the direction of the real transform we must use the given length of that dimensons, unless a complex transform is assumed (n < 0): */ int shape = kk == axis ? (n < 0 ? PyArray_DIM(input, kk) : n) : PyArray_DIM(input, kk); switch (filter_type) { case _NI_GAUSSIAN: parameters[kk] = *iparameters++ * M_PI / (double)shape; parameters[kk] = -2.0 * parameters[kk] * parameters[kk]; break; case _NI_ELLIPSOID: case _NI_UNIFORM: parameters[kk] = *iparameters++; break; } } /* allocate memory for tables: */ params = malloc(PyArray_NDIM(input) * sizeof(double*)); if (!params) { PyErr_NoMemory(); goto exit; } for (kk = 0; kk < PyArray_NDIM(input); kk++) { params[kk] = NULL; } for (kk = 0; kk < PyArray_NDIM(input); kk++) { if (PyArray_DIM(input, kk) > 1) { params[kk] = malloc(PyArray_DIM(input, kk) * sizeof(double)); if (!params[kk]) { PyErr_NoMemory(); goto exit; } } } NPY_BEGIN_THREADS; switch (filter_type) { case _NI_GAUSSIAN: /* calculate the tables of exponentials: */ for (hh = 0; hh < PyArray_NDIM(input); hh++) { if (params[hh]) { if (hh == axis && n >= 0) { for (kk = 0; kk < PyArray_DIM(input, hh); kk++) { double tmp = parameters[hh] * kk * kk; params[hh][kk] = fabs(tmp) > 50.0 ? 0.0 : exp(tmp); } } else { const npy_intp dim = PyArray_DIM(input, hh); int jj = 0; for (kk = 0; kk < (dim + 1) / 2; kk++) { double tmp = parameters[hh] * kk * kk; params[hh][jj++] = fabs(tmp) > 50.0 ? 0.0 : exp(tmp); } for (kk = -(dim / 2); kk < 0; kk++) { double tmp = parameters[hh] * kk * kk; params[hh][jj++] = fabs(tmp) > 50.0 ? 0.0 : exp(tmp); } } } } break; case _NI_UNIFORM: /* calculate the tables of parameters: */ for (hh = 0; hh < PyArray_NDIM(input); hh++) { if (params[hh]) { params[hh][0] = 1.0; if (hh == axis && n >= 0) { double tmp = M_PI * parameters[hh] / n; for (kk = 1; kk < PyArray_DIM(input, hh); kk++) { params[hh][kk] = tmp > 0.0 ? sin(tmp * kk) / (tmp * kk) : 0.0; } } else { const npy_intp dim = PyArray_DIM(input, hh); double tmp = M_PI * parameters[hh] / dim; int jj = 1; for (kk = 1; kk < (dim + 1) / 2; kk++) { params[hh][jj++] = tmp > 0.0 ? sin(tmp * kk) / (tmp * kk) : 0.0; } for (kk = -(dim / 2); kk < 0; kk++) { params[hh][jj++] = tmp > 0.0 ? sin(tmp * kk) / (tmp * kk) : 0.0; } } } } break; case _NI_ELLIPSOID: /* calculate the tables of parameters: */ for (hh = 0; hh < PyArray_NDIM(input); hh++) { if (params[hh]) { params[hh][0] = 1.0; if (hh == axis && n >= 0) { double tmp = M_PI * parameters[hh] / n; for (kk = 0; kk < PyArray_DIM(input, hh); kk++) { params[hh][kk] = (double)kk * tmp; } } else { const npy_intp dim = PyArray_DIM(input, hh); double tmp = M_PI * parameters[hh] / dim; int jj = 0; for(kk = 0; kk < (dim + 1) / 2; kk++) { params[hh][jj++] = (double)kk * tmp; } for(kk = -(dim / 2); kk < 0; kk++) { params[hh][jj++] = (double)kk * tmp; } } } else if (PyArray_DIM(input, hh) > 0) { params[hh][0] = 1.0; } } if (PyArray_NDIM(input) > 1) for(hh = 0; hh < PyArray_NDIM(input); hh++) for(kk = 0; kk < PyArray_DIM(input, hh); kk++) { params[hh][kk] *= params[hh][kk]; } break; default: break; } /* initialize input element iterator: */ if (!NI_InitPointIterator(input, &ii)) goto exit; /* initialize output element iterator: */ if (!NI_InitPointIterator(output, &io)) goto exit; pi = (void *)PyArray_DATA(input); po = (void *)PyArray_DATA(output); size = PyArray_SIZE(input); /* iterator over the elements: */ for(hh = 0; hh < size; hh++) { double tmp = 1.0; switch (filter_type) { case _NI_GAUSSIAN: case _NI_UNIFORM: for (kk = 0; kk < PyArray_NDIM(input); kk++) { if (params[kk]) tmp *= params[kk][ii.coordinates[kk]]; } break; case _NI_ELLIPSOID: switch (PyArray_NDIM(input)) { case 1: tmp = params[0][ii.coordinates[0]]; tmp = tmp > 0.0 ? sin(tmp) / (tmp) : 1.0; break; case 2: tmp = 0.0; for(kk = 0; kk < 2; kk++) tmp += params[kk][ii.coordinates[kk]]; tmp = sqrt(tmp); tmp = tmp > 0.0 ? 2.0 * _bessel_j1(tmp) / tmp : 1.0; break; case 3: { double r = 0.0; for(kk = 0; kk < 3; kk++) r += params[kk][ii.coordinates[kk]]; r = sqrt(r); if (r > 0.0) { tmp = 3.0 * (sin(r) - r * cos(r)); tmp /= r * r * r; } else { tmp = 1.0; } } break; } break; default: break; } if (PyArray_TYPE(input) == NPY_CFLOAT || PyArray_TYPE(input) == NPY_CDOUBLE) { double tmp_r = 0.0, tmp_i = 0.0; switch (PyArray_TYPE(input)) { CASE_FOURIER_FILTER_RC(NPY_CFLOAT, npy_cfloat, pi, tmp, tmp_r, tmp_i); CASE_FOURIER_FILTER_RC(NPY_CDOUBLE, npy_cdouble, pi, tmp, tmp_r, tmp_i); default: NPY_END_THREADS; PyErr_SetString(PyExc_RuntimeError, "data type not supported"); goto exit; } switch (PyArray_TYPE(output)) { CASE_FOURIER_OUT_CC(NPY_CFLOAT, npy_cfloat, po, tmp_r, tmp_i); CASE_FOURIER_OUT_CC(NPY_CDOUBLE, npy_cdouble, po, tmp_r, tmp_i); default: NPY_END_THREADS; PyErr_SetString(PyExc_RuntimeError, "data type not supported"); goto exit; } } else { switch (PyArray_TYPE(input)) { CASE_FOURIER_FILTER_RR(NPY_BOOL, npy_bool, pi, tmp); CASE_FOURIER_FILTER_RR(NPY_UBYTE, npy_ubyte, pi, tmp); CASE_FOURIER_FILTER_RR(NPY_USHORT, npy_ushort, pi, tmp); CASE_FOURIER_FILTER_RR(NPY_UINT, npy_uint, pi, tmp); CASE_FOURIER_FILTER_RR(NPY_ULONG, npy_ulong, pi, tmp); CASE_FOURIER_FILTER_RR(NPY_ULONGLONG, npy_ulonglong, pi, tmp); CASE_FOURIER_FILTER_RR(NPY_BYTE, npy_byte, pi, tmp); CASE_FOURIER_FILTER_RR(NPY_SHORT, npy_short, pi, tmp); CASE_FOURIER_FILTER_RR(NPY_INT, npy_int, pi, tmp); CASE_FOURIER_FILTER_RR(NPY_LONG, npy_long, pi, tmp); CASE_FOURIER_FILTER_RR(NPY_LONGLONG, npy_longlong, pi, tmp); CASE_FOURIER_FILTER_RR(NPY_FLOAT, npy_float, pi, tmp); CASE_FOURIER_FILTER_RR(NPY_DOUBLE, npy_double, pi, tmp); default: NPY_END_THREADS; PyErr_SetString(PyExc_RuntimeError, "data type not supported"); goto exit; } switch (PyArray_TYPE(output)) { CASE_FOURIER_OUT_RR(NPY_FLOAT, npy_float, po, tmp); CASE_FOURIER_OUT_RR(NPY_DOUBLE, npy_double, po, tmp); CASE_FOURIER_OUT_RC(NPY_CFLOAT, npy_cfloat, po, tmp); CASE_FOURIER_OUT_RC(NPY_CDOUBLE, npy_cdouble, po, tmp); default: NPY_END_THREADS; PyErr_SetString(PyExc_RuntimeError, "data type not supported"); goto exit; } } NI_ITERATOR_NEXT2(ii, io, pi, po); } exit: NPY_END_THREADS; free(parameters); if (params) { for (kk = 0; kk < PyArray_NDIM(input); kk++) { free(params[kk]); } free(params); } return PyErr_Occurred() ? 0 : 1; }
/* * This function initializes a result array for a reduction operation * which has no identity. This means it needs to copy the first element * it sees along the reduction axes to result, then return a view of * the operand which excludes that element. * * If a reduction has an identity, such as 0 or 1, the result should be * initialized by calling PyArray_AssignZero(result, NULL, NULL) or * PyArray_AssignOne(result, NULL, NULL), because this function raises an * exception when there are no elements to reduce (which appropriate iff the * reduction operation has no identity). * * This means it copies the subarray indexed at zero along each reduction axis * into 'result', then returns a view into 'operand' excluding those copied * elements. * * result : The array into which the result is computed. This must have * the same number of dimensions as 'operand', but for each * axis i where 'axis_flags[i]' is True, it has a single element. * operand : The array being reduced. * axis_flags : An array of boolean flags, one for each axis of 'operand'. * When a flag is True, it indicates to reduce along that axis. * reorderable : If True, the reduction being done is reorderable, which * means specifying multiple axes of reduction at once is ok, * and the reduction code may calculate the reduction in an * arbitrary order. The calculation may be reordered because * of cache behavior or multithreading requirements. * out_skip_first_count : This gets populated with the number of first-visit * elements that should be skipped during the * iteration loop. * funcname : The name of the reduction operation, for the purpose of * better quality error messages. For example, "numpy.max" * would be a good name for NumPy's max function. * * Returns a view which contains the remaining elements on which to do * the reduction. */ NPY_NO_EXPORT PyArrayObject * PyArray_InitializeReduceResult( PyArrayObject *result, PyArrayObject *operand, npy_bool *axis_flags, int reorderable, npy_intp *out_skip_first_count, const char *funcname) { npy_intp *strides, *shape, shape_orig[NPY_MAXDIMS]; PyArrayObject *op_view = NULL; int idim, ndim, nreduce_axes; ndim = PyArray_NDIM(operand); /* Default to no skipping first-visit elements in the iteration */ *out_skip_first_count = 0; /* * If this reduction is non-reorderable, make sure there are * only 0 or 1 axes in axis_flags. */ if (!reorderable && check_nonreorderable_axes(ndim, axis_flags, funcname) < 0) { return NULL; } /* Take a view into 'operand' which we can modify. */ op_view = (PyArrayObject *)PyArray_View(operand, NULL, &PyArray_Type); if (op_view == NULL) { return NULL; } /* * Now copy the subarray of the first element along each reduction axis, * then return a view to the rest. * * Adjust the shape to only look at the first element along * any of the reduction axes. We count the number of reduction axes * at the same time. */ shape = PyArray_SHAPE(op_view); nreduce_axes = 0; memcpy(shape_orig, shape, ndim * sizeof(npy_intp)); for (idim = 0; idim < ndim; ++idim) { if (axis_flags[idim]) { if (shape[idim] == 0) { PyErr_Format(PyExc_ValueError, "zero-size array to reduction operation %s " "which has no identity", funcname); Py_DECREF(op_view); return NULL; } shape[idim] = 1; ++nreduce_axes; } } /* * Copy the elements into the result to start. */ if (PyArray_CopyInto(result, op_view) < 0) { Py_DECREF(op_view); return NULL; } /* * If there is one reduction axis, adjust the view's * shape to only look at the remaining elements */ if (nreduce_axes == 1) { strides = PyArray_STRIDES(op_view); for (idim = 0; idim < ndim; ++idim) { if (axis_flags[idim]) { shape[idim] = shape_orig[idim] - 1; ((PyArrayObject_fields *)op_view)->data += strides[idim]; } } } /* If there are zero reduction axes, make the view empty */ else if (nreduce_axes == 0) { for (idim = 0; idim < ndim; ++idim) { shape[idim] = 0; } } /* * Otherwise iterate over the whole operand, but tell the inner loop * to skip the elements we already copied by setting the skip_first_count. */ else { *out_skip_first_count = PyArray_SIZE(result); Py_DECREF(op_view); Py_INCREF(operand); op_view = operand; } return op_view; }
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; }
/* * This function executes all the standard NumPy reduction function * boilerplate code, just calling assign_identity and the appropriate * inner loop function where necessary. * * operand : The array to be reduced. * out : NULL, or the array into which to place the result. * wheremask : NOT YET SUPPORTED, but this parameter is placed here * so that support can be added in the future without breaking * API compatibility. Pass in NULL. * operand_dtype : The dtype the inner loop expects for the operand. * result_dtype : The dtype the inner loop expects for the result. * casting : The casting rule to apply to the operands. * axis_flags : Flags indicating the reduction axes of 'operand'. * reorderable : If True, the reduction being done is reorderable, which * means specifying multiple axes of reduction at once is ok, * and the reduction code may calculate the reduction in an * arbitrary order. The calculation may be reordered because * of cache behavior or multithreading requirements. * keepdims : If true, leaves the reduction dimensions in the result * with size one. * subok : If true, the result uses the subclass of operand, otherwise * it is always a base class ndarray. * assign_identity : If NULL, PyArray_InitializeReduceResult is used, otherwise * this function is called to initialize the result to * the reduction's unit. * loop : The loop which does the reduction. * data : Data which is passed to assign_identity and the inner loop. * buffersize : Buffer size for the iterator. For the default, pass in 0. * funcname : The name of the reduction function, for error messages. * * TODO FIXME: if you squint, this is essentially an second independent * implementation of generalized ufuncs with signature (i)->(), plus a few * extra bells and whistles. (Indeed, as far as I can tell, it was originally * split out to support a fancy version of count_nonzero... which is not * actually a reduction function at all, it's just a (i)->() function!) So * probably these two implementation should be merged into one. (In fact it * would be quite nice to support axis= and keepdims etc. for arbitrary * generalized ufuncs!) */ NPY_NO_EXPORT PyArrayObject * PyUFunc_ReduceWrapper(PyArrayObject *operand, PyArrayObject *out, PyArrayObject *wheremask, PyArray_Descr *operand_dtype, PyArray_Descr *result_dtype, NPY_CASTING casting, npy_bool *axis_flags, int reorderable, int keepdims, int subok, PyArray_AssignReduceIdentityFunc *assign_identity, PyArray_ReduceLoopFunc *loop, void *data, npy_intp buffersize, const char *funcname) { PyArrayObject *result = NULL, *op_view = NULL; npy_intp skip_first_count = 0; /* Iterator parameters */ NpyIter *iter = NULL; PyArrayObject *op[2]; PyArray_Descr *op_dtypes[2]; npy_uint32 flags, op_flags[2]; /* Validate that the parameters for future expansion are NULL */ if (wheremask != NULL) { PyErr_SetString(PyExc_RuntimeError, "Reduce operations in NumPy do not yet support " "a where mask"); return NULL; } /* * This either conforms 'out' to the ndim of 'operand', or allocates * a new array appropriate for this reduction. */ Py_INCREF(result_dtype); result = PyArray_CreateReduceResult(operand, out, result_dtype, axis_flags, keepdims, subok, funcname); if (result == NULL) { goto fail; } /* * Initialize the result to the reduction unit if possible, * otherwise copy the initial values and get a view to the rest. */ if (assign_identity != NULL) { /* * If this reduction is non-reorderable, make sure there are * only 0 or 1 axes in axis_flags. */ if (!reorderable && check_nonreorderable_axes(PyArray_NDIM(operand), axis_flags, funcname) < 0) { goto fail; } if (assign_identity(result, data) < 0) { goto fail; } op_view = operand; Py_INCREF(op_view); } else { op_view = PyArray_InitializeReduceResult(result, operand, axis_flags, reorderable, &skip_first_count, funcname); if (op_view == NULL) { goto fail; } if (PyArray_SIZE(op_view) == 0) { Py_DECREF(op_view); op_view = NULL; goto finish; } } /* Set up the iterator */ op[0] = result; op[1] = op_view; op_dtypes[0] = result_dtype; op_dtypes[1] = operand_dtype; flags = NPY_ITER_BUFFERED | NPY_ITER_EXTERNAL_LOOP | NPY_ITER_GROWINNER | NPY_ITER_DONT_NEGATE_STRIDES | NPY_ITER_ZEROSIZE_OK | NPY_ITER_REDUCE_OK | NPY_ITER_REFS_OK; op_flags[0] = NPY_ITER_READWRITE | NPY_ITER_ALIGNED | NPY_ITER_NO_SUBTYPE; op_flags[1] = NPY_ITER_READONLY | NPY_ITER_ALIGNED; iter = NpyIter_AdvancedNew(2, op, flags, NPY_KEEPORDER, casting, op_flags, op_dtypes, 0, NULL, NULL, buffersize); if (iter == NULL) { goto fail; } if (NpyIter_GetIterSize(iter) != 0) { NpyIter_IterNextFunc *iternext; char **dataptr; npy_intp *strideptr; npy_intp *countptr; int needs_api; iternext = NpyIter_GetIterNext(iter, NULL); if (iternext == NULL) { goto fail; } dataptr = NpyIter_GetDataPtrArray(iter); strideptr = NpyIter_GetInnerStrideArray(iter); countptr = NpyIter_GetInnerLoopSizePtr(iter); needs_api = NpyIter_IterationNeedsAPI(iter); /* Straightforward reduction */ if (loop == NULL) { PyErr_Format(PyExc_RuntimeError, "reduction operation %s did not supply an " "inner loop function", funcname); goto fail; } if (loop(iter, dataptr, strideptr, countptr, iternext, needs_api, skip_first_count, data) < 0) { goto fail; } } NpyIter_Deallocate(iter); Py_DECREF(op_view); finish: /* Strip out the extra 'one' dimensions in the result */ if (out == NULL) { if (!keepdims) { PyArray_RemoveAxesInPlace(result, axis_flags); } } else { Py_DECREF(result); result = out; Py_INCREF(result); } return result; fail: Py_XDECREF(result); Py_XDECREF(op_view); if (iter != NULL) { NpyIter_Deallocate(iter); } return NULL; }
static PyObject *Py_FindObjects(PyObject *obj, PyObject *args) { PyArrayObject *input = NULL; PyObject *result = NULL, *tuple = NULL, *start = NULL, *end = NULL; PyObject *slc = NULL; int jj; npy_intp max_label; npy_intp ii, *regions = NULL; if (!PyArg_ParseTuple(args, "O&n", NI_ObjectToInputArray, &input, &max_label)) goto exit; if (max_label < 0) max_label = 0; if (max_label > 0) { if (PyArray_NDIM(input) > 0) { regions = (npy_intp*)malloc(2 * max_label * PyArray_NDIM(input) * sizeof(npy_intp)); } else { regions = (npy_intp*)malloc(max_label * sizeof(npy_intp)); } if (!regions) { PyErr_NoMemory(); goto exit; } } if (!NI_FindObjects(input, max_label, regions)) goto exit; result = PyList_New(max_label); if (!result) { PyErr_NoMemory(); goto exit; } for(ii = 0; ii < max_label; ii++) { npy_intp idx = PyArray_NDIM(input) > 0 ? 2 * PyArray_NDIM(input) * ii : ii; if (regions[idx] >= 0) { PyObject *tuple = PyTuple_New(PyArray_NDIM(input)); if (!tuple) { PyErr_NoMemory(); goto exit; } for(jj = 0; jj < PyArray_NDIM(input); jj++) { start = PyLong_FromSsize_t(regions[idx + jj]); end = PyLong_FromSsize_t(regions[idx + jj + PyArray_NDIM(input)]); if (!start || !end) { PyErr_NoMemory(); goto exit; } slc = PySlice_New(start, end, NULL); if (!slc) { PyErr_NoMemory(); goto exit; } Py_XDECREF(start); Py_XDECREF(end); start = end = NULL; PyTuple_SetItem(tuple, jj, slc); slc = NULL; } PyList_SetItem(result, ii, tuple); tuple = NULL; } else { Py_INCREF(Py_None); PyList_SetItem(result, ii, Py_None); } } Py_INCREF(result); exit: Py_XDECREF(input); Py_XDECREF(result); Py_XDECREF(tuple); Py_XDECREF(start); Py_XDECREF(end); Py_XDECREF(slc); free(regions); if (PyErr_Occurred()) { Py_XDECREF(result); return NULL; } else { return result; } }
/* * Conforms an output parameter 'out' to have 'ndim' dimensions * with dimensions of size one added in the appropriate places * indicated by 'axis_flags'. * * The return value is a view into 'out'. */ static PyArrayObject * conform_reduce_result(int ndim, npy_bool *axis_flags, PyArrayObject *out, int keepdims, const char *funcname) { npy_intp strides[NPY_MAXDIMS], shape[NPY_MAXDIMS]; npy_intp *strides_out = PyArray_STRIDES(out); npy_intp *shape_out = PyArray_DIMS(out); int idim, idim_out, ndim_out = PyArray_NDIM(out); PyArray_Descr *dtype; PyArrayObject_fields *ret; /* * If the 'keepdims' parameter is true, do a simpler validation and * return a new reference to 'out'. */ if (keepdims) { if (PyArray_NDIM(out) != ndim) { PyErr_Format(PyExc_ValueError, "output parameter for reduction operation %s " "has the wrong number of dimensions (must match " "the operand's when keepdims=True)", funcname); return NULL; } for (idim = 0; idim < ndim; ++idim) { if (axis_flags[idim]) { if (shape_out[idim] != 1) { PyErr_Format(PyExc_ValueError, "output parameter for reduction operation %s " "has a reduction dimension not equal to one " "(required when keepdims=True)", funcname); return NULL; } } } Py_INCREF(out); return out; } /* Construct the strides and shape */ idim_out = 0; for (idim = 0; idim < ndim; ++idim) { if (axis_flags[idim]) { strides[idim] = 0; shape[idim] = 1; } else { if (idim_out >= ndim_out) { PyErr_Format(PyExc_ValueError, "output parameter for reduction operation %s " "does not have enough dimensions", funcname); return NULL; } strides[idim] = strides_out[idim_out]; shape[idim] = shape_out[idim_out]; ++idim_out; } } if (idim_out != ndim_out) { PyErr_Format(PyExc_ValueError, "output parameter for reduction operation %s " "has too many dimensions", funcname); return NULL; } /* Allocate the view */ dtype = PyArray_DESCR(out); Py_INCREF(dtype); ret = (PyArrayObject_fields *)PyArray_NewFromDescr(&PyArray_Type, dtype, ndim, shape, strides, PyArray_DATA(out), PyArray_FLAGS(out), NULL); if (ret == NULL) { return NULL; } Py_INCREF(out); if (PyArray_SetBaseObject((PyArrayObject *)ret, (PyObject *)out) < 0) { Py_DECREF(ret); return NULL; } return (PyArrayObject *)ret; }
/*NUMPY_API * ArgMax */ NPY_NO_EXPORT PyObject * PyArray_ArgMax(PyArrayObject *op, int axis, PyArrayObject *out) { PyArrayObject *ap = NULL, *rp = NULL; PyArray_ArgFunc* arg_func; char *ip; npy_intp *rptr; npy_intp i, n, m; int elsize; NPY_BEGIN_THREADS_DEF; if ((ap = (PyArrayObject *)PyArray_CheckAxis(op, &axis, 0)) == NULL) { return NULL; } /* * We need to permute the array so that axis is placed at the end. * And all other dimensions are shifted left. */ if (axis != PyArray_NDIM(ap)-1) { PyArray_Dims newaxes; npy_intp dims[NPY_MAXDIMS]; int j; newaxes.ptr = dims; newaxes.len = PyArray_NDIM(ap); for (j = 0; j < axis; j++) { dims[j] = j; } for (j = axis; j < PyArray_NDIM(ap) - 1; j++) { dims[j] = j + 1; } dims[PyArray_NDIM(ap) - 1] = axis; op = (PyArrayObject *)PyArray_Transpose(ap, &newaxes); Py_DECREF(ap); if (op == NULL) { return NULL; } } else { op = ap; } /* Will get native-byte order contiguous copy. */ ap = (PyArrayObject *)PyArray_ContiguousFromAny((PyObject *)op, PyArray_DESCR(op)->type_num, 1, 0); Py_DECREF(op); if (ap == NULL) { return NULL; } arg_func = PyArray_DESCR(ap)->f->argmax; if (arg_func == NULL) { PyErr_SetString(PyExc_TypeError, "data type not ordered"); goto fail; } elsize = PyArray_DESCR(ap)->elsize; m = PyArray_DIMS(ap)[PyArray_NDIM(ap)-1]; if (m == 0) { PyErr_SetString(PyExc_ValueError, "attempt to get argmax of an empty sequence"); goto fail; } if (!out) { rp = (PyArrayObject *)PyArray_New(Py_TYPE(ap), PyArray_NDIM(ap)-1, PyArray_DIMS(ap), NPY_INTP, NULL, NULL, 0, 0, (PyObject *)ap); if (rp == NULL) { goto fail; } } else { if ((PyArray_NDIM(out) != PyArray_NDIM(ap) - 1) || !PyArray_CompareLists(PyArray_DIMS(out), PyArray_DIMS(ap), PyArray_NDIM(out))) { PyErr_SetString(PyExc_ValueError, "output array does not match result of np.argmax."); goto fail; } rp = (PyArrayObject *)PyArray_FromArray(out, PyArray_DescrFromType(NPY_INTP), NPY_ARRAY_CARRAY | NPY_ARRAY_UPDATEIFCOPY); if (rp == NULL) { goto fail; } } NPY_BEGIN_THREADS_DESCR(PyArray_DESCR(ap)); n = PyArray_SIZE(ap)/m; rptr = (npy_intp *)PyArray_DATA(rp); for (ip = PyArray_DATA(ap), i = 0; i < n; i++, ip += elsize*m) { arg_func(ip, m, rptr, ap); rptr += 1; } NPY_END_THREADS_DESCR(PyArray_DESCR(ap)); Py_DECREF(ap); /* Trigger the UPDATEIFCOPY if necessary */ if (out != NULL && out != rp) { Py_DECREF(rp); rp = out; Py_INCREF(rp); } return (PyObject *)rp; fail: Py_DECREF(ap); Py_XDECREF(rp); return NULL; }
NPY_NO_EXPORT int PyArray_WeekMaskConverter(PyObject *weekmask_in, npy_bool *weekmask) { PyObject *obj = weekmask_in; /* Make obj into an ASCII string if it is UNICODE */ Py_INCREF(obj); if (PyUnicode_Check(obj)) { /* accept unicode input */ PyObject *obj_str; obj_str = PyUnicode_AsASCIIString(obj); if (obj_str == NULL) { Py_DECREF(obj); return 0; } Py_DECREF(obj); obj = obj_str; } if (PyBytes_Check(obj)) { char *str; Py_ssize_t len; int i; if (PyBytes_AsStringAndSize(obj, &str, &len) < 0) { Py_DECREF(obj); return 0; } /* Length 7 is a string like "1111100" */ if (len == 7) { for (i = 0; i < 7; ++i) { switch(str[i]) { case '0': weekmask[i] = 0; break; case '1': weekmask[i] = 1; break; default: goto general_weekmask_string; } } goto finish; } general_weekmask_string: /* a string like "SatSun" or "Mon Tue Wed" */ memset(weekmask, 0, 7); for (i = 0; i < len; i += 3) { while (isspace(str[i])) ++i; if (i == len) { goto finish; } else if (i + 2 >= len) { goto invalid_weekmask_string; } switch (str[i]) { case 'M': if (str[i+1] == 'o' && str[i+2] == 'n') { weekmask[0] = 1; } else { goto invalid_weekmask_string; } break; case 'T': if (str[i+1] == 'u' && str[i+2] == 'e') { weekmask[1] = 1; } else if (str[i+1] == 'h' && str[i+2] == 'u') { weekmask[3] = 1; } else { goto invalid_weekmask_string; } break; case 'W': if (str[i+1] == 'e' && str[i+2] == 'd') { weekmask[2] = 1; } else { goto invalid_weekmask_string; } break; case 'F': if (str[i+1] == 'r' && str[i+2] == 'i') { weekmask[4] = 1; } else { goto invalid_weekmask_string; } break; case 'S': if (str[i+1] == 'a' && str[i+2] == 't') { weekmask[5] = 1; } else if (str[i+1] == 'u' && str[i+2] == 'n') { weekmask[6] = 1; } else { goto invalid_weekmask_string; } break; default: goto invalid_weekmask_string; } } goto finish; invalid_weekmask_string: PyErr_Format(PyExc_ValueError, "Invalid business day weekmask string \"%s\"", str); Py_DECREF(obj); return 0; } /* Something like [1,1,1,1,1,0,0] */ else if (PySequence_Check(obj)) { if (PySequence_Size(obj) != 7 || (PyArray_Check(obj) && PyArray_NDIM((PyArrayObject *)obj) != 1)) { PyErr_SetString(PyExc_ValueError, "A business day weekmask array must have length 7"); Py_DECREF(obj); return 0; } else { int i; PyObject *f; for (i = 0; i < 7; ++i) { long val; f = PySequence_GetItem(obj, i); if (f == NULL) { Py_DECREF(obj); return 0; } val = PyInt_AsLong(f); if (val == -1 && PyErr_Occurred()) { Py_DECREF(obj); return 0; } if (val == 0) { weekmask[i] = 0; } else if (val == 1) { weekmask[i] = 1; } else { PyErr_SetString(PyExc_ValueError, "A business day weekmask array must have all " "1's and 0's"); Py_DECREF(obj); return 0; } } goto finish; } } PyErr_SetString(PyExc_ValueError, "Couldn't convert object into a business day weekmask"); Py_DECREF(obj); return 0; finish: Py_DECREF(obj); return 1; }
/*NUMPY_API * Clip */ NPY_NO_EXPORT PyObject * PyArray_Clip(PyArrayObject *self, PyObject *min, PyObject *max, PyArrayObject *out) { PyArray_FastClipFunc *func; int outgood = 0, ingood = 0; PyArrayObject *maxa = NULL; PyArrayObject *mina = NULL; PyArrayObject *newout = NULL, *newin = NULL; PyArray_Descr *indescr = NULL, *newdescr = NULL; char *max_data, *min_data; PyObject *zero; /* Treat None the same as NULL */ if (min == Py_None) { min = NULL; } if (max == Py_None) { max = NULL; } if ((max == NULL) && (min == NULL)) { PyErr_SetString(PyExc_ValueError, "array_clip: must set either max or min"); return NULL; } func = PyArray_DESCR(self)->f->fastclip; if (func == NULL || (min != NULL && !PyArray_CheckAnyScalar(min)) || (max != NULL && !PyArray_CheckAnyScalar(max))) { return _slow_array_clip(self, min, max, out); } /* Use the fast scalar clip function */ /* First we need to figure out the correct type */ if (min != NULL) { indescr = PyArray_DescrFromObject(min, NULL); if (indescr == NULL) { goto fail; } } if (max != NULL) { newdescr = PyArray_DescrFromObject(max, indescr); Py_XDECREF(indescr); indescr = NULL; if (newdescr == NULL) { goto fail; } } else { /* Steal the reference */ newdescr = indescr; indescr = NULL; } /* * Use the scalar descriptor only if it is of a bigger * KIND than the input array (and then find the * type that matches both). */ if (PyArray_ScalarKind(newdescr->type_num, NULL) > PyArray_ScalarKind(PyArray_DESCR(self)->type_num, NULL)) { indescr = PyArray_PromoteTypes(newdescr, PyArray_DESCR(self)); if (indescr == NULL) { goto fail; } func = indescr->f->fastclip; if (func == NULL) { Py_DECREF(indescr); return _slow_array_clip(self, min, max, out); } } else { indescr = PyArray_DESCR(self); Py_INCREF(indescr); } Py_DECREF(newdescr); newdescr = NULL; if (!PyDataType_ISNOTSWAPPED(indescr)) { PyArray_Descr *descr2; descr2 = PyArray_DescrNewByteorder(indescr, '='); Py_DECREF(indescr); indescr = NULL; if (descr2 == NULL) { goto fail; } indescr = descr2; } /* Convert max to an array */ if (max != NULL) { Py_INCREF(indescr); maxa = (PyArrayObject *)PyArray_FromAny(max, indescr, 0, 0, NPY_ARRAY_DEFAULT, NULL); if (maxa == NULL) { goto fail; } } /* * If we are unsigned, then make sure min is not < 0 * This is to match the behavior of _slow_array_clip * * We allow min and max to go beyond the limits * for other data-types in which case they * are interpreted as their modular counterparts. */ if (min != NULL) { if (PyArray_ISUNSIGNED(self)) { int cmp; zero = PyInt_FromLong(0); cmp = PyObject_RichCompareBool(min, zero, Py_LT); if (cmp == -1) { Py_DECREF(zero); goto fail; } if (cmp == 1) { min = zero; } else { Py_DECREF(zero); Py_INCREF(min); } } else { Py_INCREF(min); } /* Convert min to an array */ Py_INCREF(indescr); mina = (PyArrayObject *)PyArray_FromAny(min, indescr, 0, 0, NPY_ARRAY_DEFAULT, NULL); Py_DECREF(min); if (mina == NULL) { goto fail; } } /* * Check to see if input is single-segment, aligned, * and in native byteorder */ if (PyArray_ISONESEGMENT(self) && PyArray_CHKFLAGS(self, NPY_ARRAY_ALIGNED) && PyArray_ISNOTSWAPPED(self) && (PyArray_DESCR(self) == indescr)) { ingood = 1; } if (!ingood) { int flags; if (PyArray_ISFORTRAN(self)) { flags = NPY_ARRAY_FARRAY; } else { flags = NPY_ARRAY_CARRAY; } Py_INCREF(indescr); newin = (PyArrayObject *)PyArray_FromArray(self, indescr, flags); if (newin == NULL) { goto fail; } } else { newin = self; Py_INCREF(newin); } /* * At this point, newin is a single-segment, aligned, and correct * byte-order array of the correct type * * if ingood == 0, then it is a copy, otherwise, * it is the original input. */ /* * If we have already made a copy of the data, then use * that as the output array */ if (out == NULL && !ingood) { out = newin; } /* * Now, we know newin is a usable array for fastclip, * we need to make sure the output array is available * and usable */ if (out == NULL) { Py_INCREF(indescr); out = (PyArrayObject*)PyArray_NewFromDescr(Py_TYPE(self), indescr, PyArray_NDIM(self), PyArray_DIMS(self), NULL, NULL, PyArray_ISFORTRAN(self), (PyObject *)self); if (out == NULL) { goto fail; } outgood = 1; } else Py_INCREF(out); /* Input is good at this point */ if (out == newin) { outgood = 1; } if (!outgood && PyArray_ISONESEGMENT(out) && PyArray_CHKFLAGS(out, NPY_ARRAY_ALIGNED) && PyArray_ISNOTSWAPPED(out) && PyArray_EquivTypes(PyArray_DESCR(out), indescr)) { outgood = 1; } /* * Do we still not have a suitable output array? * Create one, now */ if (!outgood) { int oflags; if (PyArray_ISFORTRAN(out)) oflags = NPY_ARRAY_FARRAY; else oflags = NPY_ARRAY_CARRAY; oflags |= NPY_ARRAY_UPDATEIFCOPY | NPY_ARRAY_FORCECAST; Py_INCREF(indescr); newout = (PyArrayObject*)PyArray_FromArray(out, indescr, oflags); if (newout == NULL) { goto fail; } } else { newout = out; Py_INCREF(newout); } /* make sure the shape of the output array is the same */ if (!PyArray_SAMESHAPE(newin, newout)) { PyErr_SetString(PyExc_ValueError, "clip: Output array must have the" "same shape as the input."); goto fail; } if (PyArray_DATA(newout) != PyArray_DATA(newin)) { if (PyArray_AssignArray(newout, newin, NULL, NPY_DEFAULT_ASSIGN_CASTING) < 0) { goto fail; } } /* Now we can call the fast-clip function */ min_data = max_data = NULL; if (mina != NULL) { min_data = PyArray_DATA(mina); } if (maxa != NULL) { max_data = PyArray_DATA(maxa); } func(PyArray_DATA(newin), PyArray_SIZE(newin), min_data, max_data, PyArray_DATA(newout)); /* Clean up temporary variables */ Py_XDECREF(indescr); Py_XDECREF(newdescr); Py_XDECREF(mina); Py_XDECREF(maxa); Py_DECREF(newin); /* Copy back into out if out was not already a nice array. */ Py_DECREF(newout); return (PyObject *)out; fail: Py_XDECREF(indescr); Py_XDECREF(newdescr); Py_XDECREF(maxa); Py_XDECREF(mina); Py_XDECREF(newin); PyArray_XDECREF_ERR(newout); return NULL; }
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); }