double npy_hypot(double x, double y) { double yx; if (npy_isinf(x) || npy_isinf(y)) { return NPY_INFINITY; } if (npy_isnan(x) || npy_isnan(y)) { return NPY_NAN; } x = npy_fabs(x); y = npy_fabs(y); if (x < y) { double temp = x; x = y; y = temp; } if (x == 0.) { return 0.; } else { yx = y/x; return x*npy_sqrt(1.+yx*yx); } }
npy_cdouble cbesh_wrap2_e( double v, npy_cdouble z) { int n = 1; int kode = 2; int m = 2; int nz, ierr; int sign = 1; npy_cdouble cy; cy.real = NPY_NAN; cy.imag = NPY_NAN; if (npy_isnan(v) || npy_isnan(z.real) || npy_isnan(z.imag)) { return cy; } if (v < 0) { v = -v; sign = -1; } F_FUNC(zbesh,ZBESH)(CADDR(z), &v, &kode, &m, &n, CADDR(cy), &nz, &ierr); DO_SFERR("hankel2e:", &cy); if (sign == -1) { cy = rotate(cy, -v); } return cy; }
npy_cdouble cbesk_wrap_e( double v, npy_cdouble z) { int n = 1; int kode = 2; int nz, ierr; npy_cdouble cy; cy.real = NPY_NAN; cy.imag = NPY_NAN; if (npy_isnan(v) || npy_isnan(z.real) || npy_isnan(z.imag)) { return cy; } if (v < 0) { /* K_v == K_{-v} even for non-integer v */ v = -v; } F_FUNC(zbesk,ZBESK)(CADDR(z), &v, &kode, &n, CADDR(cy), &nz, &ierr); DO_SFERR("kve:", &cy); if (ierr == 2) { if (z.real >= 0 && z.imag == 0) { /* overflow */ cy.real = NPY_INFINITY; cy.imag = 0; } } return cy; }
int pbdv_wrap(double v, double x, double *pdf, double *pdd) { double *dv; double *dp; int num; if (npy_isnan(v) || npy_isnan(x)) { *pdf = NPY_NAN; *pdd = NPY_NAN; return 0; } /* NB. Indexing of DV/DP in specfun.f:PBDV starts from 0, hence +2 */ num = ABS((int)v) + 2; dv = (double *)PyMem_Malloc(sizeof(double)*2*num); if (dv==NULL) { sf_error("pbdv", SF_ERROR_OTHER, "memory allocation error"); *pdf = NPY_NAN; *pdd = NPY_NAN; return -1; } dp = dv + num; F_FUNC(pbdv,PBDV)(&v, &x, dv, dp, pdf, pdd); PyMem_Free(dv); return 0; }
npy_cdouble cbesj_wrap_e( double v, npy_cdouble z) { int n = 1; int kode = 2; int nz, ierr; int sign = 1; npy_cdouble cy_j, cy_y, cwork; cy_j.real = NPY_NAN; cy_j.imag = NPY_NAN; cy_y.real = NPY_NAN; cy_y.imag = NPY_NAN; if (npy_isnan(v) || npy_isnan(z.real) || npy_isnan(z.imag)) { return cy_j; } if (v < 0) { v = -v; sign = -1; } F_FUNC(zbesj,ZBESJ)(CADDR(z), &v, &kode, &n, CADDR(cy_j), &nz, &ierr); DO_SFERR("jve:", &cy_j); if (sign == -1) { if (!reflect_jy(&cy_j, v)) { F_FUNC(zbesy,ZBESY)(CADDR(z), &v, &kode, &n, CADDR(cy_y), &nz, CADDR(cwork), &ierr); DO_SFERR("jve(yve):", &cy_y); cy_j = rotate_jy(cy_j, cy_y, v); } } return cy_j; }
double ndtr(double a) { double x, y, z; if (npy_isnan(a)) { mtherr("ndtr", DOMAIN); return (NPY_NAN); } x = a * SQRTH; z = fabs(x); if( z < SQRTH ) y = 0.5 + 0.5 * erf(x); else { y = 0.5 * erfc(z); if( x > 0 ) y = 1.0 - y; } return(y); }
npy_cdouble cbesy_wrap( double v, npy_cdouble z) { int n = 1; int kode = 1; int nz, ierr; int sign = 1; npy_cdouble cy_y, cy_j, cwork; cy_j.real = NPY_NAN; cy_j.imag = NPY_NAN; cy_y.real = NPY_NAN; cy_y.imag = NPY_NAN; if (npy_isnan(v) || npy_isnan(z.real) || npy_isnan(z.imag)) { return cy_y; } if (v < 0) { v = -v; sign = -1; } if (z.real == 0 && z.imag == 0) { /* overflow */ cy_y.real = -NPY_INFINITY; cy_y.imag = 0; sf_error("yv", SF_ERROR_OVERFLOW, NULL); } else { F_FUNC(zbesy,ZBESY)(CADDR(z), &v, &kode, &n, CADDR(cy_y), &nz, CADDR(cwork), &ierr); DO_SFERR("yv:", &cy_y); if (ierr == 2) { if (z.real >= 0 && z.imag == 0) { /* overflow */ cy_y.real = -NPY_INFINITY; cy_y.imag = 0; } } } if (sign == -1) { if (!reflect_jy(&cy_y, v)) { F_FUNC(zbesj,ZBESJ)(CADDR(z), &v, &kode, &n, CADDR(cy_j), &nz, &ierr); DO_SFERR("yv(jv):", &cy_j); cy_y = rotate_jy(cy_y, cy_j, -v); } } return cy_y; }
npy_cdouble cbesi_wrap( double v, npy_cdouble z) { int n = 1; int kode = 1; int sign = 1; int nz, ierr; npy_cdouble cy, cy_k; cy.real = NPY_NAN; cy.imag = NPY_NAN; cy_k.real = NPY_NAN; cy_k.imag = NPY_NAN; if (npy_isnan(v) || npy_isnan(z.real) || npy_isnan(z.imag)) { return cy; } if (v < 0) { v = -v; sign = -1; } F_FUNC(zbesi,ZBESI)(CADDR(z), &v, &kode, &n, CADDR(cy), &nz, &ierr); DO_SFERR("iv:", &cy); if (ierr == 2) { /* overflow */ if (z.imag == 0 && (z.real >= 0 || v == floor(v))) { if (z.real < 0 && v/2 != floor(v/2)) cy.real = -NPY_INFINITY; else cy.real = NPY_INFINITY; cy.imag = 0; } else { cy = cbesi_wrap_e(v*sign, z); cy.real *= NPY_INFINITY; cy.imag *= NPY_INFINITY; } } if (sign == -1) { if (!reflect_i(&cy, v)) { F_FUNC(zbesk,ZBESK)(CADDR(z), &v, &kode, &n, CADDR(cy_k), &nz, &ierr); DO_SFERR("iv(kv):", &cy_k); cy = rotate_i(cy, cy_k, v); } } return cy; }
double igami(double a, double p) { int i; double x, fac, f_fp, fpp_fp; if (npy_isnan(a) || npy_isnan(p)) { return NPY_NAN; } else if ((a < 0) || (p < 0) || (p > 1)) { mtherr("gammaincinv", DOMAIN); } else if (p == 0.0) { return 0.0; } else if (p == 1.0) { return NPY_INFINITY; } else if (p > 0.9) { return igamci(a, 1 - p); } x = find_inverse_gamma(a, p, 1 - p); /* Halley's method */ for (i = 0; i < 3; i++) { fac = igam_fac(a, x); if (fac == 0.0) { return x; } f_fp = (igam(a, x) - p) * x / fac; /* The ratio of the first and second derivatives simplifies */ fpp_fp = -1.0 + (a - 1) / x; if (npy_isinf(fpp_fp)) { /* Resort to Newton's method in the case of overflow */ x = x - f_fp; } else { x = x - f_fp / (1.0 - 0.5 * f_fp * fpp_fp); } } return x; }
npy_cdouble cbesi_wrap_e( double v, npy_cdouble z) { int n = 1; int kode = 2; int sign = 1; int nz, ierr; npy_cdouble cy, cy_k; cy.real = NPY_NAN; cy.imag = NPY_NAN; cy_k.real = NPY_NAN; cy_k.imag = NPY_NAN; if (npy_isnan(v) || npy_isnan(z.real) || npy_isnan(z.imag)) { return cy; } if (v < 0) { v = -v; sign = -1; } F_FUNC(zbesi,ZBESI)(CADDR(z), &v, &kode, &n, CADDR(cy), &nz, &ierr); DO_SFERR("ive:", &cy); if (sign == -1) { if (!reflect_i(&cy, v)) { F_FUNC(zbesk,ZBESK)(CADDR(z), &v, &kode, &n, CADDR(cy_k), &nz, &ierr); DO_SFERR("ive(kv):", &cy_k); /* adjust scaling to match zbesi */ cy_k = rotate(cy_k, -z.imag/NPY_PI); if (z.real > 0) { cy_k.real *= exp(-2*z.real); cy_k.imag *= exp(-2*z.real); } /* v -> -v */ cy = rotate_i(cy, cy_k, v); } } return cy; }
double igamci(double a, double q) { int i; double x, fac, f_fp, fpp_fp; if (npy_isnan(a) || npy_isnan(q)) { return NPY_NAN; } else if ((a < 0.0) || (q < 0.0) || (q > 1.0)) { mtherr("gammainccinv", DOMAIN); } else if (q == 0.0) { return NPY_INFINITY; } else if (q == 1.0) { return 0.0; } else if (q > 0.9) { return igami(a, 1 - q); } x = find_inverse_gamma(a, 1 - q, q); for (i = 0; i < 3; i++) { fac = igam_fac(a, x); if (fac == 0.0) { return x; } f_fp = (igamc(a, x) - q) * x / (-fac); fpp_fp = -1.0 + (a - 1) / x; if (npy_isinf(fpp_fp)) { x = x - f_fp; } else { x = x - f_fp / (1.0 - 0.5 * f_fp * fpp_fp); } } return x; }
double erfc(double a) { double p,q,x,y,z; if (npy_isnan(a)) { mtherr("erfc", DOMAIN); return (NPY_NAN); } if( a < 0.0 ) x = -a; else x = a; if( x < 1.0 ) return( 1.0 - erf(a) ); z = -a * a; if( z < -MAXLOG ) { under: mtherr( "erfc", UNDERFLOW ); if( a < 0 ) return( 2.0 ); else return( 0.0 ); } z = exp(z); if( x < 8.0 ) { p = polevl( x, P, 8 ); q = p1evl( x, Q, 8 ); } else { p = polevl( x, R, 5 ); q = p1evl( x, S, 6 ); } y = (z * p)/q; if( a < 0 ) y = 2.0 - y; if( y == 0.0 ) goto under; return(y); }
int pbvv_wrap(double v, double x, double *pvf, double *pvd) { double *vv; double *vp; int num; if (npy_isnan(v) || npy_isnan(x)) { *pvf = NPY_NAN; *pvd = NPY_NAN; return 0; } /* NB. Indexing of DV/DP in specfun.f:PBVV starts from 0, hence +2 */ num = ABS((int)v) + 2; vv = (double *)PyMem_Malloc(sizeof(double)*2*num); if (vv==NULL) { sf_error("pbvv", SF_ERROR_OTHER, "memory allocation error"); *pvf = NPY_NAN; *pvd = NPY_NAN; return -1; } vp = vv + num; F_FUNC(pbvv,PBVV)(&v, &x, vv, vp, pvf, pvd); PyMem_Free(vv); return 0; }
double erf(double x) { double y, z; if (npy_isnan(x)) { mtherr("erf", DOMAIN); return (NPY_NAN); } if( fabs(x) > 1.0 ) return( 1.0 - erfc(x) ); z = x * x; y = x * polevl( z, T, 4 ) / p1evl( z, U, 5 ); return( y ); }
double exp10(double x) { double px, xx; short n; if (npy_isnan(x)) return (x); if (x > MAXL10) { return (NPY_INFINITY); } if (x < -MAXL10) { /* Would like to use MINLOG but can't */ mtherr("exp10", UNDERFLOW); return (0.0); } /* Express 10**x = 10**g 2**n * = 10**g 10**( n log10(2) ) * = 10**( g + n log10(2) ) */ px = floor(LOG210 * x + 0.5); n = px; x -= px * LG102A; x -= px * LG102B; /* rational approximation for exponential * of the fractional part: * 10**x = 1 + 2x P(x**2)/( Q(x**2) - P(x**2) ) */ xx = x * x; px = x * polevl(xx, P, 3); x = px / (p1evl(xx, Q, 3) - px); x = 1.0 + ldexp(x, 1); /* multiply by power of 2 */ x = ldexp(x, n); return (x); }
double exp2(double x) { double px, xx; short n; if( npy_isnan(x) ) return(x); if( x > MAXL2) { return( NPY_INFINITY ); } if( x < MINL2 ) { return(0.0); } xx = x; /* save x */ /* separate into integer and fractional parts */ px = floor(x+0.5); n = px; x = x - px; /* rational approximation * exp2(x) = 1 + 2xP(xx)/(Q(xx) - P(xx)) * where xx = x**2 */ xx = x * x; px = x * polevl( xx, P, 2 ); x = px / ( p1evl( xx, Q, 2 ) - px ); x = 1.0 + ldexp( x, 1 ); /* scale by power of 2 */ x = ldexp( x, n ); return(x); }
int compute_ewa(size_t chan_count, int maximum_weight_mode, size_t swath_cols, size_t swath_rows, size_t grid_cols, size_t grid_rows, CR_TYPE *uimg, CR_TYPE *vimg, IMAGE_TYPE **images, IMAGE_TYPE img_fill, accum_type **grid_accums, weight_type **grid_weights, ewa_weight *ewaw, ewa_parameters *ewap) { // This was originally copied from a cython C file for 32-bit float inputs (that explains some of the weird parens and other syntax int got_point; unsigned int row; unsigned int col; ewa_parameters *this_ewap; int iu1; int iu2; int iv1; int iv2; int iu; int iv; CR_TYPE u0; CR_TYPE v0; weight_type ddq; weight_type dq; weight_type q; weight_type u; weight_type v; weight_type a2up1; weight_type au2; weight_type bu; weight_type weight; // Test: This is how the original fornav did its calculations // double u0; // double v0; // double ddq; // double dq; // double q; // double u; // double v; // double a2up1; // double au2; // double bu; // double weight; // double qfactor; int iw; IMAGE_TYPE this_val; unsigned int swath_offset; unsigned int grid_offset; size_t chan; got_point = 0; for (row = 0, swath_offset=0; row < swath_rows; row+=1) { for (col = 0, this_ewap = ewap; col < swath_cols; col++, this_ewap++, swath_offset++) { u0 = uimg[swath_offset]; v0 = vimg[swath_offset]; if (u0 < 0.0 || v0 < 0.0 || __isnan(u0) || npy_isnan(v0)) { continue; } iu1 = ((int)(u0 - this_ewap->u_del)); iu2 = ((int)(u0 + this_ewap->u_del)); iv1 = ((int)(v0 - this_ewap->v_del)); iv2 = ((int)(v0 + this_ewap->v_del)); if (iu1 < 0) { iu1 = 0; } if (iu2 >= grid_cols) { iu2 = (grid_cols - 1); } if (iv1 < 0) { iv1 = 0; } if (iv2 >= grid_rows) { iv2 = (grid_rows - 1); } if (iu1 < grid_cols && iu2 >= 0 && iv1 < grid_rows && iv2 >= 0) { got_point = 1; ddq = 2.0 * this_ewap->a; u = (iu1 - u0); a2up1 = (this_ewap->a * ((2.0 * u) + 1.0)); bu = this_ewap->b * u; au2 = this_ewap->a * u * u; for (iv = iv1; iv <= iv2; iv++) { v = (iv - v0); dq = (a2up1 + (this_ewap->b * v)); q = ((((this_ewap->c * v) + bu) * v) + au2); for (iu = iu1; iu <= iu2; iu++) { if ((q >= 0.0) && (q < this_ewap->f)) { iw = ((int)(q * ewaw->qfactor)); if (iw >= ewaw->count) { iw = (ewaw->count - 1); } weight = (ewaw->wtab[iw]); grid_offset = ((iv * grid_cols) + iu); for (chan = 0; chan < chan_count; chan+=1) { this_val = ((images[chan])[swath_offset]); if (maximum_weight_mode) { if (weight > grid_weights[chan][grid_offset]) { ((grid_weights[chan])[grid_offset]) = weight; if ((this_val == img_fill) || (__isnan(this_val))) { ((grid_accums[chan])[grid_offset]) = (accum_type)NPY_NANF; } else { ((grid_accums[chan])[grid_offset]) = (accum_type)this_val; } } } else { if ((this_val != img_fill) && !(__isnan(this_val))) { ((grid_weights[chan])[grid_offset]) += weight; ((grid_accums[chan])[grid_offset]) += (accum_type)this_val * weight; } } } } q += dq; dq += ddq; } } } } } /* function exit code */ return got_point; }
NPY_NO_EXPORT PyObject * arr_interp(PyObject *NPY_UNUSED(self), PyObject *args, PyObject *kwdict) { PyObject *fp, *xp, *x; PyObject *left = NULL, *right = NULL; PyArrayObject *afp = NULL, *axp = NULL, *ax = NULL, *af = NULL; npy_intp i, lenx, lenxp; npy_double lval, rval; const npy_double *dy, *dx, *dz; npy_double *dres, *slopes = NULL; static char *kwlist[] = {"x", "xp", "fp", "left", "right", NULL}; NPY_BEGIN_THREADS_DEF; if (!PyArg_ParseTupleAndKeywords(args, kwdict, "OOO|OO", kwlist, &x, &xp, &fp, &left, &right)) { return NULL; } afp = (PyArrayObject *)PyArray_ContiguousFromAny(fp, NPY_DOUBLE, 1, 1); if (afp == NULL) { return NULL; } axp = (PyArrayObject *)PyArray_ContiguousFromAny(xp, NPY_DOUBLE, 1, 1); if (axp == NULL) { goto fail; } ax = (PyArrayObject *)PyArray_ContiguousFromAny(x, NPY_DOUBLE, 1, 0); if (ax == NULL) { goto fail; } lenxp = PyArray_SIZE(axp); if (lenxp == 0) { PyErr_SetString(PyExc_ValueError, "array of sample points is empty"); goto fail; } if (PyArray_SIZE(afp) != lenxp) { PyErr_SetString(PyExc_ValueError, "fp and xp are not of the same length."); goto fail; } af = (PyArrayObject *)PyArray_SimpleNew(PyArray_NDIM(ax), PyArray_DIMS(ax), NPY_DOUBLE); if (af == NULL) { goto fail; } lenx = PyArray_SIZE(ax); dy = (const npy_double *)PyArray_DATA(afp); dx = (const npy_double *)PyArray_DATA(axp); dz = (const npy_double *)PyArray_DATA(ax); dres = (npy_double *)PyArray_DATA(af); /* Get left and right fill values. */ if ((left == NULL) || (left == Py_None)) { lval = dy[0]; } else { lval = PyFloat_AsDouble(left); if ((lval == -1) && PyErr_Occurred()) { goto fail; } } if ((right == NULL) || (right == Py_None)) { rval = dy[lenxp - 1]; } else { rval = PyFloat_AsDouble(right); if ((rval == -1) && PyErr_Occurred()) { goto fail; } } /* binary_search_with_guess needs at least a 3 item long array */ if (lenxp == 1) { const npy_double xp_val = dx[0]; const npy_double fp_val = dy[0]; NPY_BEGIN_THREADS_THRESHOLDED(lenx); for (i = 0; i < lenx; ++i) { const npy_double x_val = dz[i]; dres[i] = (x_val < xp_val) ? lval : ((x_val > xp_val) ? rval : fp_val); } NPY_END_THREADS; } else { npy_intp j = 0; /* only pre-calculate slopes if there are relatively few of them. */ if (lenxp <= lenx) { slopes = PyArray_malloc((lenxp - 1) * sizeof(npy_double)); if (slopes == NULL) { goto fail; } } NPY_BEGIN_THREADS; if (slopes != NULL) { for (i = 0; i < lenxp - 1; ++i) { slopes[i] = (dy[i+1] - dy[i]) / (dx[i+1] - dx[i]); } } for (i = 0; i < lenx; ++i) { const npy_double x_val = dz[i]; if (npy_isnan(x_val)) { dres[i] = x_val; continue; } j = binary_search_with_guess(x_val, dx, lenxp, j); if (j == -1) { dres[i] = lval; } else if (j == lenxp) { dres[i] = rval; } else if (j == lenxp - 1) { dres[i] = dy[j]; } else { const npy_double slope = (slopes != NULL) ? slopes[j] : (dy[j+1] - dy[j]) / (dx[j+1] - dx[j]); dres[i] = slope*(x_val - dx[j]) + dy[j]; } } NPY_END_THREADS; } PyArray_free(slopes); Py_DECREF(afp); Py_DECREF(axp); Py_DECREF(ax); return (PyObject *)af; fail: Py_XDECREF(afp); Py_XDECREF(axp); Py_XDECREF(ax); Py_XDECREF(af); return NULL; }
double npy_atan2(double y, double x) { npy_int32 k, m, iy, ix, hx, hy; npy_uint32 lx,ly; double z; EXTRACT_WORDS(hx, lx, x); ix = hx & 0x7fffffff; EXTRACT_WORDS(hy, ly, y); iy = hy & 0x7fffffff; /* if x or y is nan, return nan */ if (npy_isnan(x * y)) { return x + y; } if (x == 1.0) { return npy_atan(y); } m = 2 * npy_signbit(x) + npy_signbit(y); if (y == 0.0) { switch(m) { case 0: case 1: return y; /* atan(+-0,+anything)=+-0 */ case 2: return NPY_PI;/* atan(+0,-anything) = pi */ case 3: return -NPY_PI;/* atan(-0,-anything) =-pi */ } } if (x == 0.0) { return y > 0 ? NPY_PI_2 : -NPY_PI_2; } if (npy_isinf(x)) { if (npy_isinf(y)) { switch(m) { case 0: return NPY_PI_4;/* atan(+INF,+INF) */ case 1: return -NPY_PI_4;/* atan(-INF,+INF) */ case 2: return 3.0*NPY_PI_4;/*atan(+INF,-INF)*/ case 3: return -3.0*NPY_PI_4;/*atan(-INF,-INF)*/ } } else { switch(m) { case 0: return NPY_PZERO; /* atan(+...,+INF) */ case 1: return NPY_NZERO; /* atan(-...,+INF) */ case 2: return NPY_PI; /* atan(+...,-INF) */ case 3: return -NPY_PI; /* atan(-...,-INF) */ } } } if (npy_isinf(y)) { return y > 0 ? NPY_PI_2 : -NPY_PI_2; } /* compute y/x */ k = (iy - ix) >> 20; if (k > 60) { /* |y/x| > 2**60 */ z = NPY_PI_2 + 0.5 * NPY_DBL_EPSILON; m &= 1; } else if (hx < 0 && k < -60) { z = 0.0; /* 0 > |y|/x > -2**-60 */ } else { z = npy_atan(npy_fabs(y/x)); /* safe to do y/x */ } switch (m) { case 0: return z ; /* atan(+,+) */ case 1: return -z ; /* atan(-,+) */ case 2: return NPY_PI - (z - NPY_DBL_EPSILON);/* atan(+,-) */ default: /* case 3 */ return (z - NPY_DBL_EPSILON) - NPY_PI;/* atan(-,-) */ } }
template<typename IMAGE_TYPE> int __isnan(IMAGE_TYPE x) { // Return numpy's isnan for normal float arguments (see __isnan below for ints) return npy_isnan(x); }