testStatFunc.cxx

Go to the documentation of this file.
00001 /// test of the statistical functions cdf and quantiles 
00002 
00003 //#define NO_MATHCORE
00004 
00005 #include "Math/DistFuncMathMore.h"
00006 #ifndef NO_MATHCORE
00007 #include "Math/GSLIntegrator.h"
00008 #include "Math/WrappedFunction.h"
00009 #include "Math/DistFuncMathCore.h"
00010 #endif
00011 
00012 
00013 #include <iostream>
00014 #include <limits>
00015 
00016 using namespace ROOT::Math; 
00017 
00018 int compare( std::string name, double v1, double v2, double scale = 2.0) {
00019   //  ntest = ntest + 1; 
00020 
00021    //std::cout << std::setw(50) << std::left << name << ":\t";   
00022    
00023   // numerical double limit for epsilon 
00024    double eps = scale* std::numeric_limits<double>::epsilon();
00025    int iret = 0; 
00026    double delta = v2 - v1;
00027    double d = 0;
00028    if (delta < 0 ) delta = - delta; 
00029    if (v1 == 0 || v2 == 0) { 
00030       if  (delta > eps ) { 
00031          iret = 1; 
00032       }
00033    }
00034    // skip case v1 or v2 is infinity
00035    else { 
00036       d = v1; 
00037 
00038       if ( v1 < 0) d = -d; 
00039       // add also case when delta is small by default
00040       if ( delta/d  > eps && delta > eps ) 
00041          iret =  1; 
00042    }
00043 
00044    if (iret == 0) 
00045       std::cout <<".";
00046    else { 
00047       int pr = std::cout.precision (18);
00048       std::cout << "\nDiscrepancy in " << name.c_str() << "() :\n  " << v1 << " != " << v2 << " discr = " << int(delta/d/eps) 
00049                 << "   (Allowed discrepancy is " << eps  << ")\n\n";
00050       std::cout.precision (pr);
00051       //nfail = nfail + 1;
00052    }
00053    return iret; 
00054 }
00055 
00056 
00057 
00058 // for functions with one parameters
00059 
00060 struct TestFunc1 { 
00061 
00062    typedef double ( * Pdf) ( double, double, double); 
00063    typedef double ( * Cdf) ( double, double, double); 
00064    typedef double ( * Quant) ( double, double); 
00065 
00066    // wrappers to pdf to be integrated 
00067    struct PdfFunction { 
00068       PdfFunction( Pdf pdf, double p1 ) : fPdf(pdf), fP1(p1) {}
00069       double operator() ( double x) const { return fPdf(x,fP1,0.0); }
00070       
00071       Pdf fPdf; 
00072       double fP1; 
00073    };
00074 
00075 
00076    TestFunc1( double p1, double s = 2) : 
00077       scale(s)
00078    {
00079       p[0] = p1;
00080    }
00081 
00082 #ifndef NO_MATHCORE // skip cdf test when Mathcore is missing
00083  
00084    int testCdf( Pdf f_pdf, Cdf f_cdf, bool c = false) {
00085       int iret = 0; 
00086       double val = 1.0; // value used  for testing
00087       double q1 = f_cdf(val, p[0],0.0);
00088       // calculate integral of pdf
00089       PdfFunction f(f_pdf,p[0]); 
00090       WrappedFunction<PdfFunction> wf(f);
00091       GSLIntegrator ig(1.E-12,1.E-12,100000);
00092       ig.SetFunction(wf);
00093       if (!c) { 
00094          // lower intergal (cdf) 
00095          double q2 = ig.IntegralLow(val); 
00096          // use a larger scale (integral error is 10-9)
00097          iret |= compare("test _cdf", q1, q2, 1.0E6);
00098       }
00099       else { 
00100          // upper integral (cdf_c)
00101          double q2 = ig.IntegralUp(val); 
00102          iret |= compare("test _cdf_c", q1, q2, 1.0E6);
00103       }
00104       return iret; 
00105    }
00106 
00107 #endif
00108    
00109    int testQuantile (Cdf f_cdf, Quant f_quantile, bool c= false) {
00110       int iret = 0; 
00111       double z1,z2,q; 
00112       z1 = 1.0E-6; 
00113       for (int i = 0; i < 10; ++i) { 
00114          q = f_quantile(z1,p[0]); 
00115          z2 = f_cdf(q, p[0],0.); 
00116          if (!c) 
00117             iret |= compare("test quantile", z1, z2, scale);
00118          else 
00119             iret |= compare("test quantile_c", z1, z2, scale);
00120          z1 += 0.1; 
00121       }
00122       return iret; 
00123    } 
00124 
00125    double p[1]; // parameters 
00126    double scale; 
00127 };
00128 
00129 // for functions with two parameters
00130 
00131 
00132 struct TestFunc2 { 
00133 
00134    typedef double ( * Pdf) ( double, double, double, double); 
00135    typedef double ( * Cdf) ( double, double, double, double); 
00136    typedef double ( * Quant) ( double, double, double); 
00137 
00138 
00139    struct PdfFunction { 
00140       PdfFunction( Pdf pdf, double p1, double p2 ) : fPdf(pdf), fP1(p1), fP2(p2) {}
00141       double operator() ( double x) const { return fPdf(x,fP1,fP2,0.0); }
00142       
00143       Pdf fPdf; 
00144       double fP1; 
00145       double fP2; 
00146    };
00147 
00148    TestFunc2( double p1, double p2, double s = 2) : 
00149       scale(s)
00150    {
00151       p[0] = p1,
00152       p[1] = p2; 
00153    }
00154 
00155 #ifndef NO_MATHCORE // skip cdf test when Mathcore is missing
00156 
00157     int testCdf( Pdf f_pdf, Cdf f_cdf, bool c = false) {
00158       int iret = 0; 
00159       double val = 1.0; // value used  for testing
00160       double q1 = f_cdf(val, p[0],p[1],0.0);
00161       // calculate integral of pdf
00162       PdfFunction f(f_pdf,p[0],p[1]); 
00163       WrappedFunction<PdfFunction> wf(f);
00164       GSLIntegrator ig(1.E-12,1.E-12,100000);
00165       ig.SetFunction(wf);
00166       if (!c) { 
00167          // lower intergal (cdf) 
00168          double q2 = ig.IntegralLow(val); 
00169          // use a larger scale (integral error is 10-9)
00170          iret |= compare("test _cdf", q1, q2, 1.0E6);
00171       }
00172       else { 
00173          // upper integral (cdf_c)
00174          double q2 = ig.IntegralUp(val); 
00175          iret |= compare("test _cdf_c", q1, q2, 1.0E6);
00176       }
00177       return iret; 
00178    }
00179 
00180 #endif
00181    
00182     int testQuantile (Cdf f_cdf, Quant f_quantile, bool c=false) {
00183       int iret = 0; 
00184       double z1,z2,q; 
00185       z1 = 1.0E-6; 
00186       for (int i = 0; i < 10; ++i) { 
00187          q = f_quantile(z1,p[0],p[1]); 
00188          z2 = f_cdf(q, p[0],p[1],0.0); 
00189          if (!c) 
00190             iret |= compare("test quantile", z1, z2, scale);
00191          else 
00192             iret |= compare("test quantile_c", z1, z2, scale);
00193          z1 += 0.1; 
00194       }
00195       return iret; 
00196    } 
00197 
00198    double p[2]; // parameters 
00199    double scale; 
00200 }; 
00201 
00202 void printStatus(int iret) { 
00203    if (iret == 0) 
00204       std::cout <<"\t\t\t\t OK" << std::endl;
00205    else  
00206       std::cout <<"\t\t\t\t FAILED " << std::endl;
00207 }
00208 
00209 #ifndef NO_MATHCORE
00210 
00211 #define TESTDIST1(name, p1, s) {\
00212       int ir = 0; \
00213       TestFunc1 t(p1,s);\
00214       ir |= t.testCdf( name ## _pdf , name ## _cdf );\
00215       ir |= t.testCdf( name ##_pdf , name ##_cdf_c,true);\
00216       ir |= t.testQuantile( name ## _cdf, name ##_quantile);\
00217       ir |= t.testQuantile( name ##_cdf_c, name ##_quantile_c,true);\
00218       printStatus(ir);\
00219       iret |= ir; }  
00220 
00221 #define TESTDIST2(name, p1, p2, s) {\
00222       int ir = 0; \
00223       TestFunc2 t(p1,p2,s);\
00224       ir |= t.testCdf( name ## _pdf , name ## _cdf );\
00225       ir |= t.testCdf( name ##_pdf , name ##_cdf_c,true);\
00226       ir |= t.testQuantile( name ## _cdf, name ##_quantile);\
00227       ir |= t.testQuantile( name ##_cdf_c, name ##_quantile_c,true);\
00228       printStatus(ir);\
00229       iret |= ir; }  
00230 
00231 
00232 
00233 
00234 #else
00235 // without mathcore pdf are missing so skip cdf test
00236 #define TESTDIST1(name, p1, s) {\
00237       int ir = 0; \
00238       TestFunc1 t(p1,s);\
00239       ir |= t.testQuantile( name ## _cdf, name ##_quantile);\
00240       ir |= t.testQuantile( name ##_cdf_c, name ##_quantile_c,true);\
00241       printStatus(ir);\
00242       iret |= ir; }  
00243 
00244 #define TESTDIST2(name, p1, p2, s) {\
00245       int ir = 0; \
00246       TestFunc2 t(p1,p2,s);\
00247       ir |= t.testQuantile( name ## _cdf, name ##_quantile);\
00248       ir |= t.testQuantile( name ##_cdf_c, name ##_quantile_c,true);\
00249       printStatus(ir);\
00250       iret |= ir; }  
00251 
00252 #endif
00253 
00254 // wrapper for the beta 
00255 double mbeta_pdf(double x, double a, double b, double){ 
00256    return beta_pdf(x,a,b);
00257 }
00258 double mbeta_cdf(double x, double a, double b, double){ 
00259    return beta_cdf(x,a,b);
00260 }
00261 double mbeta_cdf_c(double x, double a, double b, double){ 
00262    return beta_cdf_c(x,a,b);
00263 }
00264 double mbeta_quantile(double x, double a, double b){ 
00265    return beta_quantile(x,a,b);
00266 }
00267 double mbeta_quantile_c(double x, double a, double b){ 
00268    return beta_quantile_c(x,a,b);
00269 }
00270 
00271 
00272 #ifndef NO_MATHCORE
00273 
00274 int testPoissonCdf(double mu,double tol) { 
00275    int iret = 0; 
00276    for (int i = 0; i < 12; ++i) { 
00277       double q1 = poisson_cdf(i,mu); 
00278       double q1c = 1.- poisson_cdf_c(i,mu); 
00279       double q2 = 0; 
00280       for (int j = 0; j <= i; ++j) {
00281          q2 += poisson_pdf(j,mu); 
00282       }
00283       iret |= compare("test cdf",q1,q2,tol);
00284       iret |= compare("test cdf_c",q1c,q2,tol);
00285    }
00286    printStatus(iret);   
00287    return iret; 
00288 }
00289 
00290 int testBinomialCdf(double p, int n, double tol) { 
00291    int iret = 0; 
00292    for (int i = 0; i < 12; ++i) { 
00293       double q1 = binomial_cdf(i,p,n); 
00294       double q1c = 1.- binomial_cdf_c(i,p,n); 
00295       double q2 = 0; 
00296       for (int j = 0; j <= i; ++j) {
00297          q2 += binomial_pdf(j,p,n); 
00298       }
00299       iret |= compare("test cdf",q1,q2,tol);
00300       iret |= compare("test cdf_c",q1c,q2,tol);
00301    }
00302    printStatus(iret);   
00303    return iret; 
00304 }
00305 
00306 #endif
00307 
00308 int testStatFunc() { 
00309 
00310    int iret = 0; 
00311    double tol = 2; 
00312 
00313 
00314 #ifndef NO_MATHCORE
00315 
00316    tol = 8; 
00317    std::cout << "Poisson distrib. \t: "; 
00318    double mu = 5; 
00319    iret |= testPoissonCdf(mu,tol); 
00320 
00321    tol = 32;
00322    std::cout << "Binomial distrib. \t: "; 
00323    double p = 0.5; int nt = 9;  
00324    iret |= testBinomialCdf(p,nt,tol); 
00325 
00326    tol = 2; 
00327    std::cout << "BreitWigner distrib\t: "; 
00328    TESTDIST1(breitwigner,1.0,tol);
00329 
00330    std::cout << "Cauchy distribution\t: "; 
00331    TESTDIST1(cauchy,2.0,tol);
00332 
00333    std::cout << "Exponential distrib\t: "; 
00334    TESTDIST1(exponential,1.0,tol);
00335 
00336    std::cout << "Gaussian distribution\t: "; 
00337    TESTDIST1(gaussian,1.0,tol);
00338 
00339    std::cout << "Log-normal distribution\t: "; 
00340    TESTDIST2(lognormal,1.0,1.0,tol);
00341 
00342    std::cout << "Normal distribution\t: "; 
00343    TESTDIST1(normal,1.0,tol);
00344 
00345    std::cout << "Uniform distribution\t: "; 
00346    TESTDIST2(uniform,0.0,10.0,tol);
00347 
00348 
00349          
00350 #endif
00351 
00352    std::cout << "Chisquare distribution\t: "; 
00353    tol = 8; 
00354    TESTDIST1(chisquared,9.,tol);
00355 
00356    tol = 2; 
00357    
00358    std::cout << "F distribution\t\t: "; 
00359    double n = 5; double m = 6;  
00360    TESTDIST2(fdistribution,n,m,tol);
00361    
00362    std::cout << "Gamma distribution\t: "; 
00363    double a = 1; double b = 2;  
00364    TESTDIST2(gamma,a,b,tol);
00365 
00366    std::cout << "t distribution\t\t: "; 
00367    double nu = 10; 
00368    TESTDIST1(tdistribution,nu,tol);
00369 
00370    std::cout << "Beta distribution\t: "; 
00371    a = 2; b = 1;  
00372    TESTDIST2(mbeta,a,b,tol);
00373 
00374 
00375 
00376    return iret; 
00377 }
00378 int main() { 
00379 
00380    return testStatFunc();
00381 }

Generated on Tue Jul 5 14:35:00 2011 for ROOT_528-00b_version by  doxygen 1.5.1