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

WeibullNgbPnLoop.h

Go to the documentation of this file.
00001 #ifndef Impala_Core_Feature_WeibullNgbPnLoop_h
00002 #define Impala_Core_Feature_WeibullNgbPnLoop_h
00003 
00004 #include "Core/Array/Pattern/Categories.h"
00005 #include "Core/Array/Pattern/Cnum.h"
00006 #include "Core/Array/Element/Vec3Real64.h"
00007 #include "Core/Array/Arrays.h"
00008 #include "Core/Array/Sort.h"
00009 #include "Core/Array/MulVal.h"
00010 #include "Core/Array/Set.h"
00011 #include "Core/Array/PrintData.h"
00012 //#include <cmath>
00013 #include "limits.h"
00014 #include "float.h"
00015 #include <errno.h>
00016 
00017 namespace Impala
00018 {
00019 namespace Core
00020 {
00021 namespace Feature
00022 {
00023 
00024 /* constants: pi, Euler's constant, and log(2) */
00025 #ifndef M_PI
00026 #define M_PI 3.1415926535897932384626433832795029
00027 #endif
00028 #ifndef MMGAMMA
00029 #define MMGAMMA 0.5772156649015328606065120900824024
00030 #endif
00031 #ifndef M_LN2
00032 #define M_LN2 0.6931471805599453094172321214581766
00033 #endif
00034 
00035 
00038 template<class DstArrayT, class SrcArrayT>
00039 class WeibullNgbPnLoop
00040 {
00041 public:
00042 
00044     typedef Array::Pattern::TagLoop IteratorCategory;
00045 
00047     typedef Array::Pattern::TagNPhase PhaseCategory;
00048 
00049     typedef typename DstArrayT::StorType DstStorType;
00050     typedef typename DstArrayT::ArithType DstArithType;
00051     typedef typename SrcArrayT::StorType SrcStorType;
00052     typedef typename SrcArrayT::ArithType SrcArithType;
00053 
00054 
00056     WeibullNgbPnLoop(bool verbose, int ngbWidth, int ngbHeight)
00057     {
00058         mNgbWidth = ngbWidth;
00059         mNgbHeight = ngbHeight;
00060         mVerbose = verbose;
00061         mFrac = mNgbWidth*mNgbHeight;
00062         mGamma = 0.1;
00063         mGammaNext = 0.0;
00064         mLast = false;
00065         mData = new SrcArrayT(mFrac, 1, 0, 0);
00066         mEcdf = new SrcArrayT(mFrac, 1, 0, 0);
00067     }
00068 
00070     ~WeibullNgbPnLoop()
00071     {
00072       delete mData;
00073       delete mEcdf;
00074     }
00076     int
00077     Width()
00078     {
00079         return mNgbWidth;
00080     }
00081 
00083     int
00084     Height()
00085     {
00086         return mNgbHeight;
00087     }
00088 
00090     void
00091     Init(int phase, int x, int y, SrcArithType value)
00092     {
00093       if(mLast) return;
00094       int ph = phase%2;
00095       //        if (mVerbose)
00096       //  std::cout << "  WeibullNgbPnLoop::init(" << phase << ","
00097       //            << x << "," << y << "," << value << ") " << std::endl;
00098 
00099       if (phase == 1)
00100       {
00101         //      std::cout << "int: x = " << x << " y = " << y << std::endl; 
00102         //      if(mGamma > 5) mGamma = 0.1;
00103         mGamma = 0.1;
00104         mGammaNext = 0.0; 
00105         mPrecision = 0.005; 
00106         mMaxNumIters = 20;
00107         mIter = 1;
00108         mMaxGamma = 25; 
00109       }
00110       mPhase = phase;
00111       if (ph)
00112       {
00113         mSumDataPowerGamma = 0.0;
00114         mSumDataLog = 0.0;
00115         mF = 0.0;
00116         mFprime = 0.0;
00117       }
00118       
00119     }
00120 
00122     void
00123     NextEl(int x, int y, SrcArithType value)
00124     {
00125       SrcArithType dataPowerGamma;
00126       SrcArithType sumItem;
00127       SrcArithType data = value + 0.000001; 
00128       dataPowerGamma = pow(data, mGamma);
00129       int phase = mPhase%2;
00130         
00131       if(mVerbose)
00132         if (mGamma == 0.1 && phase == 0)
00133           std::cout << value << std::endl;
00134       //      if (mVerbose)
00135       //        std::cout << "      WeibullNgbPnLoop::next(" << x << "," << y << ","<< value << ") " << std::endl;
00136 
00137       if (mLast)
00138       {
00139         mData->SetValue(value, x*mNgbWidth + y, 0);
00140         return;
00141       } 
00142       switch (phase)
00143       {
00144       case 1 : 
00145         mSumDataPowerGamma += dataPowerGamma;
00146         mSumDataLog += dataPowerGamma*log(data);
00147         break;
00148         
00149       case 0 :
00150         sumItem = dataPowerGamma/mSumDataPowerGamma; 
00151         mF += log(mFrac*sumItem) - mFrac*(sumItem)*log(mFrac*sumItem);
00152         mFprime += (mSumDataPowerGamma/dataPowerGamma - mFrac*(log(mFrac*sumItem) + 1)) *
00153         (dataPowerGamma*(log(data)*mSumDataPowerGamma - mSumDataLog))/
00154           (mSumDataPowerGamma*mSumDataPowerGamma);
00155         break;
00156       }
00157         
00158     }
00159 
00161     void
00162     Done(int phase)
00163     {
00164 
00165       int ph = phase%2;
00166       if (mVerbose)
00167         std::cout << "done: phase = " << phase <<  std::endl;
00168       if(!ph)
00169       {
00170         if (mVerbose)
00171           std::cout << "mGamma = " << mGamma << std::endl;
00172 
00173         mF = mFrac + mF;
00174         mGammaNext = mGamma - mF/mFprime;
00175         if (mVerbose)
00176           std::cout << "mGammaNext = " << mGammaNext << std::endl;
00177       }
00178       
00179     }
00180 
00182     bool
00183     HasNextPhase(int lastPhase)
00184     {
00185       if(mLast)
00186       {
00187         mLast = false;
00188         return false;
00189       }
00190       int ph = lastPhase%2;  
00191       if (mVerbose)
00192         std::cout << "  WeibullNgbPnLoop::hasNext(" << lastPhase << ") "
00193                   << std::endl;
00194 
00195       if (ph)
00196         return true;
00197 
00198       else
00199       {
00200         if (fabs(mGamma - mGammaNext) < mPrecision || mIter > mMaxNumIters || 
00201             mGammaNext > mMaxGamma || isnan(mGammaNext) || isinf(mGammaNext) || mGammaNext < 0)
00202         {         
00203           if (mVerbose)
00204           {
00205             std::cout << "no next phase! " << "fabs(mGamma - mGammaNext) = " << fabs(mGamma - mGammaNext)  << std::endl;
00206             std::cout << "mIter = " << mIter << " maxIter =  " << mMaxNumIters << std::endl; 
00207             std::cout << "maxGamma = " << mMaxGamma << std::endl;
00208             std::cout << "mGamma = " << mGamma << " mGammaNext = " << mGammaNext << std::endl;
00209           }
00210           //    std::cout << "mIter = " << mIter << std::endl; 
00211           mIter = 1;
00212           mLast = true;
00213           return true;
00214         }
00215         else 
00216         {
00217           if (mVerbose)
00218             std::cout << "there is next phase: iteration = " << mIter << std::endl;
00219           mGamma = mGammaNext;
00220           mIter++;
00221           return true;
00222         }
00223       }
00224     }
00225 
00227     DstArithType
00228     Result() 
00229     {
00230       double Beta = pow(mSumDataPowerGamma/mFrac, (1/mGamma));
00231       if(Beta == 0) 
00232         Beta = 0.00000001;
00233       Core::Array::Sort(mEcdf, mData);
00234       if(mVerbose)
00235       {
00236         std::cout << "******** mData **********" << std::endl;
00237         Core::Array::PrintData(mData, false);
00238         std::cout << "******** mData sorted **********" << std::endl << std::endl;
00239         Core::Array::PrintData(mEcdf, false);
00240       }
00241       Core::Array::Set(mData, mEcdf);
00242       Core::Array::MulVal(mEcdf, mEcdf, 1/mData->Value(mFrac-1, 0));
00243       double F;
00244       double dF;
00245       double AD = 0.0; 
00246       for (int i=0; i<mFrac; i++)
00247       {
00248         F = 1 - exp(-pow(mData->Value(i,0)/Beta, mGamma));
00249         dF = (mGamma/Beta)*pow((mData->Value(i,0)/Beta), (mGamma-1))*F;
00250         AD += pow((mEcdf->Value(i,0) - F), 2)*dF/(F*(1 - F));
00251       }
00252       AD = AD/mFrac;
00253       if (mVerbose)
00254         std::cout << "result: Gamma = " << mGamma  << " Beta = " << Beta << " AD = " << AD << std::endl;
00255       return Core::Array::Element::Vec3Real64(Beta, mGamma, AD);
00256    }
00257 
00258     double
00259     gammaFunc(double xx) const
00260     {
00261         double x,y,tmp,ser;
00262         static double cof[6] =
00263             {
00264                 76.18009172947146, -86.50532032941677,
00265                 24.01409824083091, -1.231739572450155,
00266                 0.1208650973866179e-2, -0.5395239384953e-5
00267             };
00268         
00269         int j;
00270         y=x=xx;
00271         tmp=x+5.5;
00272         tmp -= (x+0.5)*log(tmp);
00273         ser=1.000000000190015;
00274         for (j=0;j<=5;j++)
00275             ser += cof[j]/++y;
00276         xx = -tmp+log(2.5066282746310005*ser/x);
00277         return exp(xx);
00278     }
00279 
00280     double
00281     DiGamma(double x) const
00282     {
00283         /* force into the interval 1..3 */
00284         if( x < 0.0 )
00285             return DiGamma(1.0-x)+M_PI/tan(M_PI*(1.0-x)) ;  /* refection formula */
00286         else if( x < 1.0 )
00287             return DiGamma(1.0+x)-1.0/x ;
00288         else if ( x == 1.0)
00289             return -MMGAMMA ;
00290         else if ( x == 2.0)
00291             return 1.0-MMGAMMA ;
00292         else if ( x == 3.0)
00293             return 1.5-MMGAMMA ;
00294         else if ( x > 3.0)
00295             /* duplication formula */
00296             return 0.5*(DiGamma(x/2.0)+DiGamma((x+1.0)/2.0))+M_LN2 ;
00297         else
00298         {
00299             static double Kncoe[] =
00300                 { .30459198558715155634315638246624251,
00301                   .72037977439182833573548891941219706, -.12454959243861367729528855995001087,
00302                   .27769457331927827002810119567456810e-1, -.67762371439822456447373550186163070e-2,
00303                   .17238755142247705209823876688592170e-2, -.44817699064252933515310345718960928e-3,
00304                   .11793660000155572716272710617753373e-3, -.31253894280980134452125172274246963e-4,
00305                   .83173997012173283398932708991137488e-5, -.22191427643780045431149221890172210e-5,
00306                   .59302266729329346291029599913617915e-6, -.15863051191470655433559920279603632e-6,
00307                   .42459203983193603241777510648681429e-7, -.11369129616951114238848106591780146e-7,
00308                   .304502217295931698401459168423403510e-8, -.81568455080753152802915013641723686e-9,
00309                   .21852324749975455125936715817306383e-9, -.58546491441689515680751900276454407e-10,
00310                   .15686348450871204869813586459513648e-10, -.42029496273143231373796179302482033e-11,
00311                   .11261435719264907097227520956710754e-11, -.30174353636860279765375177200637590e-12,
00312                   .80850955256389526647406571868193768e-13, -.21663779809421233144009565199997351e-13,
00313                   .58047634271339391495076374966835526e-14, -.15553767189204733561108869588173845e-14,
00314                   .41676108598040807753707828039353330e-15, -.11167065064221317094734023242188463e-15 } ;
00315 
00316             double Tn_1 = 1.0 ; /* T_{n-1}(x), started at n=1 */
00317             double Tn = x-2.0 ; /* T_{n}(x) , started at n=1 */
00318             double resul = Kncoe[0] + Kncoe[1]*Tn ;
00319 
00320             x -= 2.0 ;
00321 
00322             for(int n = 2 ; n < sizeof(Kncoe)/sizeof(double) ;n++)
00323             {
00324                 const double Tn1 = 2.0 * x * Tn - Tn_1 ;    /* Chebyshev recursion, Eq. 22.7.4 Abramowitz-Stegun */
00325                 resul += Kncoe[n]*Tn1 ;
00326                 Tn_1 = Tn ;
00327                 Tn = Tn1 ;
00328             }
00329             return resul ;
00330         }
00331     } //  DiGamma(double x)
00332 
00335 #define ISNAN(x) (isnan(x) !=0)
00336 #define ML_POSINF (1.0 / 0.0)
00337 #define ML_NEGINF ((-1.0) / 0.0)
00338 #define ML_NAN (0.0 / 0.0)
00339 #define n_max (100)
00340 #define M_LOG10_2 0.30102999566398119521
00341 
00342 int Rf_i1mach(int i)
00343 {
00344   switch(i) 
00345   {
00346     
00347   case  1: return 5;
00348   case  2: return 6;
00349   case  3: return 0;
00350   case  4: return 0;
00351     
00352   case  5: return CHAR_BIT * sizeof(int);
00353   case  6: return sizeof(int)/sizeof(char);
00354     
00355   case  7: return 2;
00356   case  8: return CHAR_BIT * sizeof(int) - 1;
00357   case  9: return INT_MAX;
00358     
00359   case 10: return FLT_RADIX;
00360     
00361   case 11: return FLT_MANT_DIG;
00362   case 12: return FLT_MIN_EXP;
00363 
00364   case 13: return FLT_MAX_EXP;
00365     
00366   case 14: return DBL_MANT_DIG;
00367         case 15: return DBL_MIN_EXP;
00368         case 16: return DBL_MAX_EXP;
00369 
00370   default: return 0;
00371   }
00372 }
00373  
00374 double Rf_d1mach(int i)
00375 {
00376   switch(i) 
00377   {
00378     
00379   case 1: return DBL_MIN;
00380   case 2: return DBL_MAX;
00381     
00382   case 3: /* = FLT_RADIX  ^ - DBL_MANT_DIG
00383              for IEEE:  = 2^-53 = 1.110223e-16 = .5*DBL_EPSILON */
00384     return 0.5*DBL_EPSILON;
00385     
00386   case 4: /* = FLT_RADIX  ^ (1- DBL_MANT_DIG) =
00387              for IEEE:  = 2^-52 = DBL_EPSILON */
00388     return DBL_EPSILON;
00389     
00390   case 5: return M_LOG10_2;
00391     
00392   default: return 0.0;
00393   }
00394 }
00395  
00396 double fmax2(double x, double y)
00397 {
00398 #ifdef IEEE_754
00399   if (ISNAN(x) || ISNAN(y))
00400     return x + y;
00401 #endif
00402   return (x < y) ? y : x;
00403 }
00404 
00405 double fmin2(double x, double y)
00406 {
00407 #ifdef IEEE_754
00408   if (ISNAN(x) || ISNAN(y))
00409     return x + y;
00410 #endif
00411   return (x < y) ? x : y;
00412 }
00413 
00414 int imin2(int x, int y)
00415 {
00416   return (x < y) ? x : y;
00417 }
00418 
00419 void dpsifn(double x, int n, int kode, int m, double *ans, int *nz, int *ierr)
00420 {
00421   const static double bvalues[] = {/* Bernoulli Numbers */
00422           1.00000000000000000e+00,
00423           -5.00000000000000000e-01,
00424           1.66666666666666667e-01,
00425           -3.33333333333333333e-02,
00426           2.38095238095238095e-02,
00427           -3.33333333333333333e-02,
00428           7.57575757575757576e-02,
00429           -2.53113553113553114e-01,
00430           1.16666666666666667e+00,
00431           -7.09215686274509804e+00,
00432           5.49711779448621554e+01,
00433           -5.29124242424242424e+02,
00434           6.19212318840579710e+03,
00435           -8.65802531135531136e+04,
00436           1.42551716666666667e+06,
00437           -2.72982310678160920e+07,
00438           6.01580873900642368e+08,
00439           -1.51163157670921569e+10,
00440           4.29614643061166667e+11,
00441           -1.37116552050883328e+13,
00442           4.88332318973593167e+14,
00443           -1.92965793419400681e+16
00444         };
00445 
00446         int i, j, k, mm, mx, nn, np, nx, fn;
00447         double arg, den, elim, eps, fln, fx, rln, rxsq,
00448           r1m4, r1m5, s, slope, t, ta, tk, tol, tols, tss, tst,
00449           tt, t1, t2, wdtol, xdmln, xdmy, xinc, xln = 0.0 /* -Wall */, 
00450           xm, xmin, xq, yint;
00451         double trm[23], trmr[n_max + 1];
00452 
00453         *ierr = 0;
00454         if (n < 0 || kode < 1 || kode > 2 || m < 1) {
00455           *ierr = 1;
00456           return;
00457         }
00458         if (x <= 0.) {
00459           /* useAbramowitz & Stegun 6.4.7 "Reflection Formula"
00460            *psi(k, x) = (-1)^k psi(k, 1-x)-  pi^{n+1} (d/dx)^n cot(x)
00461            */
00462           if (x == (long)x) {
00463             /* non-positive integer : +Inf or NaN depends on n */
00464             for(j=0; j < m; j++) /* k = j + n : */
00465               ans[j] = ((j+n) % 2) ? ML_POSINF : ML_NAN;
00466             return;
00467           }
00468           dpsifn(1. - x, n, /*kode = */ 1, m, ans, nz, ierr);
00469           /* ans[j] == (-1)^(k+1) / gamma(k+1) * psi(k, 1 - x)
00470            *     for j = 0:(m-1) ,k = n + j
00471            */
00472 
00473           /* Cheat for now: only work for m = 1, n in {0,1,2,3} : */
00474           if(m > 1 || n > 3) {/* doesn't happen for digamma() .. pentagamma() */
00475             /* not yet implemented */
00476             *ierr = 4; return;
00477           }
00478           x *= M_PI; /* pi * x */
00479           if (n == 0)
00480             tt = cos(x)/sin(x);
00481           else if (n == 1)
00482             tt = -1/pow(sin(x),2);
00483           else if (n == 2)
00484             tt = 2*cos(x)/pow(sin(x),3);
00485           else if (n == 3)
00486             tt = -2*(2*pow(cos(x),2) + 1)/pow(sin(x),4);
00487           else /* can not happen! */
00488             tt = ML_NAN;
00489           /* end cheat */
00490 
00491           s = (n % 2) ? -1. : 1.;/* s = (-1)^n */
00492           /* t := pi^(n+1) * d_n(x) / gamma(n+1), where
00493            *   d_n(x) := (d/dx)^n cot(x)*/
00494           t1 = t2 = s = 1.;
00495           for(k=0, j=k-n; j < m; k++, j++, s = -s) {
00496             /* k == n+j , s = (-1)^k */
00497             t1 *= M_PI;/* t1 == pi^(k+1) */
00498             if(k >= 2)
00499               t2 *= k;/* t2 == k! == gamma(k+1) */
00500             if(j >= 0) /* by cheat above,  tt === d_k(x) */
00501               ans[j] = s*(ans[j] + t1/t2 * tt);
00502           }
00503           if (n == 0 && kode == 2)
00504             ans[0] += xln;
00505           return;
00506         } /* x <= 0 */
00507 
00508         *nz = 0;
00509         mm = m;
00510         nx = imin2(-Rf_i1mach(15), Rf_i1mach(16));/* = 1021 */
00511         r1m5 = Rf_d1mach(5);
00512         r1m4 = Rf_d1mach(4) * 0.5;
00513         wdtol = fmax2(r1m4, 0.5e-18); /* 1.11e-16 */
00514 
00515         /* elim = approximate exponential over and underflow limit */
00516 
00517         elim = 2.302 * (nx * r1m5 - 3.0);/* = 700.6174... */
00518         xln = log(x);
00519         for(;;) {
00520           nn = n + mm - 1;
00521           fn = nn;
00522           t = (fn + 1) * xln;
00523 
00524           /* overflow and underflow test for small and large x */
00525 
00526           if (fabs(t) > elim) {
00527             if (t <= 0.0) {
00528               *nz = 0;
00529               *ierr = 2;
00530               return;
00531             }
00532           }
00533           else {
00534             if (x < wdtol) {
00535               ans[0] = pow(x, -n-1.0);
00536               if (mm != 1) {
00537                 for(k = 1; k < mm ; k++)
00538                   ans[k] = ans[k-1] / x;
00539               }
00540               if (n == 0 && kode == 2)
00541                 ans[0] += xln;
00542               return;
00543             }
00544 
00545             /* compute xmin and the number of terms of the series,  fln+1 */
00546 
00547             rln = r1m5 * Rf_i1mach(14);
00548             rln = fmin2(rln, 18.06);
00549             fln = fmax2(rln, 3.0) - 3.0;
00550             yint = 3.50 + 0.40 * fln;
00551             slope = 0.21 + fln * (0.0006038 * fln + 0.008677);
00552             xm = yint + slope * fn;
00553             mx = (int)xm + 1;
00554             xmin = mx;
00555             if (n != 0) {
00556               xm = -2.302 * rln - fmin2(0.0, xln);
00557               arg = xm / n;
00558               arg = fmin2(0.0, arg);
00559               eps = exp(arg);
00560               xm = 1.0 - eps;
00561               if (fabs(arg) < 1.0e-3)
00562                 xm = -arg;
00563               fln = x * xm / eps;
00564               xm = xmin - x;
00565               if (xm > 7.0 && fln < 15.0)
00566                 break;
00567             }
00568             xdmy = x;
00569             xdmln = xln;
00570             xinc = 0.0;
00571             if (x < xmin) {
00572               nx = (int)x;
00573               xinc = xmin - nx;
00574               xdmy = x + xinc;
00575               xdmln = log(xdmy);
00576             }
00577 
00578             /* generate w(n+mm-1, x) by the asymptotic expansion */
00579 
00580             t = fn * xdmln;
00581             t1 = xdmln + xdmln;
00582             t2 = t + xdmln;
00583             tk = fmax2(fabs(t), fmax2(fabs(t1), fabs(t2)));
00584             if (tk <= elim)
00585               goto L10;
00586           }
00587           nz++;
00588           mm--;
00589           ans[mm] = 0.;
00590           if (mm == 0)
00591             return;
00592         }
00593         nn = (int)fln + 1;
00594         np = n + 1;
00595         t1 = (n + 1) * xln;
00596         t = exp(-t1);
00597         s = t;
00598         den = x;
00599         for(i=1; i <= nn; i++) {
00600           den += 1.;
00601           trm[i] = pow(den, (double)-np);
00602           s += trm[i];
00603         }
00604         ans[0] = s;
00605         if (n == 0 && kode == 2)
00606           ans[0] = s + xln;
00607 
00608         if (mm != 1) { /* generate higher derivatives, j > n */
00609 
00610           tol = wdtol / 5.0;
00611           for(j = 1; j < mm; j++) {
00612             t /= x;
00613             s = t;
00614             tols = t * tol;
00615             den = x;
00616             for(i=1; i <= nn; i++) {
00617               den += 1.;
00618               trm[i] /= den;
00619               s += trm[i];
00620               if (trm[i] < tols)
00621                 break;
00622             }
00623             ans[j] = s;
00624           }
00625         }
00626         return;
00627 
00628       L10:
00629         tss = exp(-t);
00630         tt = 0.5 / xdmy;
00631         t1 = tt;
00632         tst = wdtol * tt;
00633         if (nn != 0)
00634           t1 = tt + 1.0 / fn;
00635         rxsq = 1.0 / (xdmy * xdmy);
00636         ta = 0.5 * rxsq;
00637         t = (fn + 1) * ta;
00638         s = t * bvalues[2];
00639         if (fabs(s) >= tst) {
00640           tk = 2.0;
00641           for(k = 4; k <= 22; k++) {
00642             t = t * ((tk + fn + 1)/(tk + 1.0))*((tk + fn)/(tk + 2.0)) * rxsq;
00643             trm[k] = t * bvalues[k-1];
00644             if (fabs(trm[k]) < tst)
00645               break;
00646             s += trm[k];
00647             tk += 2.;
00648           }
00649         }
00650         s = (s + t1) * tss;
00651         if (xinc != 0.0) {
00652 
00653           /* backward recur from xdmy to x */
00654 
00655           nx = (int)xinc;
00656           np = nn + 1;
00657           if (nx > n_max) {
00658             *nz = 0;
00659             *ierr = 3;
00660             return;
00661           }
00662           else {
00663             if (nn==0)
00664               goto L20;
00665             xm = xinc - 1.0;
00666             fx = x + xm;
00667 
00668             /* this loop should not be changed. fx is accurate when x is small */
00669             for(i = 1; i <= nx; i++) {
00670               trmr[i] = pow(fx, (double)-np);
00671               s += trmr[i];
00672               xm -= 1.;
00673               fx = x + xm;
00674             }
00675           }
00676         }
00677         ans[mm-1] = s;
00678         if (fn == 0)
00679           goto L30;
00680 
00681         /* generate lower derivatives,  j < n+mm-1 */
00682 
00683         for(j = 2; j <= mm; j++) {
00684           fn--;
00685           tss *= xdmy;
00686           t1 = tt;
00687           if (fn!=0)
00688             t1 = tt + 1.0 / fn;
00689           t = (fn + 1) * ta;
00690           s = t * bvalues[2];
00691           if (fabs(s) >= tst) {
00692             tk = 4 + fn;
00693             for(k=4; k <= 22; k++) {
00694               trm[k] = trm[k] * (fn + 1) / tk;
00695               if (fabs(trm[k]) < tst)
00696                 break;
00697               s += trm[k];
00698               tk += 2.;
00699             }
00700           }
00701           s = (s + t1) * tss;
00702           if (xinc != 0.0) {
00703             if (fn == 0)
00704               goto L20;
00705             xm = xinc - 1.0;
00706             fx = x + xm;
00707             for(i=1 ; i<=nx ; i++) {
00708               trmr[i] = trmr[i] * fx;
00709               s += trmr[i];
00710               xm -= 1.;
00711               fx = x + xm;
00712             }
00713           }
00714           ans[mm - j] = s;
00715           if (fn == 0)
00716             goto L30;
00717         }
00718         return;
00719 
00720       L20:
00721         for(i = 1; i <= nx; i++)
00722           s += 1. / (x + nx - i);
00723 
00724       L30:
00725         if (kode!=2)
00726           ans[0] = s - xdmln;
00727         else if (xdmy != x) {
00728           xq = xdmy / x;
00729           ans[0] = s - log(xq);
00730         }
00731         return;
00732       } /* dpsifn() */
00733 
00734     double TriGamma(double x)
00735     {
00736       double ans;
00737       int nz, ierr;
00738       if(ISNAN(x)) return x;
00739       dpsifn(x, 1, 1, 1, &ans, &nz, &ierr);
00740       if(ierr != 0) 
00741       {
00742         errno = EDOM;
00743         return ML_NAN;
00744       }
00745       return ans;
00746     } // double triGamma()
00747 // !!!!!!!!!!!!!!!!!!!!!!! end of trigamma routine !!!!!!!!!!!!!!!!!
00748 
00749 
00750 private:
00751     int          mNgbWidth;
00752     int          mNgbHeight;
00753     int mFrac;
00754     SrcArithType mFactor;
00755     SrcArithType mGamma;
00756     SrcArithType mGammaNext;
00757     SrcArithType mMaxGamma;
00758     SrcArithType mSumDataPowerGamma;
00759     SrcArithType mSumDataLog;
00760     SrcArithType mF;
00761     SrcArithType mFprime;
00762     SrcArithType mPrecision;
00763     SrcArrayT* mEcdf;
00764     SrcArrayT* mData;
00765     int mIter;
00766     int mMaxNumIters;
00767     int mPhase;
00768     bool mVerbose;
00769     bool mLast;
00770 };
00771 
00772 } // namespace Feature
00773 } // namespace Core
00774 } // namespace Impala
00775 
00776 #endif

Generated on Fri Mar 19 09:31:08 2010 for ImpalaSrc by  doxygen 1.5.1