#include //#include "FunctorNew.h" //#include "Math/IGenFunction.h" #include "Math/WrappedFunction.h" #include "Math/WrappedParamFunction.h" //#include "Fit/WrappedTF1.h" #include "TStopwatch.h" #include #include "TRandom2.h" #include "TF1.h" #include "TF2.h" #include "Math/WrappedTF1.h" #include "Math/WrappedMultiTF1.h" #ifdef HAVE_ROOFIT #include "RooRealVar.h" #include "RooArgList.h" #include "RooExponential.h" #endif #include "Math/IFunctionfwd.h" #include "Math/IFunction.h" #include "Math/Functor.h" #include "Math/ParamFunctor.h" #include #include //#define EXPFUNC #ifndef EXPFUNC #define NLOOP 100 #define NTIMES 500000 #define FUNC1D x+x; #define FUNC x[0]+x[1] #else #define NLOOP 10 #define NTIMES 500000 #define FUNC1D std::exp(x); #define FUNC std::exp( x[0] + x[1] ); #endif double freeFunction(const double * x ) { return FUNC; //return ; } double freeRootFunc2D(const double *x, const double *){ return FUNC; } double freeRootFunc1D(const double *xx, const double *){ double x = *xx; return FUNC1D; } double freeParamFunc1D(double x, double *){ return FUNC1D; } double freeFunction1D(double x ) { return FUNC1D; } class MyFunction { public: double operator()(const double *x) const { return FUNC; //return x[0]*std::exp(x[1]); } double Derivative(const double * x, int /* icoord */) const { return FUNC; } double Eval(const double * x) const { return FUNC; } }; struct MyDerivFunction { double operator()(const double *x, int ) const { return FUNC; } }; class MyFunction1D { public: double operator()(double x) const { return FUNC1D; } double operator()(const double * x) const { return (*this)(*x); } double Eval(double x) const { return FUNC1D; } double Derivative(double x) const { return FUNC1D; } }; class DerivFunction : public ROOT::Math::IMultiGenFunction { public: unsigned int NDim() const { return 2; } DerivFunction * Clone() const { return new DerivFunction(); } private: double DoEval(const double *x) const { return FUNC; } }; class DerivFunction1D : public ROOT::Math::IGenFunction { public: DerivFunction1D * Clone() const { return new DerivFunction1D(); } private: double DoEval(double x) const { return FUNC1D; } }; struct F1D { double Eval(double x) { return FUNC1D; } }; const int Ntimes = NTIMES; template void TestTime(const Func & f) { //double x[Ntimes]; // use std::vector's to avoid crashes on Windows std::vector x(Ntimes); TStopwatch w; TRandom2 r; r.RndmArray(Ntimes,&x[0]); w. Start(); double s=0; for (int ipass = 0; ipass void TestTimePF( PFunc & f) { //double x[Ntimes]; // use std::vector's to avoid crashes on Windows std::vector x(Ntimes); TStopwatch w; TRandom2 r; r.RndmArray(Ntimes,&x[0]); w. Start(); double s=0; double * p = 0; for (int ipass = 0; ipass x(Ntimes); TStopwatch w; TRandom2 r; r.RndmArray(Ntimes,&x[0]); w. Start(); double s=0; for (int ipass = 0; ipass x(Ntimes); TStopwatch w; TRandom2 r; r.RndmArray(Ntimes,&x[0]); w. Start(); double s=0; // RooArgSet * varSet = f.getVariables(); // RooArgList varList(*varSet); // delete varSet; // RooAbsArg & arg = varList[0]; // RooRealVar * vars = dynamic_cast (&arg); // assert(x != 0); for (int ipass = 0; ipass setVal(x[i+1]); double y = x[i]*f.getVal(); s+= y; } } w.Stop(); std::cout << "Time for " << "RooPdf\t\t" << "\t: " << w.RealTime() << " " << w.CpuTime() << std::endl; std::cout << s << std::endl; } #endif // test all functor constructs void testMultiDim() { // multi-dim test std::cout <<"\n**************************************************************\n"; std::cout <<"Test of Multi-dim functors" << std::endl; std::cout <<"***************************************************************\n\n"; // test directly calling the function object MyFunction myf; TestTime(myf); // test from a free function pointer ROOT::Math::Functor f1(&freeFunction,2); TestTime(f1); // test from function object ROOT::Math::Functor f2(myf,2); TestTime(f2); // test from a member function ROOT::Math::Functor f3(&myf,&MyFunction::Eval,2); TestTime(f3); // test grad functor from an object providing eval and deriv. ROOT::Math::GradFunctor f4(myf,2); TestTime(f4); // test grad functor from object and member functions ROOT::Math::GradFunctor f5(&myf,&MyFunction::Eval, &MyFunction::Derivative, 2); TestTime(f5); // test from 2 function objects MyDerivFunction myderf; ROOT::Math::GradFunctor f6(myf,myderf, 2); TestTime(f6); } // test all functor constructs void testOneDim() { // test 1D functors std::cout <<"\n**************************************************************\n"; std::cout <<"Test of 1D functors" << std::endl; std::cout <<"***************************************************************\n\n"; // test dircectly calling function object MyFunction1D myf1; TestTime(myf1); /// test free function ROOT::Math::Functor1D f1(&freeFunction1D); TestTime(f1); // test from function object ROOT::Math::Functor1D f2(myf1); TestTime(f2); // test from member function ROOT::Math::Functor1D f3(&myf1,&MyFunction1D::Derivative); TestTime(f3); // testgrad functor // from function object implementing both ROOT::Math::GradFunctor1D f4(myf1); TestTime(f4); // test grad functor from object and member functions ROOT::Math::GradFunctor1D f5(&myf1,&MyFunction1D::Eval, &MyFunction1D::Derivative); TestTime(f5); // test from 2 function objects ROOT::Math::GradFunctor1D f6(&freeFunction1D,myf1); TestTime(f6); } void testMore() { std::cout <<"\n**************************************************************\n"; std::cout <<"Extra functor tests" << std::endl; std::cout <<"***************************************************************\n\n"; ROOT::Math::ParamFunctor fp1(&freeRootFunc2D); TestTimePF(fp1); // ROOT::Math::ParamFunctor1D fp2(&freeParamFunc1D); // TestTimePF(fp2); DerivFunction fdf; TestTime(fdf); //1D DerivFunction1D f13; TestTime(f13); //TestTimeGF(f3); typedef double( * FreeFunc ) (double ); ROOT::Math::WrappedFunction<> f5(freeFunction1D); TestTime(f5); ROOT::Math::WrappedMultiFunction<> f5b(freeFunction,2); TestTime(f5b); F1D fobj; //std::cout << typeid(&F1D::Eval).name() << std::endl; ROOT::Math::Functor1D f6(std::bind1st(std::mem_fun(&F1D::Eval), &fobj) ); TestTime(f6); ROOT::Math::WrappedFunction > > f6a((std::bind1st(std::mem_fun(&F1D::Eval), &fobj))); TestTime(f6a); //ROOT::Math::WrappedMemFunction f6b(&fobj, &F1D::Eval, ); // typedef double (F1D::*MemFun)(double); // double (F1D::*p1 )(double) = &F1D::Eval; // std::cout << typeid(p1).name() << std::endl; ROOT::Math::WrappedMemFunction f6b(fobj, &F1D::Eval ); TestTime(f6b); ROOT::Math::Functor1D f6c(&fobj, &F1D::Eval ); TestTime(f6c); #ifdef LATER FunctorNV f5(myf); TestTime(f5); // test of virtuality two times Functor f6(f3); TestTime(f6); #endif TF1 tf1("tf1",freeRootFunc2D,0,1,0); //TF2 tf1("tf1","x+y",0,1,0,1); TestTimeTF1(tf1); // ROOT::Fit::WrappedTF1 f7(&tf1); // TestTime(f7); ROOT::Math::WrappedMultiTF1 f7b(tf1); TestTime(f7b); TestTimePF(f7b); ROOT::Math::WrappedParamFunction<> wf7(&freeRootFunc2D,2,0,0); TestTime(wf7); TestTimePF(wf7); // use the fact that TF1 implements operator(double *, double *) ROOT::Math::WrappedParamFunction wf7b(&tf1,2,0,0); TestTimePF(wf7b); TF1 tf2("tf2",freeRootFunc1D,0,1,0); TestTimeTF1(tf2); ROOT::Math::WrappedTF1 f7c(tf2); TestTime(f7c); // double xx[1] = {2}; // f7(xx); ROOT::Math::Functor f8(f7b,f7b.NDim()); TestTime(f8); // this does not compile oin Windows, since it does not understand the default arguments // It does not work for gcc 4.3 either. // #ifndef _WIN32 // ROOT::Math::Functor1D f9(&tf1,&TF1::Eval); // TestTime(f9); // ROOT::Math::Functor f10(&tf1,&TF1::EvalPar,tf1.GetNdim()); // TestTime(f10); // #endif // test with rootit #ifdef HAVE_ROOFIT RooRealVar x("x","x",0); RooRealVar c("c","c",1.,1.,1.); RooExponential rooExp("exp","exponential",x,c); TestTimeRooPdf(rooExp,&x); #endif } int main() { testMultiDim(); testOneDim(); testMore(); return 0; }