Home || Architecture || Video Search || Visual Search || Scripts || Applications || Important Messages || OGL || Src

template<class DstArrayT, class SrcArrayT>
void Impala::Core::Feature::IntWeibullNgbPnLoop< DstArrayT, SrcArrayT >::dpsifn ( double  x,
int  n,
int  kode,
int  m,
double *  ans,
int *  nz,
int *  ierr 
) [inline]

Definition at line 415 of file IntWeibullNgbPnLoop.h.

References Impala::Core::Feature::IntWeibullNgbPnLoop< DstArrayT, SrcArrayT >::fmax2(), Impala::Core::Feature::IntWeibullNgbPnLoop< DstArrayT, SrcArrayT >::fmin2(), Impala::Core::Feature::IntWeibullNgbPnLoop< DstArrayT, SrcArrayT >::imin2(), M_PI, ML_NAN, ML_POSINF, n_max, Impala::Core::Feature::IntWeibullNgbPnLoop< DstArrayT, SrcArrayT >::Rf_d1mach(), and Impala::Core::Feature::IntWeibullNgbPnLoop< DstArrayT, SrcArrayT >::Rf_i1mach().

Referenced by Impala::Core::Feature::IntWeibullNgbPnLoop< DstArrayT, SrcArrayT >::TriGamma().

