ROOT  6.06/09
Reference Guide
testFunctor.cxx
Go to the documentation of this file.
1 #include <iostream>
2 //#include "FunctorNew.h"
3 
4 //#include "Math/IGenFunction.h"
5 #include "Math/WrappedFunction.h"
7 //#include "Fit/WrappedTF1.h"
8 #include "TStopwatch.h"
9 #include <cmath>
10 #include "TRandom2.h"
11 #include "TF1.h"
12 #include "TF2.h"
13 #include "Math/WrappedTF1.h"
14 #include "Math/WrappedMultiTF1.h"
15 
16 #ifdef HAVE_ROOFIT
17 #include "RooRealVar.h"
18 #include "RooArgList.h"
19 #include "RooExponential.h"
20 #endif
21 
22 #include "Math/IFunctionfwd.h"
23 #include "Math/IFunction.h"
24 #include "Math/Functor.h"
25 #include "Math/ParamFunctor.h"
26 
27 #include <functional>
28 #include <vector>
29 
30 //#define EXPFUNC
31 #ifndef EXPFUNC
32 
33 #define NLOOP 100
34 #define NTIMES 500000
35 #define FUNC1D x+x;
36 #define FUNC x[0]+x[1]
37 
38 #else
39 
40 #define NLOOP 10
41 #define NTIMES 500000
42 #define FUNC1D std::exp(x);
43 #define FUNC std::exp( x[0] + x[1] );
44 
45 #endif
46 
47 double freeFunction(const double * x ) {
48  return FUNC;
49  //return ;
50 }
51 
52 double freeRootFunc2D(const double *x, const double *){
53  return FUNC;
54 }
55 double freeRootFunc1D(const double *xx, const double *){
56  double x = *xx;
57  return FUNC1D;
58 }
59 double freeParamFunc1D(double x, double *){
60  return FUNC1D;
61 }
62 
63 double freeFunction1D(double x ) {
64  return FUNC1D;
65 }
66 
67 
68 class MyFunction {
69 
70 
71 public:
72  double operator()(const double *x) const {
73  return FUNC;
74  //return x[0]*std::exp(x[1]);
75  }
76 
77  double Derivative(const double * x, int /* icoord */) const { return FUNC; }
78  double Eval(const double * x) const { return FUNC; }
79 };
80 struct MyDerivFunction {
81  double operator()(const double *x, int ) const {
82  return FUNC;
83  }
84 };
85 
86 class MyFunction1D {
87 
88 
89 public:
90 
91  double operator()(double x) const {
92  return FUNC1D;
93  }
94 
95  double operator()(const double * x) const {
96  return (*this)(*x);
97  }
98 
99  double Eval(double x) const { return FUNC1D; }
100 
101  double Derivative(double x) const { return FUNC1D; }
102 };
103 
104 
105 
106 class DerivFunction : public ROOT::Math::IMultiGenFunction {
107 
108 public:
109 
110 
111  unsigned int NDim() const { return 2; }
112 
113  DerivFunction * Clone() const {
114  return new DerivFunction();
115  }
116 
117 private:
118 
119 
120  double DoEval(const double *x) const {
121  return FUNC;
122  }
123 
124 };
125 
126 
127 class DerivFunction1D : public ROOT::Math::IGenFunction {
128 
129 public:
130 
131  DerivFunction1D * Clone() const {
132  return new DerivFunction1D();
133  }
134 
135 private:
136 
137 
138  double DoEval(double x) const {
139  return FUNC1D;
140  }
141 
142 };
143 
144 struct F1D {
145  double Eval(double x) {
146  return FUNC1D;
147  }
148 };
149 
150 
151 const int Ntimes = NTIMES;
152 
153 template <class Func>
154 void TestTime(const Func & f) {
155  //double x[Ntimes];
156  // use std::vector's to avoid crashes on Windows
157  std::vector<double> x(Ntimes);
158  TStopwatch w;
159  TRandom2 r;
160  r.RndmArray(Ntimes,&x[0]);
161  w. Start();
162  double s=0;
163  for (int ipass = 0; ipass <NLOOP; ++ipass) {
164  for (int i = 0; i < Ntimes-1; ++i) {
165  const double * xx = &x[i];
166  double y = f(xx);
167  s+= y;
168  }
169  }
170  w.Stop();
171  std::cout << "Time for " << typeid(f).name() << "\t: " << w.RealTime() << " " << w.CpuTime() << std::endl;
172  std::cout << s << std::endl;
173 }
174 
175 template <class PFunc>
176 void TestTimePF( PFunc & f) {
177  //double x[Ntimes];
178  // use std::vector's to avoid crashes on Windows
179  std::vector<double> x(Ntimes);
180  TStopwatch w;
181  TRandom2 r;
182  r.RndmArray(Ntimes,&x[0]);
183  w. Start();
184  double s=0;
185  double * p = 0;
186  for (int ipass = 0; ipass <NLOOP; ++ipass) {
187  for (int i = 0; i < Ntimes-1; ++i) {
188  double y = f(&x[i],p);
189  s+= y;
190  }
191  }
192  w.Stop();
193  std::cout << "Time for " << typeid(f).name() << "\t: " << w.RealTime() << " " << w.CpuTime() << std::endl;
194  std::cout << s << std::endl;
195 }
196 
197 
199  TestTime(f);
200 }
201 
202 
203 void TestTimeTF1(TF1 & f) {
204  //double x[Ntimes];
205  std::vector<double> x(Ntimes);
206  TStopwatch w;
207  TRandom2 r;
208  r.RndmArray(Ntimes,&x[0]);
209  w. Start();
210  double s=0;
211  for (int ipass = 0; ipass <NLOOP; ++ipass) {
212  for (int i = 0; i < Ntimes-1; ++i) {
213  double y = f.EvalPar(&x[i],0);
214  s+= y;
215  }
216  }
217  w.Stop();
218  std::cout << "Time for " << "TF1\t\t" << "\t: " << w.RealTime() << " " << w.CpuTime() << std::endl;
219  std::cout << s << std::endl;
220 }
221 
222 #ifdef HAVE_ROOFIT
223 void TestTimeRooPdf(RooAbsPdf & f, RooRealVar * vars) {
224  //double x[Ntimes];
225  std::vector<double> x(Ntimes);
226  TStopwatch w;
227  TRandom2 r;
228  r.RndmArray(Ntimes,&x[0]);
229  w. Start();
230  double s=0;
231 // RooArgSet * varSet = f.getVariables();
232 // RooArgList varList(*varSet);
233 // delete varSet;
234 // RooAbsArg & arg = varList[0];
235 // RooRealVar * vars = dynamic_cast<RooRealVar * > (&arg);
236 // assert(x != 0);
237  for (int ipass = 0; ipass <NLOOP; ++ipass) {
238  for (int i = 0; i < Ntimes-1; ++i) {
239  vars->setVal(x[i+1]);
240  double y = x[i]*f.getVal();
241  s+= y;
242  }
243  }
244  w.Stop();
245  std::cout << "Time for " << "RooPdf\t\t" << "\t: " << w.RealTime() << " " << w.CpuTime() << std::endl;
246  std::cout << s << std::endl;
247 }
248 #endif
249 
250 
251 // test all functor constructs
252 void testMultiDim() {
253 
254  // multi-dim test
255  std::cout <<"\n**************************************************************\n";
256  std::cout <<"Test of Multi-dim functors" << std::endl;
257  std::cout <<"***************************************************************\n\n";
258 
259  // test directly calling the function object
260  MyFunction myf;
261  TestTime(myf);
262 
263  // test from a free function pointer
265  TestTime(f1);
266 
267  // test from function object
268  ROOT::Math::Functor f2(myf,2);
269  TestTime(f2);
270 
271  // test from a member function
273  TestTime(f3);
274 
275  // test grad functor from an object providing eval and deriv.
276  ROOT::Math::GradFunctor f4(myf,2);
277  TestTime(f4);
278 
279  // test grad functor from object and member functions
280  ROOT::Math::GradFunctor f5(&myf,&MyFunction::Eval, &MyFunction::Derivative, 2);
281  TestTime(f5);
282 
283  // test from 2 function objects
284  MyDerivFunction myderf;
285  ROOT::Math::GradFunctor f6(myf,myderf, 2);
286  TestTime(f6);
287 }
288 
289 // test all functor constructs
290 void testOneDim() {
291 
292  // test 1D functors
293  std::cout <<"\n**************************************************************\n";
294  std::cout <<"Test of 1D functors" << std::endl;
295  std::cout <<"***************************************************************\n\n";
296 
297  // test dircectly calling function object
298  MyFunction1D myf1;
299  TestTime(myf1);
300 
301  /// test free function
303  TestTime(f1);
304 
305  // test from function object
307  TestTime(f2);
308 
309  // test from member function
310  ROOT::Math::Functor1D f3(&myf1,&MyFunction1D::Derivative);
311  TestTime(f3);
312 
313  // testgrad functor
314 
315  // from function object implementing both
316  ROOT::Math::GradFunctor1D f4(myf1);
317  TestTime(f4);
318 
319  // test grad functor from object and member functions
320  ROOT::Math::GradFunctor1D f5(&myf1,&MyFunction1D::Eval, &MyFunction1D::Derivative);
321  TestTime(f5);
322 
323  // test from 2 function objects
325  TestTime(f6);
326 
327 
328 }
329 
330 
331 void testMore() {
332 
333 
334  std::cout <<"\n**************************************************************\n";
335  std::cout <<"Extra functor tests" << std::endl;
336  std::cout <<"***************************************************************\n\n";
337 
339  TestTimePF(fp1);
340 
341 // ROOT::Math::ParamFunctor1D fp2(&freeParamFunc1D);
342 // TestTimePF(fp2);
343 
344 
345  DerivFunction fdf;
346  TestTime(fdf);
347 
348 
349  //1D
350 
351  DerivFunction1D f13;
352  TestTime(f13);
353 
354 
355 
356 
357  //TestTimeGF(f3);
359  TestTime(f5);
360 
362  TestTime(f5b);
363 
364 
365 
366  F1D fobj;
367  //std::cout << typeid(&F1D::Eval).name() << std::endl;
368  ROOT::Math::Functor1D f6(std::bind1st(std::mem_fun(&F1D::Eval), &fobj) );
369  TestTime(f6);
370 
372  TestTime(f6a);
373 
374  //typedef double( * FreeFunc ) (double );
375  //ROOT::Math::WrappedMemFunction<F1D,FreeFunc> f6b(&fobj, &F1D::Eval, );
376 
377 // typedef double (F1D::*MemFun)(double);
378 // double (F1D::*p1 )(double) = &F1D::Eval;
379 // std::cout << typeid(p1).name() << std::endl;
381  TestTime(f6b);
382 
383  ROOT::Math::Functor1D f6c(&fobj, &F1D::Eval );
384  TestTime(f6c);
385 
386 
387 
388 #ifdef LATER
389  FunctorNV<GradFunc, MyFunction> f5(myf);
390  TestTime(f5);
391 
392  // test of virtuality two times
393  Functor<GenFunc> f6(f3);
394  TestTime(f6);
395 #endif
396 
397  TF1 tf1("tf1",freeRootFunc2D,0,1,0);
398  //TF2 tf1("tf1","x+y",0,1,0,1);
399  TestTimeTF1(tf1);
400 
401 // ROOT::Fit::WrappedTF1 f7(&tf1);
402 // TestTime(f7);
403 
405  TestTime(f7b);
406  TestTimePF(f7b);
407 
409  TestTime(wf7);
410  TestTimePF(wf7);
411 
412  // use the fact that TF1 implements operator(double *, double *)
414  TestTimePF(wf7b);
415 
416 
417 
418  TF1 tf2("tf2",freeRootFunc1D,0,1,0);
419  TestTimeTF1(tf2);
420 
421  ROOT::Math::WrappedTF1 f7c(tf2);
422  TestTime(f7c);
423 
424 
425 // double xx[1] = {2};
426 // f7(xx);
427 
428  ROOT::Math::Functor f8(f7b,f7b.NDim());
429  TestTime(f8);
430 
431 // this does not compile oin Windows, since it does not understand the default arguments
432 // It does not work for gcc 4.3 either.
433 // #ifndef _WIN32
434 // ROOT::Math::Functor1D f9(&tf1,&TF1::Eval);
435 // TestTime(f9);
436 
437 // ROOT::Math::Functor f10(&tf1,&TF1::EvalPar,tf1.GetNdim());
438 // TestTime(f10);
439 // #endif
440 
441 
442 
443  // test with rootit
444 #ifdef HAVE_ROOFIT
445  RooRealVar x("x","x",0);
446  RooRealVar c("c","c",1.,1.,1.);
447  RooExponential rooExp("exp","exponential",x,c);
448  TestTimeRooPdf(rooExp,&x);
449 #endif
450 
451 }
452 
453 int main() {
454 
455  testMultiDim();
456 
457  testOneDim();
458 
459  testMore();
460 
461  return 0;
462 
463 }
double freeRootFunc2D(const double *x, const double *)
Definition: testFunctor.cxx:52
Double_t RealTime()
Stop the stopwatch (if it is running) and return the realtime (in seconds) passed between the start a...
Definition: TStopwatch.cxx:108
Interface (abstract class) for generic functions objects of one-dimension Provides a method to evalua...
Definition: IFunction.h:133
GradFunctor class for Multidimensional gradient functions.
Definition: Functor.h:590
GradFunctor1D class for one-dimensional gradient functions.
Definition: Functor.h:705
void testMultiDim()
Documentation for class Functor class.
Definition: Functor.h:394
Class to Wrap a ROOT Function class (like TF1) in a IParamMultiFunction interface of multi-dimensions...
Random number generator class based on the maximally quidistributed combined Tausworthe generator by ...
Definition: TRandom2.h:29
Class to Wrap a ROOT Function class (like TF1) in a IParamFunction interface of one dimensions to be ...
Definition: WrappedTF1.h:41
Double_t CpuTime()
Stop the stopwatch (if it is running) and return the cputime (in seconds) passed between the start an...
Definition: TStopwatch.cxx:123
#define FUNC1D
Definition: testFunctor.cxx:35
#define NTIMES
Definition: testFunctor.cxx:34
double freeFunction1D(double x)
Definition: testFunctor.cxx:63
Template class to wrap any C++ callable object which takes one argument i.e.
void Stop()
Stop the stopwatch.
Definition: TStopwatch.cxx:75
Double_t x[n]
Definition: legend1.C:17
double freeRootFunc1D(const double *xx, const double *)
Definition: testFunctor.cxx:55
int main()
Double_t getVal(const RooArgSet *set=0) const
Definition: RooAbsReal.h:64
double freeFunction(const double *x)
Definition: testFunctor.cxx:47
virtual void setVal(Double_t value)
Set value of variable to 'value'.
Definition: RooRealVar.cxx:202
void TestTimePF(PFunc &f)
ROOT::R::TRInterface & r
Definition: Object.C:4
IParamFunction interface (abstract class) describing multi-dimensional parameteric functions It is a ...
virtual unsigned int NDim() const =0
Retrieve the dimension of the function.
virtual void RndmArray(Int_t n, Float_t *array)
Return an array of n random numbers uniformly distributed in ]0,1].
Definition: TRandom2.cxx:77
void testOneDim()
TRObject operator()(const T1 &t1) const
double f(double x)
void TestTime(const Func &f)
Double_t y[n]
Definition: legend1.C:17
void TestTimeTF1(TF1 &f)
double freeParamFunc1D(double x, double *)
Definition: testFunctor.cxx:59
virtual double DoEval(double x) const =0
implementation of the evaluation function. Must be implemented by derived classes ...
Template class to wrap any C++ callable object implementing operator() (const double * x) in a multi-...
void testMore()
#define name(a, b)
Definition: linkTestLib0.cpp:5
void TestTimeGF(const ROOT::Math::IGenFunction &f)
RooAbsPdf is the abstract interface for all probability density functions The class provides hybrid a...
Definition: RooAbsPdf.h:41
double f2(const double *x)
#define FUNC
Definition: testFunctor.cxx:36
1-Dim function class
Definition: TF1.h:149
TF1 * f1
Definition: legend1.C:11
Param Functor class for Multidimensional functions.
Definition: ParamFunctor.h:209
virtual IBaseFunctionOneDim * Clone() const =0
Clone a function.
Functor1D class for one-dimensional functions.
Definition: Functor.h:492
unsigned int NDim() const
function dimension
Documentation for the abstract class IBaseFunctionMultiDim.
Definition: IFunction.h:63
virtual Double_t EvalPar(const Double_t *x, const Double_t *params=0)
Evaluate function with given coordinates and parameters.
Definition: TF1.cxx:1215
Template class to wrap any member function of a class taking a double and returning a double in a 1D ...
virtual double DoEval(const double *x) const =0
Implementation of the evaluation function.
WrappedParamFunction class to wrap any multi-dimensional function pbject implementing the operator()(...
virtual IBaseFunctionMultiDim * Clone() const =0
Clone a function.
Stopwatch class.
Definition: TStopwatch.h:30
#define NLOOP
Definition: testFunctor.cxx:33