ROOT logo
// @(#)root/mathmore:$Id$
// Author: L. Moneta Wed Sep  6 09:52:26 2006

/**********************************************************************
 *                                                                    *
 * Copyright (c) 2006  LCG ROOT Math Team, CERN/PH-SFT                *
 *                                                                    *
 *                                                                    *
 **********************************************************************/

// Header file for class WrappedTF1

#ifndef ROOT_Math_WrappedTF1
#define ROOT_Math_WrappedTF1


#ifndef ROOT_Math_IParamFunction
#include "Math/IParamFunction.h"
#endif

#ifndef ROOT_TF1
#include "TF1.h"
#endif

namespace ROOT { 

   namespace Math { 


/** 
   Class to Wrap a ROOT Function class (like TF1)  in a IParamFunction interface
   of one dimensions to be used in the ROOT::Math numerical algorithms
   The parameter are stored in this wrapper class, so  the TF1 parameter values are not used for evaluating the function. 
   We use TF1 only for the function evaluation. 
   This allows for the copy of the wrapper function without the need to copy the TF1. 
   The wrapper does not own the TF1 pointer, so it assumes it exists during the wrapper lifetime

   @ingroup CppFunctions
*/ 
class WrappedTF1 : public ROOT::Math::IParamGradFunction, public ROOT::Math::IGradientOneDim {

public: 

   typedef  ROOT::Math::IGradientOneDim     IGrad;
   typedef  ROOT::Math::IParamGradFunction  BaseGradFunc; 
   typedef  ROOT::Math::IParamGradFunction::BaseFunc BaseFunc; 
 

   /** 
      constructor from a TF1 function pointer. 
   */ 
   WrappedTF1 ( TF1 & f  ); 

   /** 
      Destructor (no operations). TF1 Function pointer is not owned
   */ 
   virtual ~WrappedTF1 () {}

   /** 
      Copy constructor
   */ 
   WrappedTF1(const WrappedTF1 & rhs);

   /** 
      Assignment operator
   */ 
   WrappedTF1 & operator = (const WrappedTF1 & rhs); 

   /** @name interface inherited from IFunction */

   /** 
       Clone the wrapper but not the original function
   */
   ROOT::Math::IGenFunction * Clone() const { 
      return  new WrappedTF1(*this); 
   } 


   /** @name interface inherited from IParamFunction */     

   /// get the parameter values (return values cachen inside, those inside TF1 might be different) 
   const double * Parameters() const {
      return  (fParams.size() > 0) ? &fParams.front() : 0;
   }

   /// set parameter values (only the cached one in this class,leave unchanges those of TF1)
   void SetParameters(const double * p) { 
      std::copy(p,p+fParams.size(),fParams.begin());
   } 

   /// return number of parameters 
   unsigned int NPar() const { 
      return fParams.size();
   }

   /// return parameter name (this is stored in TF1)
   std::string ParameterName(unsigned int i) const { 
      return std::string(fFunc->GetParName(i)); 
   } 


   using BaseGradFunc::operator();

   /// evaluate the derivative of the function with respect to the parameters
   void  ParameterGradient(double x, const double * par, double * grad ) const;

   /// calculate function and derivative at same time (required by IGradient interface)
   void FdF(double x, double & f, double & deriv) const { 
      f = DoEval(x); 
      deriv = DoDerivative(x);
   }      

   /// precision value used for calculating the derivative step-size 
   /// h = eps * |x|. The default is 0.001, give a smaller in case function changes rapidly
   static void SetDerivPrecision(double eps); 

   /// get precision value used for calculating the derivative step-size 
   static double GetDerivPrecision();

private: 


   /// evaluate function passing coordinates x and vector of parameters
   double DoEvalPar (double x, const double * p ) const { 
      fX[0] = x;  
      if (fFunc->GetMethodCall() ) fFunc->InitArgs(fX,p);  // needed for interpreted functions 
      return fFunc->EvalPar(fX,p); 
   }

   /// evaluate function using the cached parameter values of this class (not of TF1)
   /// re-implement for better efficiency
   double DoEval (double x) const { 
      // no need to call InitArg for interpreted functions (done in ctor)
      // use EvalPar since it is much more efficient than Eval
      fX[0] = x;  
      const double * p = (fParams.size() > 0) ? &fParams.front() : 0;
      return fFunc->EvalPar(fX, p ); 
   }

   /// return the function derivatives w.r.t. x 
   double DoDerivative( double  x  ) const;

   /// evaluate the derivative of the function with respect to the parameters
   double  DoParameterDerivative(double x, const double * p, unsigned int ipar ) const; 

   bool fLinear;                 // flag for linear functions 
   bool fPolynomial;             // flag for polynomial functions 
   TF1 * fFunc;                  // pointer to ROOT function
   mutable double fX[1];         //! cached vector for x value (needed for TF1::EvalPar signature) 
   std::vector<double> fParams;  //  cached vector with parameter values

   static double fgEps;          // epsilon used in derivative calculation h ~ eps |x|
}; 

   } // end namespace Fit

} // end namespace ROOT


