00001 #include <iostream>
00002
00003
00004
00005 #include "Math/WrappedFunction.h"
00006 #include "Math/WrappedParamFunction.h"
00007
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
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
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
00075 }
00076
00077 double Derivative(const double * x, int ) 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
00156
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
00178
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
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
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
00232
00233
00234
00235
00236
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
00252 void testMultiDim() {
00253
00254
00255 std::cout <<"\n**************************************************************\n";
00256 std::cout <<"Test of Multi-dim functors" << std::endl;
00257 std::cout <<"***************************************************************\n\n";
00258
00259
00260 MyFunction myf;
00261 TestTime(myf);
00262
00263
00264 ROOT::Math::Functor f1(&freeFunction,2);
00265 TestTime(f1);
00266
00267
00268 ROOT::Math::Functor f2(myf,2);
00269 TestTime(f2);
00270
00271
00272 ROOT::Math::Functor f3(&myf,&MyFunction::Eval,2);
00273 TestTime(f3);
00274
00275
00276 ROOT::Math::GradFunctor f4(myf,2);
00277 TestTime(f4);
00278
00279
00280 ROOT::Math::GradFunctor f5(&myf,&MyFunction::Eval, &MyFunction::Derivative, 2);
00281 TestTime(f5);
00282
00283
00284 MyDerivFunction myderf;
00285 ROOT::Math::GradFunctor f6(myf,myderf, 2);
00286 TestTime(f6);
00287 }
00288
00289
00290 void testOneDim() {
00291
00292
00293 std::cout <<"\n**************************************************************\n";
00294 std::cout <<"Test of 1D functors" << std::endl;
00295 std::cout <<"***************************************************************\n\n";
00296
00297
00298 MyFunction1D myf1;
00299 TestTime(myf1);
00300
00301
00302 ROOT::Math::Functor1D f1(&freeFunction1D);
00303 TestTime(f1);
00304
00305
00306 ROOT::Math::Functor1D f2(myf1);
00307 TestTime(f2);
00308
00309
00310 ROOT::Math::Functor1D f3(&myf1,&MyFunction1D::Derivative);
00311 TestTime(f3);
00312
00313
00314
00315
00316 ROOT::Math::GradFunctor1D f4(myf1);
00317 TestTime(f4);
00318
00319
00320 ROOT::Math::GradFunctor1D f5(&myf1,&MyFunction1D::Eval, &MyFunction1D::Derivative);
00321 TestTime(f5);
00322
00323
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
00342
00343
00344
00345 DerivFunction fdf;
00346 TestTime(fdf);
00347
00348
00349
00350
00351 DerivFunction1D f13;
00352 TestTime(f13);
00353
00354
00355
00356
00357
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
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
00376
00377
00378
00379
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
00393 Functor<GenFunc> f6(f3);
00394 TestTime(f6);
00395 #endif
00396
00397 TF1 tf1("tf1",freeRootFunc2D,0,1,0);
00398
00399 TestTimeTF1(tf1);
00400
00401
00402
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
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
00426
00427
00428 ROOT::Math::Functor f8(f7b,f7b.NDim());
00429 TestTime(f8);
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443
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 }