Logo ROOT   6.10/09
Reference Guide
WrappedMultiTF1.h
Go to the documentation of this file.
1 // @(#)root/mathmore:$Id$
2 // Author: L. Moneta Wed Sep 6 09:52:26 2006
3 
4 /**********************************************************************
5  * *
6  * Copyright (c) 2006 LCG ROOT Math Team, CERN/PH-SFT *
7  * *
8  * *
9  **********************************************************************/
10 
11 // Header file for class WrappedTFunction
12 
13 #ifndef ROOT_Math_WrappedMultiTF1
14 #define ROOT_Math_WrappedMultiTF1
15 
16 
17 #include "Math/IParamFunction.h"
18 
19 #include "TF1.h"
20 
21 namespace ROOT {
22 
23  namespace Math {
24 
25  namespace Internal {
26  double DerivPrecision(double eps);
27  TF1 *CopyTF1Ptr(const TF1 *funcToCopy);
28  };
29  /**
30  Class to Wrap a ROOT Function class (like TF1) in a IParamMultiFunction interface
31  of multi-dimensions to be used in the ROOT::Math numerical algorithm.
32  This wrapper class does not own the TF1 pointer, so it assumes it exists during the wrapper lifetime.
33  The class copy the TF1 pointer only when it owns it.
34 
35  The class from ROOT version 6.03 does not contain anymore a copy of the parameters. The parameters are
36  stored in the TF1 class.
37 
38  @ingroup CppFunctions
39  */
40 
41  //LM note: are there any issues when cloning the class for the parameters that are not copied anymore ??
42 
43  template<class T>
45 
46  public:
47 
50 
51  /**
52  constructor from a function pointer to a TF1
53  If dim = 0 dimension is taken from TF1::GetNdim().
54  IN case of multi-dimensional function created using directly TF1 object the dimension
55  returned by TF1::GetNdim is always 1. The user must then pass the correct value of dim
56  */
57  WrappedMultiTF1Templ(TF1 &f, unsigned int dim = 0);
58 
59  /**
60  Destructor (no operations). Function pointer is not owned
61  */
63  {
64  if (fOwnFunc && fFunc) delete fFunc;
65  }
66 
67  /**
68  Copy constructor
69  */
71 
72  /**
73  Assignment operator
74  */
76 
77  /** @name interface inherited from IParamFunction */
78 
79  /**
80  Clone the wrapper but not the original function
81  */
83  {
84  return new WrappedMultiTF1Templ<T>(*this);
85  }
86 
87  /**
88  Retrieve the dimension of the function
89  */
90  unsigned int NDim() const
91  {
92  return fDim;
93  }
94 
95  /// get the parameter values (return values from TF1)
96  const double *Parameters() const
97  {
98  //return (fParams.size() > 0) ? &fParams.front() : 0;
99  return fFunc->GetParameters();
100  }
101 
102  /// set parameter values (only the cached one in this class,leave unchanges those of TF1)
103  void SetParameters(const double *p)
104  {
105  //std::copy(p,p+fParams.size(),fParams.begin());
106  fFunc->SetParameters(p);
107  }
108 
109  /// return number of parameters
110  unsigned int NPar() const
111  {
112  // return fParams.size();
113  return fFunc->GetNpar();
114  }
115 
116  /// return parameter name (from TF1)
117  std::string ParameterName(unsigned int i) const {
118  return std::string(fFunc->GetParName(i));
119  }
120 
121  // evaluate the derivative of the function with respect to the parameters
122  void ParameterGradient(const double *x, const double *par, double *grad) const;
123 
124  /// precision value used for calculating the derivative step-size
125  /// h = eps * |x|. The default is 0.001, give a smaller in case function changes rapidly
126  static void SetDerivPrecision(double eps);
127 
128  /// get precision value used for calculating the derivative step-size
129  static double GetDerivPrecision();
130 
131  /// method to retrieve the internal function pointer
132  const TF1 *GetFunction() const
133  {
134  return fFunc;
135  }
136 
137  /// method to set a new function pointer and copy it inside.
138  /// By calling this method the class manages now the passed TF1 pointer
139  void SetAndCopyFunction(const TF1 *f = 0);
140 
141  private:
142  /// evaluate function passing coordinates x and vector of parameters
143  T DoEvalPar(const T *x, const double *p) const
144  {
145  return fFunc->EvalPar(x, p);
146  }
147 
148  /// evaluate function using the cached parameter values (of TF1)
149  /// re-implement for better efficiency
150  T DoEvalVec(const T *x) const
151  {
152  return fFunc->EvalPar(x, 0);
153  }
154 
155  /// evaluate function using the cached parameter values (of TF1)
156  /// re-implement for better efficiency
157  T DoEval(const T *x) const
158  {
159  // no need to call InitArg for interpreted functions (done in ctor)
160 
161  //const double * p = (fParams.size() > 0) ? &fParams.front() : 0;
162  return fFunc->EvalPar(x, 0);
163  }
164 
165  /// evaluate the partial derivative with respect to the parameter
166  double DoParameterDerivative(const double *x, const double *p, unsigned int ipar) const;
167 
168  bool fLinear; // flag for linear functions
169  bool fPolynomial; // flag for polynomial functions
170  bool fOwnFunc; // flag to indicate we own the TF1 function pointer
171  TF1 *fFunc; // pointer to ROOT function
172  unsigned int fDim; // cached value of dimension
173  //std::vector<double> fParams; // cached vector with parameter values
174 
175  };
176 
177 // impelmentations for WrappedMultiTF1Templ<T>
178  template<class T>
180  fLinear(false),
181  fPolynomial(false),
182  fOwnFunc(false),
183  fFunc(&f),
184  fDim(dim)
185  //fParams(f.GetParameters(),f.GetParameters()+f.GetNpar())
186  {
187  // constructor of WrappedMultiTF1Templ<T>
188  // pass a dimension if dimension specified in TF1 does not correspond to real dimension
189  // for example in case of multi-dimensional TF1 objects defined as TF1 (i.e. for functions with dims > 3 )
190  if (fDim == 0) fDim = fFunc->GetNdim();
191 
192  // check that in case function is linear the linear terms are not zero
193  // function is linear when is a TFormula created with "++"
194  // hyperplane are not yet existing in TFormula
195  if (fFunc->IsLinear()) {
196  int ip = 0;
197  fLinear = true;
198  while (fLinear && ip < fFunc->GetNpar()) {
199  fLinear &= (fFunc->GetLinearPart(ip) != 0) ;
200  ip++;
201  }
202  }
203  // distinguish case of polynomial functions and linear functions
204  if (fDim == 1 && fFunc->GetNumber() >= 300 && fFunc->GetNumber() < 310) {
205  fLinear = true;
206  fPolynomial = true;
207  }
208  }
209 
210  template<class T>
212  BaseFunc(),
213  BaseParamFunc(),
214  fLinear(rhs.fLinear),
216  fOwnFunc(rhs.fOwnFunc),
217  fFunc(rhs.fFunc),
218  fDim(rhs.fDim)
219  //fParams(rhs.fParams)
220  {
221  // copy constructor
223  }
224 
225  template<class T>
227  {
228  // Assignment operator
229  if (this == &rhs) return *this; // time saving self-test
230  fLinear = rhs.fLinear;
231  fPolynomial = rhs.fPolynomial;
232  fOwnFunc = rhs.fOwnFunc;
233  fDim = rhs.fDim;
234  //fParams = rhs.fParams;
235  return *this;
236  }
237 
238  template<class T>
239  void WrappedMultiTF1Templ<T>::ParameterGradient(const double *x, const double *par, double *grad) const
240  {
241  // evaluate the gradient of the function with respect to the parameters
242  //IMPORTANT NOTE: TF1::GradientPar returns 0 for fixed parameters to avoid computing useless derivatives
243  // BUT the TLinearFitter wants to have the derivatives also for fixed parameters.
244  // so in case of fLinear (or fPolynomial) a non-zero value will be returned for fixed parameters
245 
246  if (!fLinear) {
247  // need to set parameter values
248  fFunc->SetParameters(par);
249  // no need to call InitArgs (it is called in TF1::GradientPar)
250  double prec = this->GetDerivPrecision();
251  fFunc->GradientPar(x, grad, prec);
252  } else { // case of linear functions
253  unsigned int np = NPar();
254  for (unsigned int i = 0; i < np; ++i)
255  grad[i] = DoParameterDerivative(x, par, i);
256  }
257  }
258 
259  template<class T>
260  double WrappedMultiTF1Templ<T>::DoParameterDerivative(const double *x, const double *p, unsigned int ipar) const
261  {
262  // evaluate the derivative of the function with respect to parameter ipar
263  // see note above concerning the fixed parameters
264  if (! fLinear) {
265  fFunc->SetParameters(p);
266  double prec = this->GetDerivPrecision();
267  return fFunc->GradientPar(ipar, x, prec);
268  }
269  if (fPolynomial) {
270  // case of polynomial function (no parameter dependency) (case for dim = 1)
271  assert(fDim == 1);
272  if (ipar == 0) return 1.0;
273  return std::pow(x[0], static_cast<int>(ipar));
274  } else {
275  // case of general linear function (built in TFormula with ++ )
276  const TFormula *df = dynamic_cast<const TFormula *>(fFunc->GetLinearPart(ipar));
277  assert(df != 0);
278  return (const_cast<TFormula *>(df))->EvalPar(x) ; // derivatives should not depend on parameters since
279  // function is linear
280  }
281  }
282 
283  template<class T>
285  {
287  }
288 
289  template<class T>
291  {
293  }
294 
295  template<class T>
297  {
298  const TF1 *funcToCopy = (f) ? f : fFunc;
300  fOwnFunc = true;
301  }
302 
304 
305  } // end namespace Math
306 
307 } // end namespace ROOT
308 
309 
310 #endif /* ROOT_Fit_WrappedMultiTF1 */
double par[1]
Definition: unuranDistr.cxx:38
virtual void SetParameters(const Double_t *params)
Definition: TF1.h:588
Namespace for new ROOT classes and functions.
Definition: StringConv.hxx:21
double T(double x)
Definition: ChebyshevPol.h:34
double DoParameterDerivative(const double *x, const double *p, unsigned int ipar) const
evaluate the partial derivative with respect to the parameter
const TF1 * GetFunction() const
method to retrieve the internal function pointer
Interface (abstract class) for parametric gradient multi-dimensional functions providing in addition ...
void SetParameters(const double *p)
set parameter values (only the cached one in this class,leave unchanges those of TF1) ...
Double_t x[n]
Definition: legend1.C:17
static double GetDerivPrecision()
get precision value used for calculating the derivative step-size
unsigned int NPar() const
return number of parameters
Class to Wrap a ROOT Function class (like TF1) in a IParamMultiFunction interface of multi-dimensions...
double pow(double, double)
virtual Int_t GetNdim() const
Definition: TF1.h:439
virtual Double_t GradientPar(Int_t ipar, const Double_t *x, Double_t eps=0.01)
Compute the gradient (derivative) wrt a parameter ipar.
Definition: TF1.cxx:2176
void ParameterGradient(const double *x, const double *par, double *grad) const
Evaluate the all the derivatives (gradient vector) of the function with respect to the parameters at ...
ROOT::Math::IParametricGradFunctionMultiDimTempl< T > BaseParamFunc
Documentation for the abstract class IBaseFunctionMultiDim.
Definition: IFunction.h:62
TF1 * CopyTF1Ptr(const TF1 *funcToCopy)
Definition: WrappedTF1.cxx:33
std::string ParameterName(unsigned int i) const
return parameter name (from TF1)
T DoEvalVec(const T *x) const
evaluate function using the cached parameter values (of TF1) re-implement for better efficiency ...
The Formula class.
Definition: TFormula.h:83
virtual const TObject * GetLinearPart(Int_t i) const
Definition: TF1.h:419
T DoEvalPar(const T *x, const double *p) const
evaluate function passing coordinates x and vector of parameters
virtual Bool_t IsLinear() const
Definition: TF1.h:546
WrappedMultiTF1Templ(TF1 &f, unsigned int dim=0)
constructor from a function pointer to a TF1 If dim = 0 dimension is taken from TF1::GetNdim().
IMultiGenFunctionTempl< T > * Clone() const
Clone the wrapper but not the original function.
static void SetDerivPrecision(double eps)
precision value used for calculating the derivative step-size h = eps * |x|.
ROOT::Math::IParametricFunctionMultiDimTempl< T >::BaseFunc BaseFunc
double f(double x)
double DerivPrecision(double eps)
Definition: WrappedTF1.cxx:25
~WrappedMultiTF1Templ()
Destructor (no operations).
Namespace for new Math classes and functions.
Binding & operator=(OUT(*fun)(void))
unsigned int NDim() const
Retrieve the dimension of the function.
T DoEval(const T *x) const
evaluate function using the cached parameter values (of TF1) re-implement for better efficiency ...
1-Dim function class
Definition: TF1.h:150
WrappedMultiTF1Templ & operator=(const WrappedMultiTF1Templ< T > &rhs)
Assignment operator.
const double * Parameters() const
get the parameter values (return values from TF1)
virtual Int_t GetNumber() const
Definition: TF1.h:452
void SetAndCopyFunction(const TF1 *f=0)
method to set a new function pointer and copy it inside.