#endif /* ROOT_Fit_WrappedTF1 */
 WrappedTF1.h:1
 WrappedTF1.h:2
 WrappedTF1.h:3
 WrappedTF1.h:4
 WrappedTF1.h:5
 WrappedTF1.h:6
 WrappedTF1.h:7
 WrappedTF1.h:8
 WrappedTF1.h:9
 WrappedTF1.h:10
 WrappedTF1.h:11
 WrappedTF1.h:12
 WrappedTF1.h:13
 WrappedTF1.h:14
 WrappedTF1.h:15
 WrappedTF1.h:16
 WrappedTF1.h:17
 WrappedTF1.h:18
 WrappedTF1.h:19
 WrappedTF1.h:20
 WrappedTF1.h:21
 WrappedTF1.h:22
 WrappedTF1.h:23
 WrappedTF1.h:24
 WrappedTF1.h:25
 WrappedTF1.h:26
 WrappedTF1.h:27
 WrappedTF1.h:28
 WrappedTF1.h:29
 WrappedTF1.h:30
 WrappedTF1.h:31
 WrappedTF1.h:32
 WrappedTF1.h:33
 WrappedTF1.h:34
 WrappedTF1.h:35
 WrappedTF1.h:36
 WrappedTF1.h:37
 WrappedTF1.h:38
 WrappedTF1.h:39
 WrappedTF1.h:40
 WrappedTF1.h:41
 WrappedTF1.h:42
 WrappedTF1.h:43
 WrappedTF1.h:44
 WrappedTF1.h:45
 WrappedTF1.h:46
 WrappedTF1.h:47
 WrappedTF1.h:48
 WrappedTF1.h:49
 WrappedTF1.h:50
 WrappedTF1.h:51
 WrappedTF1.h:52
 WrappedTF1.h:53
 WrappedTF1.h:54
 WrappedTF1.h:55
 WrappedTF1.h:56
 WrappedTF1.h:57
 WrappedTF1.h:58
 WrappedTF1.h:59
 WrappedTF1.h:60
 WrappedTF1.h:61
 WrappedTF1.h:62
 WrappedTF1.h:63
 WrappedTF1.h:64
 WrappedTF1.h:65
 WrappedTF1.h:66
 WrappedTF1.h:67
 WrappedTF1.h:68
 WrappedTF1.h:69
 WrappedTF1.h:70
 WrappedTF1.h:71
 WrappedTF1.h:72
 WrappedTF1.h:73
 WrappedTF1.h:74
 WrappedTF1.h:75
 WrappedTF1.h:76
 WrappedTF1.h:77
 WrappedTF1.h:78
 WrappedTF1.h:79
 WrappedTF1.h:80
 WrappedTF1.h:81
 WrappedTF1.h:82
 WrappedTF1.h:83
 WrappedTF1.h:84
 WrappedTF1.h:85
 WrappedTF1.h:86
 WrappedTF1.h:87
 WrappedTF1.h:88
 WrappedTF1.h:89
 WrappedTF1.h:90
 WrappedTF1.h:91
 WrappedTF1.h:92
 WrappedTF1.h:93
 WrappedTF1.h:94
 WrappedTF1.h:95
 WrappedTF1.h:96
 WrappedTF1.h:97
 WrappedTF1.h:98
 WrappedTF1.h:99
 WrappedTF1.h:100
 WrappedTF1.h:101
 WrappedTF1.h:102
 WrappedTF1.h:103
 WrappedTF1.h:104
 WrappedTF1.h:105
 WrappedTF1.h:106
 WrappedTF1.h:107
 WrappedTF1.h:108
 WrappedTF1.h:109
 WrappedTF1.h:110
 WrappedTF1.h:111
 WrappedTF1.h:112
 WrappedTF1.h:113
 WrappedTF1.h:114
 WrappedTF1.h:115
 WrappedTF1.h:116
 WrappedTF1.h:117
 WrappedTF1.h:118
 WrappedTF1.h:119
 WrappedTF1.h:120
 WrappedTF1.h:121
 WrappedTF1.h:122
 WrappedTF1.h:123
 WrappedTF1.h:124
 WrappedTF1.h:125
 WrappedTF1.h:126
 WrappedTF1.h:127
 WrappedTF1.h:128
 WrappedTF1.h:129
 WrappedTF1.h:130
 WrappedTF1.h:131
 WrappedTF1.h:132
 WrappedTF1.h:133
 WrappedTF1.h:134
 WrappedTF1.h:135
 WrappedTF1.h:136
 WrappedTF1.h:137
 WrappedTF1.h:138
 WrappedTF1.h:139
 WrappedTF1.h:140
 WrappedTF1.h:141
 WrappedTF1.h:142
 WrappedTF1.h:143
 WrappedTF1.h:144
 WrappedTF1.h:145
 WrappedTF1.h:146
 WrappedTF1.h:147
 WrappedTF1.h:148
 WrappedTF1.h:149
 WrappedTF1.h:150
 WrappedTF1.h:151
 WrappedTF1.h:152
 WrappedTF1.h:153
 WrappedTF1.h:154
 WrappedTF1.h:155
 WrappedTF1.h:156
 WrappedTF1.h:157
 WrappedTF1.h:158
 WrappedTF1.h:159
 WrappedTF1.h:160