/* ** 0 1 (2) ** bessy <double> */ int main(int argc, char *argv[]) { char *me; double x; int i; me = argv[0]; if (2 != argc || 1 != sscanf(argv[1], "%lg", &x)) { fprintf(stderr, "%s: need one double as argument\n", me); exit(1); } printf("BesselI(0, %g) = %g\n", x, airBesselI0(x)); printf("log(BesselI(0, %g)) = %g ?=? %g\n", x, airLogBesselI0(x), log(airBesselI0(x))); printf("BesselI(1, %g) = %g\n", x, airBesselI1(x)); printf("BesselI1By0(%g) = %g ?=? %g\n", x, airBesselI1By0(x), airBesselI1(x)/airBesselI0(x)); printf("BesselIExpScaled(0, %g) = %f\n", x, airBesselI0ExpScaled(x)); printf("BesselIExpScaled(1, %g) = %f\n", x, airBesselI1ExpScaled(x)); printf("erfc,erf(%g) = %g %g\n", x, airErfc(x), airErf(x)); printf(" n BesselIn(n,%g) BesselInExpScaled(n,%g)\n", x, x); for (i = -10; i<= 10; i++) { printf("%d %g %g\n", i, airBesselIn(i,x), airBesselInExpScaled(i,x)); } exit(0); }
/* ** maxsmooth(m, w, x) is like max(m,x), but starting at value m+w, values ** are raised (via erf), so that the output is asymptotic to m */ static double _nrrdTernaryOpMaxSmooth(double min, double width, double x) { double tran; tran = min + width; return (min < tran /* using the function as intended */ ? (tran < x ? x : airErf((x-tran)*0.886226925452758/(min - tran))*(min - tran) + tran) : AIR_MAX(x, min)); /* transition in wrong place; revert to simple max() */ }
/* ** minsmooth(x, w, M) is like min(x,M), but starting at value M-w, values ** are lowered (via erf), so that the output is asymptotic to M */ static double _nrrdTernaryOpMinSmooth(double x, double width, double max) { double tran; tran = max - width; return (tran < max /* using the function as intended */ ? (x < tran ? x : airErf((x-tran)*0.886226925452758/(max - tran))*(max - tran) + tran) : AIR_MIN(x, max)); /* transition in wrong place; revert to simple max() */ }
void tend_helixDoit(Nrrd *nout, double bnd, double orig[3], double i2w[9], double mf[9], double r, double R, double S, double angle, int incrtwist, double ev[3], double bgEval) { int sx, sy, sz, xi, yi, zi; double th, t0, t1, t2, t3, v1, v2, wpos[3], vpos[3], mfT[9], W2H[9], H2W[9], H2C[9], C2H[9], fv[3], rv[3], uv[3], mA[9], mB[9], inside, tmp[3], len; float *out; sx = nout->axis[1].size; sy = nout->axis[2].size; sz = nout->axis[3].size; out = (float*)nout->data; ELL_3M_TRANSPOSE(mfT, mf); for (zi=0; zi<sz; zi++) { fprintf(stderr, "zi = %d/%d\n", zi, sz); for (yi=0; yi<sy; yi++) { for (xi=0; xi<sx; xi++) { ELL_3V_SET(tmp, xi, yi, zi); ELL_3MV_MUL(vpos, i2w, tmp); ELL_3V_INCR(vpos, orig); #define WPOS(pos, th) ELL_3V_SET((pos),R*cos(th), R*sin(th), S*(th)/(2*AIR_PI)) #define VAL(th) (WPOS(wpos, th), ELL_3V_DIST(wpos, vpos)) #define RR 0.61803399 #define CC (1.0-RR) #define SHIFT3(a,b,c,d) (a)=(b); (b)=(c); (c)=(d) #define SHIFT2(a,b,c) (a)=(b); (b)=(c) th = atan2(vpos[1], vpos[0]); th += 2*AIR_PI*floor(0.5 + vpos[2]/S - th/(2*AIR_PI)); if (S*th/(2*AIR_PI) > vpos[2]) { t0 = th - AIR_PI; t3 = th; } else { t0 = th; t3 = th + AIR_PI; } t1 = RR*t0 + CC*t3; t2 = CC*t0 + RR*t3; v1 = VAL(t1); v2 = VAL(t2); while ( t3-t0 > 0.000001*(AIR_ABS(t1)+AIR_ABS(t2)) ) { if (v1 < v2) { SHIFT3(t3, t2, t1, CC*t0 + RR*t2); SHIFT2(v2, v1, VAL(t1)); } else { SHIFT3(t0, t1, t2, RR*t1 + CC*t3); SHIFT2(v1, v2, VAL(t2)); } } /* t1 (and t2) are now the th for which the point on the helix (R*cos(th), R*sin(th), S*(th)/(2*AIR_PI)) is closest to vpos */ WPOS(wpos, t1); ELL_3V_SUB(wpos, vpos, wpos); ELL_3V_SET(fv, -R*sin(t1), R*cos(t1), S/AIR_PI); /* helix tangent */ ELL_3V_NORM(fv, fv, len); ELL_3V_COPY(rv, wpos); ELL_3V_NORM(rv, rv, len); len = ELL_3V_DOT(rv, fv); ELL_3V_SCALE(tmp, -len, fv); ELL_3V_ADD2(rv, rv, tmp); ELL_3V_NORM(rv, rv, len); /* rv now normal to helix, closest to pointing to vpos */ ELL_3V_CROSS(uv, rv, fv); ELL_3V_NORM(uv, uv, len); /* (rv,fv,uv) now right-handed frame */ ELL_3MV_ROW0_SET(W2H, uv); /* as is (uv,rv,fv) */ ELL_3MV_ROW1_SET(W2H, rv); ELL_3MV_ROW2_SET(W2H, fv); ELL_3M_TRANSPOSE(H2W, W2H); inside = 0.5 - 0.5*airErf((ELL_3V_LEN(wpos)-r)/(bnd + 0.0001)); if (incrtwist) { th = angle*ELL_3V_LEN(wpos)/r; } else { th = angle; } ELL_3M_ROTATE_Y_SET(H2C, th); ELL_3M_TRANSPOSE(C2H, H2C); ELL_3M_SCALE_SET(mA, AIR_LERP(inside, bgEval, ev[1]), AIR_LERP(inside, bgEval, ev[2]), AIR_LERP(inside, bgEval, ev[0])); ELL_3M_MUL(mB, mA, H2C); ELL_3M_MUL(mA, mB, W2H); ELL_3M_MUL(mB, mA, mf); ELL_3M_MUL(mA, C2H, mB); ELL_3M_MUL(mB, H2W, mA); ELL_3M_MUL(mA, mfT, mB); TEN_M2T_TT(out, float, mA); out[0] = 1.0; out += 7; } } } return; }
static double _nrrdTernaryOpGTSmooth(double a, double w, double b) { return AIR_AFFINE(-1.0, airErf((a-b)/w), 1.0, 0.0, 1.0); }
static double _nrrdUnaryOpNerf(double a) {return (1+airErf(a))/2;}
static double _nrrdUnaryOpErf(double a) {return airErf(a);}