00416 {
00417   const static double bvalues[] = {/* Bernoulli Numbers */
00418           1.00000000000000000e+00,
00419           -5.00000000000000000e-01,
00420           1.66666666666666667e-01,
00421           -3.33333333333333333e-02,
00422           2.38095238095238095e-02,
00423           -3.33333333333333333e-02,
00424           7.57575757575757576e-02,
00425           -2.53113553113553114e-01,
00426           1.16666666666666667e+00,
00427           -7.09215686274509804e+00,
00428           5.49711779448621554e+01,
00429           -5.29124242424242424e+02,
00430           6.19212318840579710e+03,
00431           -8.65802531135531136e+04,
00432           1.42551716666666667e+06,
00433           -2.72982310678160920e+07,
00434           6.01580873900642368e+08,
00435           -1.51163157670921569e+10,
00436           4.29614643061166667e+11,
00437           -1.37116552050883328e+13,
00438           4.88332318973593167e+14,
00439           -1.92965793419400681e+16
00440         };
00441 
00442         int i, j, k, mm, mx, nn, np, nx, fn;
00443         double arg, den, elim, eps, fln, fx, rln, rxsq,
00444           r1m4, r1m5, s, slope, t, ta, tk, tol, tols, tss, tst,
00445           tt, t1, t2, wdtol, xdmln, xdmy, xinc, xln = 0.0 /* -Wall */, 
00446           xm, xmin, xq, yint;
00447         double trm[23], trmr[n_max + 1];
00448 
00449         *ierr = 0;
00450         if (n < 0 || kode < 1 || kode > 2 || m < 1) {
00451           *ierr = 1;
00452           return;
00453         }
00454         if (x <= 0.) {
00455           /* useAbramowitz & Stegun 6.4.7 "Reflection Formula"
00456            *psi(k, x) = (-1)^k psi(k, 1-x)-  pi^{n+1} (d/dx)^n cot(x)
00457            */
00458           if (x == (long)x) {
00459             /* non-positive integer : +Inf or NaN depends on n */
00460             for(j=0; j < m; j++) /* k = j + n : */
00461               ans[j] = ((j+n) % 2) ? ML_POSINF : ML_NAN;
00462             return;
00463           }
00464           dpsifn(1. - x, n, /*kode = */ 1, m, ans, nz, ierr);
00465           /* ans[j] == (-1)^(k+1) / gamma(k+1) * psi(k, 1 - x)
00466            *     for j = 0:(m-1) ,k = n + j
00467            */
00468 
00469           /* Cheat for now: only work for m = 1, n in {0,1,2,3} : */
00470           if(m > 1 || n > 3) {/* doesn't happen for digamma() .. pentagamma() */
00471             /* not yet implemented */
00472             *ierr = 4; return;
00473           }
00474           x *= M_PI; /* pi * x */
00475           if (n == 0)
00476             tt = cos(x)/sin(x);
00477           else if (n == 1)
00478             tt = -1/pow(sin(x),2);
00479           else if (n == 2)
00480             tt = 2*cos(x)/pow(sin(x),3);
00481           else if (n == 3)
00482             tt = -2*(2*pow(cos(x),2) + 1)/pow(sin(x),4);
00483           else /* can not happen! */
00484             tt = ML_NAN;
00485           /* end cheat */
00486 
00487           s = (n % 2) ? -1. : 1.;/* s = (-1)^n */
00488           /* t := pi^(n+1) * d_n(x) / gamma(n+1), where
00489            *   d_n(x) := (d/dx)^n cot(x)*/
00490           t1 = t2 = s = 1.;
00491           for(k=0, j=k-n; j < m; k++, j++, s = -s) {
00492             /* k == n+j , s = (-1)^k */
00493             t1 *= M_PI;/* t1 == pi^(k+1) */
00494             if(k >= 2)
00495               t2 *= k;/* t2 == k! == gamma(k+1) */
00496             if(j >= 0) /* by cheat above,  tt === d_k(x) */
00497               ans[j] = s*(ans[j] + t1/t2 * tt);
00498           }
00499           if (n == 0 && kode == 2)
00500             ans[0] += xln;
00501           return;
00502         } /* x <= 0 */
00503 
00504         *nz = 0;
00505         mm = m;
00506         nx = imin2(-Rf_i1mach(15), Rf_i1mach(16));/* = 1021 */
00507         r1m5 = Rf_d1mach(5);
00508         r1m4 = Rf_d1mach(4) * 0.5;
00509         wdtol = fmax2(r1m4, 0.5e-18); /* 1.11e-16 */
00510 
00511         /* elim = approximate exponential over and underflow limit */
00512 
00513         elim = 2.302 * (nx * r1m5 - 3.0);/* = 700.6174... */
00514         xln = log(x);
00515         for(;;) {
00516           nn = n + mm - 1;
00517           fn = nn;
00518           t = (fn + 1) * xln;
00519 
00520           /* overflow and underflow test for small and large x */
00521 
00522           if (fabs(t) > elim) {
00523             if (t <= 0.0) {
00524               *nz = 0;
00525               *ierr = 2;
00526               return;
00527             }
00528           }
00529           else {
00530             if (x < wdtol) {
00531               ans[0] = pow(x, -n-1.0);
00532               if (mm != 1) {
00533                 for(k = 1; k < mm ; k++)
00534                   ans[k] = ans[k-1] / x;
00535               }
00536               if (n == 0 && kode == 2)
00537                 ans[0] += xln;
00538               return;
00539             }
00540 
00541             /* compute xmin and the number of terms of the series,  fln+1 */
00542 
00543             rln = r1m5 * Rf_i1mach(14);
00544             rln = fmin2(rln, 18.06);
00545             fln = fmax2(rln, 3.0) - 3.0;
00546             yint = 3.50 + 0.40 * fln;
00547             slope = 0.21 + fln * (0.0006038 * fln + 0.008677);
00548             xm = yint + slope * fn;
00549             mx = (int)xm + 1;
00550             xmin = mx;
00551             if (n != 0) {
00552               xm = -2.302 * rln - fmin2(0.0, xln);
00553               arg = xm / n;
00554               arg = fmin2(0.0, arg);
00555               eps = exp(arg);
00556               xm = 1.0 - eps;
00557               if (fabs(arg) < 1.0e-3)
00558                 xm = -arg;
00559               fln = x * xm / eps;
00560               xm = xmin - x;
00561               if (xm > 7.0 && fln < 15.0)
00562                 break;
00563             }
00564             xdmy = x;
00565             xdmln = xln;
00566             xinc = 0.0;
00567             if (x < xmin) {
00568               nx = (int)x;
00569               xinc = xmin - nx;
00570               xdmy = x + xinc;
00571               xdmln = log(xdmy);
00572             }
00573 
00574             /* generate w(n+mm-1, x) by the asymptotic expansion */
00575 
00576             t = fn * xdmln;
00577             t1 = xdmln + xdmln;
00578             t2 = t + xdmln;
00579             tk = fmax2(fabs(t), fmax2(fabs(t1), fabs(t2)));
00580             if (tk <= elim)
00581               goto L10;
00582           }
00583           nz++;
00584           mm--;
00585           ans[mm] = 0.;
00586           if (mm == 0)
00587             return;
00588         }
00589         nn = (int)fln + 1;
00590         np = n + 1;
00591         t1 = (n + 1) * xln;
00592         t = exp(-t1);
00593         s = t;
00594         den = x;
00595         for(i=1; i <= nn; i++) {
00596           den += 1.;
00597           trm[i] = pow(den, (double)-np);
00598           s += trm[i];
00599         }
00600         ans[0] = s;
00601         if (n == 0 && kode == 2)
00602           ans[0] = s + xln;
00603 
00604         if (mm != 1) { /* generate higher derivatives, j > n */
00605 
00606           tol = wdtol / 5.0;
00607           for(j = 1; j < mm; j++) {
00608             t /= x;
00609             s = t;
00610             tols = t * tol;
00611             den = x;
00612             for(i=1; i <= nn; i++) {
00613               den += 1.;
00614               trm[i] /= den;
00615               s += trm[i];
00616               if (trm[i] < tols)
00617                 break;
00618             }
00619             ans[j] = s;
00620           }
00621         }
00622         return;
00623 
00624       L10:
00625         tss = exp(-t);
00626         tt = 0.5 / xdmy;
00627         t1 = tt;
00628         tst = wdtol * tt;
00629         if (nn != 0)
00630           t1 = tt + 1.0 / fn;
00631         rxsq = 1.0 / (xdmy * xdmy);
00632         ta = 0.5 * rxsq;
00633         t = (fn + 1) * ta;
00634         s = t * bvalues[2];
00635         if (fabs(s) >= tst) {
00636           tk = 2.0;
00637           for(k = 4; k <= 22; k++) {
00638             t = t * ((tk + fn + 1)/(tk + 1.0))*((tk + fn)/(tk + 2.0)) * rxsq;
00639             trm[k] = t * bvalues[k-1];
00640             if (fabs(trm[k]) < tst)
00641               break;
00642             s += trm[k];
00643             tk += 2.;
00644           }
00645         }
00646         s = (s + t1) * tss;
00647         if (xinc != 0.0) {
00648 
00649           /* backward recur from xdmy to x */
00650 
00651           nx = (int)xinc;
00652           np = nn + 1;
00653           if (nx > n_max) {
00654             *nz = 0;
00655             *ierr = 3;
00656             return;
00657           }
00658           else {
00659             if (nn==0)
00660               goto L20;
00661             xm = xinc - 1.0;
00662             fx = x + xm;
00663 
00664             /* this loop should not be changed. fx is accurate when x is small */
00665             for(i = 1; i <= nx; i++) {
00666               trmr[i] = pow(fx, (double)-np);
00667               s += trmr[i];
00668               xm -= 1.;
00669               fx = x + xm;
00670             }
00671           }
00672         }
00673         ans[mm-1] = s;
00674         if (fn == 0)
00675           goto L30;
00676 
00677         /* generate lower derivatives,  j < n+mm-1 */
00678 
00679         for(j = 2; j <= mm; j++) {
00680           fn--;
00681           tss *= xdmy;
00682           t1 = tt;
00683           if (fn!=0)
00684             t1 = tt + 1.0 / fn;
00685           t = (fn + 1) * ta;
00686           s = t * bvalues[2];
00687           if (fabs(s) >= tst) {
00688             tk = 4 + fn;
00689             for(k=4; k <= 22; k++) {
00690               trm[k] = trm[k] * (fn + 1) / tk;
00691               if (fabs(trm[k]) < tst)
00692                 break;
00693               s += trm[k];
00694               tk += 2.;
00695             }
00696           }
00697           s = (s + t1) * tss;
00698           if (xinc != 0.0) {
00699             if (fn == 0)
00700               goto L20;
00701             xm = xinc - 1.0;
00702             fx = x + xm;
00703             for(i=1 ; i<=nx ; i++) {
00704               trmr[i] = trmr[i] * fx;
00705               s += trmr[i];
00706               xm -= 1.;
00707               fx = x + xm;
00708             }
00709           }
00710           ans[mm - j] = s;
00711           if (fn == 0)
00712             goto L30;
00713         }
00714         return;
00715 
00716       L20:
00717         for(i = 1; i <= nx; i++)
00718           s += 1. / (x + nx - i);
00719 
00720       L30:
00721         if (kode!=2)
00722           ans[0] = s - xdmln;
00723         else if (xdmy != x) {
00724           xq = xdmy / x;
00725           ans[0] = s - log(xq);
00726         }
00727         return;
00728       } /* dpsifn() */

Here is the call graph for this function:


Generated on Fri Mar 19 11:10:10 2010 for ImpalaSrc by  doxygen 1.5.1