testFunctor.cxx

Go to the documentation of this file.
00001 #include <iostream> 
00002 //#include "FunctorNew.h"
00003 
00004 //#include "Math/IGenFunction.h"
00005 #include "Math/WrappedFunction.h"
00006 #include "Math/WrappedParamFunction.h"
00007 //#include "Fit/WrappedTF1.h"
00008 #include "TStopwatch.h"
00009 #include <cmath>
00010 #include "TRandom2.h"
00011 #include "TF1.h"
00012 #include "TF2.h"
00013 #include "Math/WrappedTF1.h"
00014 #include "Math/WrappedMultiTF1.h"
00015 
00016 #ifdef HAVE_ROOFIT
00017 #include "RooRealVar.h"
00018 #include "RooArgList.h"
00019 #include "RooExponential.h"
00020 #endif
00021 
00022 #include "Math/IFunctionfwd.h"
00023 #include "Math/IFunction.h"
00024 #include "Math/Functor.h"
00025 #include "Math/ParamFunctor.h"
00026 
00027 #include <functional>
00028 #include <vector>
00029 
00030 //#define EXPFUNC
00031 #ifndef EXPFUNC
00032 
00033 #define NLOOP 100
00034 #define NTIMES 500000
00035 #define FUNC1D x+x; 
00036 #define FUNC x[0]+x[1]
00037 
00038 #else 
00039 
00040 #define NLOOP 10
00041 #define NTIMES 500000
00042 #define FUNC1D std::exp(x); 
00043 #define FUNC  std::exp( x[0] + x[1] );
00044 
00045 #endif
00046 
00047 double freeFunction(const double * x ) { 
00048    return FUNC; 
00049    //return ; 
00050 }
00051 
00052 double freeRootFunc2D(const double *x, const double *){ 
00053    return FUNC;
00054 }
00055 double freeRootFunc1D(const double *xx, const double *){ 
00056    double x = *xx;
00057    return FUNC1D;
00058 }
00059 double freeParamFunc1D(double x, double *){ 
00060    return FUNC1D;
00061 }
00062 
00063 double freeFunction1D(double  x ) { 
00064    return FUNC1D; 
00065 }
00066 
00067 
00068 class MyFunction { 
00069 
00070 
00071 public: 
00072    double operator()(const double *x) const { 
00073       return FUNC; 
00074       //return x[0]*std::exp(x[1]); 
00075    } 
00076    
00077    double Derivative(const double * x, int /* icoord */) const { return FUNC; }
00078    double Eval(const double * x) const { return FUNC; }
00079 };
00080 struct MyDerivFunction { 
00081    double operator()(const double *x, int ) const { 
00082       return FUNC; 
00083    }
00084 };
00085 
00086 class MyFunction1D { 
00087 
00088 
00089 public: 
00090 
00091    double operator()(double x) const { 
00092       return FUNC1D; 
00093    } 
00094 
00095    double operator()(const double * x) const { 
00096       return (*this)(*x); 
00097    } 
00098    
00099    double Eval(double x) const { return FUNC1D; }
00100 
00101    double Derivative(double x) const { return FUNC1D; }
00102 };
00103 
00104 
00105 
00106 class DerivFunction : public ROOT::Math::IMultiGenFunction { 
00107 
00108 public: 
00109 
00110 
00111    unsigned int NDim() const { return 2; }
00112 
00113    DerivFunction *  Clone() const { 
00114       return new DerivFunction(); 
00115    } 
00116 
00117 private: 
00118 
00119 
00120    double DoEval(const double *x) const { 
00121       return FUNC; 
00122    } 
00123 
00124 };
00125 
00126 
00127 class DerivFunction1D : public ROOT::Math::IGenFunction { 
00128 
00129 public: 
00130 
00131    DerivFunction1D *  Clone() const { 
00132       return new DerivFunction1D(); 
00133    } 
00134 
00135 private: 
00136 
00137 
00138    double DoEval(double x) const { 
00139       return FUNC1D; 
00140    } 
00141 
00142 };
00143 
00144 struct F1D { 
00145    double Eval(double x)  {
00146       return FUNC1D; 
00147    }
00148 }; 
00149 
00150 
00151 const int Ntimes = NTIMES; 
00152 
00153 template <class Func> 
00154 void TestTime(const Func & f) { 
00155   //double x[Ntimes]; 
00156   // use std::vector's to avoid crashes on Windows 
00157    std::vector<double> x(Ntimes); 
00158    TStopwatch w; 
00159    TRandom2 r; 
00160    r.RndmArray(Ntimes,&x[0]);
00161    w. Start(); 
00162    double s=0;
00163    for (int ipass = 0; ipass <NLOOP; ++ipass) {  
00164       for (int i = 0; i < Ntimes-1; ++i) { 
00165          const double * xx = &x[i];
00166          double y = f(xx); 
00167          s+= y; 
00168       }
00169    }
00170    w.Stop(); 
00171    std::cout << "Time for " << typeid(f).name() << "\t:  " << w.RealTime() << "  " << w.CpuTime() << std::endl; 
00172    std::cout << s << std::endl;
00173 }
00174 
00175 template <class PFunc> 
00176 void TestTimePF( PFunc & f) { 
00177   //double x[Ntimes]; 
00178   // use std::vector's to avoid crashes on Windows 
00179    std::vector<double> x(Ntimes); 
00180    TStopwatch w; 
00181    TRandom2 r; 
00182    r.RndmArray(Ntimes,&x[0]);
00183    w. Start(); 
00184    double s=0;
00185    double * p = 0;
00186    for (int ipass = 0; ipass <NLOOP; ++ipass) {  
00187       for (int i = 0; i < Ntimes-1; ++i) { 
00188          double y = f(&x[i],p); 
00189          s+= y; 
00190       }
00191    }
00192    w.Stop(); 
00193    std::cout << "Time for " << typeid(f).name() << "\t:  " << w.RealTime() << "  " << w.CpuTime() << std::endl; 
00194    std::cout << s << std::endl;
00195 }
00196 
00197 
00198 void TestTimeGF(const ROOT::Math::IGenFunction & f) { 
00199    TestTime(f);    
00200 }
00201 
00202 
00203 void TestTimeTF1(TF1 & f) { 
00204   //double x[Ntimes]; 
00205    std::vector<double> x(Ntimes); 
00206    TStopwatch w; 
00207    TRandom2 r; 
00208    r.RndmArray(Ntimes,&x[0]);
00209    w. Start(); 
00210    double s=0;
00211    for (int ipass = 0; ipass <NLOOP; ++ipass) {  
00212       for (int i = 0; i < Ntimes-1; ++i) { 
00213          double y = f.EvalPar(&x[i],0); 
00214          s+= y; 
00215       }
00216    }
00217    w.Stop(); 
00218    std::cout << "Time for " << "TF1\t\t" << "\t:  " << w.RealTime() << "  " << w.CpuTime() << std::endl; 
00219    std::cout << s << std::endl;
00220 }
00221 
00222 #ifdef HAVE_ROOFIT
00223 void TestTimeRooPdf(RooAbsPdf & f, RooRealVar * vars) { 
00224    //double x[Ntimes];    
00225    std::vector<double> x(Ntimes); 
00226    TStopwatch w; 
00227    TRandom2 r; 
00228    r.RndmArray(Ntimes,&x[0]);
00229    w. Start(); 
00230    double s=0;
00231 //    RooArgSet * varSet = f.getVariables(); 
00232 //    RooArgList varList(*varSet); 
00233 //    delete varSet; 
00234 //    RooAbsArg & arg = varList[0];
00235 //    RooRealVar * vars = dynamic_cast<RooRealVar * > (&arg); 
00236 //    assert(x != 0);
00237    for (int ipass = 0; ipass <NLOOP; ++ipass) {  
00238       for (int i = 0; i < Ntimes-1; ++i) { 
00239          vars->setVal(x[i+1]);
00240          double y = x[i]*f.getVal(); 
00241          s+= y; 
00242       }
00243    }
00244    w.Stop(); 
00245    std::cout << "Time for " << "RooPdf\t\t" << "\t:  " << w.RealTime() << "  " << w.CpuTime() << std::endl; 
00246    std::cout << s << std::endl;
00247 }
00248 #endif
00249 
00250 
00251 // test all functor constructs
00252 void testMultiDim() { 
00253 
00254    // multi-dim test 
00255    std::cout <<"\n**************************************************************\n";
00256    std::cout <<"Test of Multi-dim functors" << std::endl;
00257    std::cout <<"***************************************************************\n\n";
00258 
00259    // test directly calling the function object
00260    MyFunction myf;
00261    TestTime(myf);
00262 
00263    // test from a free function pointer
00264    ROOT::Math::Functor f1(&freeFunction,2); 
00265    TestTime(f1);
00266 
00267    // test from function object
00268    ROOT::Math::Functor f2(myf,2); 
00269    TestTime(f2);
00270 
00271    // test from a member function 
00272    ROOT::Math::Functor f3(&myf,&MyFunction::Eval,2); 
00273    TestTime(f3);
00274 
00275    // test grad functor from an object providing eval and deriv.
00276    ROOT::Math::GradFunctor  f4(myf,2); 
00277    TestTime(f4);
00278 
00279    // test grad functor from object and member functions
00280    ROOT::Math::GradFunctor  f5(&myf,&MyFunction::Eval, &MyFunction::Derivative, 2); 
00281    TestTime(f5);
00282 
00283    // test from 2 function objects
00284    MyDerivFunction myderf; 
00285    ROOT::Math::GradFunctor  f6(myf,myderf, 2); 
00286    TestTime(f6);
00287 }
00288 
00289 // test all functor constructs
00290 void testOneDim() { 
00291 
00292   // test 1D functors 
00293    std::cout <<"\n**************************************************************\n";
00294    std::cout <<"Test of 1D functors" << std::endl;
00295    std::cout <<"***************************************************************\n\n";
00296 
00297    // test dircectly calling function object
00298    MyFunction1D myf1;
00299    TestTime(myf1);
00300 
00301    /// test free function
00302    ROOT::Math::Functor1D  f1(&freeFunction1D); 
00303    TestTime(f1);
00304 
00305    // test from function object
00306    ROOT::Math::Functor1D  f2(myf1); 
00307    TestTime(f2);
00308 
00309    // test from member function 
00310    ROOT::Math::Functor1D f3(&myf1,&MyFunction1D::Derivative); 
00311    TestTime(f3);
00312 
00313    // testgrad functor
00314    
00315    // from function object implementing both
00316    ROOT::Math::GradFunctor1D  f4(myf1); 
00317    TestTime(f4);
00318    
00319    // test grad functor from object and member functions
00320    ROOT::Math::GradFunctor1D  f5(&myf1,&MyFunction1D::Eval, &MyFunction1D::Derivative); 
00321    TestTime(f5);
00322 
00323    // test from 2 function objects
00324    ROOT::Math::GradFunctor1D  f6(&freeFunction1D,myf1); 
00325    TestTime(f6);
00326 
00327 
00328 }
00329 
00330   
00331 void testMore() { 
00332  
00333 
00334    std::cout <<"\n**************************************************************\n";
00335    std::cout <<"Extra  functor tests" << std::endl;
00336    std::cout <<"***************************************************************\n\n";
00337 
00338    ROOT::Math::ParamFunctor fp1(&freeRootFunc2D); 
00339    TestTimePF(fp1);
00340 
00341 //    ROOT::Math::ParamFunctor1D fp2(&freeParamFunc1D); 
00342 //    TestTimePF(fp2);
00343 
00344 
00345    DerivFunction fdf; 
00346    TestTime(fdf);
00347 
00348 
00349    //1D
00350 
00351    DerivFunction1D f13; 
00352    TestTime(f13);
00353 
00354    
00355 
00356    
00357    //TestTimeGF(f3); 
00358    typedef double( * FreeFunc ) (double ); 
00359    ROOT::Math::WrappedFunction<> f5(freeFunction1D);
00360    TestTime(f5);
00361 
00362    ROOT::Math::WrappedMultiFunction<> f5b(freeFunction,2);
00363    TestTime(f5b);
00364 
00365 
00366 
00367    F1D fobj;
00368    //std::cout << typeid(&F1D::Eval).name() << std::endl;
00369    ROOT::Math::Functor1D f6(std::bind1st(std::mem_fun(&F1D::Eval), &fobj) );
00370    TestTime(f6);
00371 
00372    ROOT::Math::WrappedFunction<std::binder1st<std::mem_fun1_t<double, F1D, double> > >  f6a((std::bind1st(std::mem_fun(&F1D::Eval), &fobj)));
00373    TestTime(f6a);
00374 
00375    //ROOT::Math::WrappedMemFunction<F1D,FreeFunc>  f6b(&fobj, &F1D::Eval, );
00376    
00377 //    typedef double (F1D::*MemFun)(double); 
00378 //    double (F1D::*p1 )(double) = &F1D::Eval; 
00379 //    std::cout << typeid(p1).name() << std::endl;   
00380    ROOT::Math::WrappedMemFunction<F1D, double (F1D::*)(double) >  f6b(fobj, &F1D::Eval );
00381    TestTime(f6b);
00382 
00383    ROOT::Math::Functor1D f6c(&fobj, &F1D::Eval );
00384    TestTime(f6c);
00385 
00386 
00387 
00388 #ifdef LATER
00389    FunctorNV<GradFunc, MyFunction> f5(myf);
00390    TestTime(f5);
00391 
00392    // test of virtuality two times 
00393    Functor<GenFunc> f6(f3);
00394    TestTime(f6);
00395 #endif
00396    
00397    TF1 tf1("tf1",freeRootFunc2D,0,1,0);
00398    //TF2 tf1("tf1","x+y",0,1,0,1);
00399    TestTimeTF1(tf1);
00400 
00401 //    ROOT::Fit::WrappedTF1 f7(&tf1);
00402 //    TestTime(f7);
00403 
00404    ROOT::Math::WrappedMultiTF1 f7b(tf1);
00405    TestTime(f7b);
00406    TestTimePF(f7b);
00407 
00408    ROOT::Math::WrappedParamFunction<> wf7(&freeRootFunc2D,2,0,0);
00409    TestTime(wf7);
00410    TestTimePF(wf7);
00411 
00412    // use the fact that TF1 implements operator(double *, double *) 
00413    ROOT::Math::WrappedParamFunction<TF1*> wf7b(&tf1,2,0,0);
00414    TestTimePF(wf7b);
00415 
00416 
00417 
00418    TF1 tf2("tf2",freeRootFunc1D,0,1,0);
00419    TestTimeTF1(tf2);
00420 
00421    ROOT::Math::WrappedTF1 f7c(tf2);
00422    TestTime(f7c);
00423 
00424    
00425 //    double xx[1] = {2};
00426 //    f7(xx);
00427 
00428    ROOT::Math::Functor f8(f7b,f7b.NDim());
00429    TestTime(f8);
00430 
00431 // this does not compile oin Windows, since it does not understand the default arguments
00432 // It does not work for gcc 4.3 either.
00433 // #ifndef _WIN32
00434 //    ROOT::Math::Functor1D f9(&tf1,&TF1::Eval);
00435 //    TestTime(f9);
00436 
00437 //    ROOT::Math::Functor f10(&tf1,&TF1::EvalPar,tf1.GetNdim());
00438 //    TestTime(f10);
00439 // #endif
00440    
00441 
00442 
00443    // test with rootit
00444 #ifdef HAVE_ROOFIT
00445    RooRealVar x("x","x",0);
00446    RooRealVar c("c","c",1.,1.,1.);
00447    RooExponential rooExp("exp","exponential",x,c);
00448    TestTimeRooPdf(rooExp,&x);
00449 #endif
00450 
00451 }
00452 
00453 int main() { 
00454 
00455    testMultiDim();
00456 
00457    testOneDim(); 
00458 
00459    testMore(); 
00460 
00461    return 0;
00462 
00463 }

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