Logo ROOT  
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 #include <string>
21 #include <vector>
22 
23 namespace ROOT {
24 
25  namespace Math {
26 
27  namespace Internal {
28  double DerivPrecision(double eps);
29  TF1 *CopyTF1Ptr(const TF1 *funcToCopy);
30  };
31 
32  /**
33  Class to Wrap a ROOT Function class (like TF1) in a IParamMultiFunction interface
34  of multi-dimensions to be used in the ROOT::Math numerical algorithm.
35  This wrapper class does not own the TF1 pointer, so it assumes it exists during the wrapper lifetime.
36  The class copy the TF1 pointer only when it owns it.
37 
38  The class from ROOT version 6.03 does not contain anymore a copy of the parameters. The parameters are
39  stored in the TF1 class.
40 
41  @ingroup CppFunctions
42  */
43 
44  //LM note: are there any issues when cloning the class for the parameters that are not copied anymore ??
45 
46  template<class T>
48 
49  public:
50 
53 
54  /**
55  constructor from a function pointer to a TF1
56  If dim = 0 dimension is taken from TF1::GetNdim().
57  IN case of multi-dimensional function created using directly TF1 object the dimension
58  returned by TF1::GetNdim is always 1. The user must then pass the correct value of dim
59  */
60  WrappedMultiTF1Templ(TF1 &f, unsigned int dim = 0);
61 
62  /**
63  Destructor (no operations). Function pointer is not owned
64  */
66  {
67  if (fOwnFunc && fFunc) delete fFunc;
68  }
69 
70  /**
71  Copy constructor
72  */
74 
75  /**
76  Assignment operator
77  */
79 
80  /** @name interface inherited from IParamFunction */
81 
82  /**
83  Clone the wrapper but not the original function
84  */
86  {
87  return new WrappedMultiTF1Templ<T>(*this);
88  }
89 
90  /**
91  Retrieve the dimension of the function
92  */
93  unsigned int NDim() const
94  {
95  return fDim;
96  }
97 
98  /// get the parameter values (return values from TF1)
99  const double *Parameters() const
100  {
101  //return (fParams.size() > 0) ? &fParams.front() : 0;
102  return fFunc->GetParameters();
103  }
104 
105  /// set parameter values (only the cached one in this class,leave unchanges those of TF1)
106  void SetParameters(const double *p)
107  {
108  //std::copy(p,p+fParams.size(),fParams.begin());
109  fFunc->SetParameters(p);
110  }
111 
112  /// return number of parameters
113  unsigned int NPar() const
114  {
115  // return fParams.size();
116  return fFunc->GetNpar();
117  }
118 
119  /// return parameter name (from TF1)
120  std::string ParameterName(unsigned int i) const {
121  return std::string(fFunc->GetParName(i));
122  }
123 
124  // evaluate the derivative of the function with respect to the parameters
125  void ParameterGradient(const T *x, const double *par, T *grad) const;
126 
127  /// precision value used for calculating the derivative step-size
128  /// h = eps * |x|. The default is 0.001, give a smaller in case function changes rapidly
129  static void SetDerivPrecision(double eps);
130 
131  /// get precision value used for calculating the derivative step-size
132  static double GetDerivPrecision();
133 
134  /// method to retrieve the internal function pointer
135  const TF1 *GetFunction() const
136  {
137  return fFunc;
138  }
139 
140  /// method to set a new function pointer and copy it inside.
141  /// By calling this method the class manages now the passed TF1 pointer
142  void SetAndCopyFunction(const TF1 *f = 0);
143 
144  private:
145  /// evaluate function passing coordinates x and vector of parameters
146  T DoEvalPar(const T *x, const double *p) const
147  {
148  return fFunc->EvalPar(x, p);
149  }
150 
151  /// evaluate function using the cached parameter values (of TF1)
152  /// re-implement for better efficiency
153  T DoEvalVec(const T *x) const
154  {
155  return fFunc->EvalPar(x, 0);
156  }
157 
158  /// evaluate function using the cached parameter values (of TF1)
159  /// re-implement for better efficiency
160  T DoEval(const T *x) const
161  {
162  // no need to call InitArg for interpreted functions (done in ctor)
163 
164  //const double * p = (fParams.size() > 0) ? &fParams.front() : 0;
165  return fFunc->EvalPar(x, 0);
166  }
167 
168  /// evaluate the partial derivative with respect to the parameter
169  T DoParameterDerivative(const T *x, const double *p, unsigned int ipar) const;
170 
171  bool fLinear; // flag for linear functions
172  bool fPolynomial; // flag for polynomial functions
173  bool fOwnFunc; // flag to indicate we own the TF1 function pointer
174  TF1 *fFunc; // pointer to ROOT function
175  unsigned int fDim; // cached value of dimension
176  //std::vector<double> fParams; // cached vector with parameter values
177 
178  };
179 
180  /**
181  * Auxiliar class to bypass the (provisional) lack of vectorization in TFormula::EvalPar.
182  *
183  * WrappedMultiTF1Templ::DoParameterDerivation calls TFormula::EvalPar in the case of a general linear function
184  * built with TFormula using ++; as EvalPar is not vectorized, in order to generalize DoParameterDerivative with
185  * a general type T, we use this auxiliar class to branch the code in compile time with the double
186  * specialization (that can call EvalPar) and the general implementation (that throws an error in the case of
187  * general linear function).
188  */
189  template <class T>
191  static T DoParameterDerivative(const WrappedMultiTF1Templ<T> *, const T *, unsigned int)
192  {
193  Error("DoParameterDerivative", "The vectorized implementation of DoParameterDerivative does not support"
194  "general linear functions built in TFormula with ++");
195 
196  return TMath::SignalingNaN();
197  }
198  };
199 
200  template <>
202  static double
203  DoParameterDerivative(const WrappedMultiTF1Templ<double> *wrappedFunc, const double *x, unsigned int ipar)
204  {
205  const TFormula *df = dynamic_cast<const TFormula *>(wrappedFunc->GetFunction()->GetLinearPart(ipar));
206  assert(df != 0);
207  return (const_cast<TFormula *>(df))->EvalPar(x); // derivatives should not depend on parameters since
208  // function is linear
209  }
210  };
211 
212  // implementations for WrappedMultiTF1Templ<T>
213  template<class T>
215  fLinear(false),
216  fPolynomial(false),
217  fOwnFunc(false),
218  fFunc(&f),
219  fDim(dim)
220  //fParams(f.GetParameters(),f.GetParameters()+f.GetNpar())
221  {
222  // constructor of WrappedMultiTF1Templ<T>
223  // pass a dimension if dimension specified in TF1 does not correspond to real dimension
224  // for example in case of multi-dimensional TF1 objects defined as TF1 (i.e. for functions with dims > 3 )
225  if (fDim == 0) fDim = fFunc->GetNdim();
226 
227  // check that in case function is linear the linear terms are not zero
228  // function is linear when is a TFormula created with "++"
229  // hyperplane are not yet existing in TFormula
230  if (fFunc->IsLinear()) {
231  int ip = 0;
232  fLinear = true;
233  while (fLinear && ip < fFunc->GetNpar()) {
234  fLinear &= (fFunc->GetLinearPart(ip) != 0) ;
235  ip++;
236  }
237  }
238  // distinguish case of polynomial functions and linear functions
239  if (fDim == 1 && fFunc->GetNumber() >= 300 && fFunc->GetNumber() < 310) {
240  fLinear = true;
241  fPolynomial = true;
242  }
243  }
244 
245  template<class T>
247  BaseParamFunc(rhs),
248  fLinear(rhs.fLinear),
249  fPolynomial(rhs.fPolynomial),
250  fOwnFunc(rhs.fOwnFunc),
251  fFunc(rhs.fFunc),
252  fDim(rhs.fDim)
253  //fParams(rhs.fParams)
254  {
255  // copy constructor
257  }
258 
259  template<class T>
261  {
262  // Assignment operator
263  if (this == &rhs) return *this; // time saving self-test
264  fLinear = rhs.fLinear;
265  fPolynomial = rhs.fPolynomial;
266  fOwnFunc = rhs.fOwnFunc;
267  fDim = rhs.fDim;
268  //fParams = rhs.fParams;
269  return *this;
270  }
271 
272  template <class T>
273  void WrappedMultiTF1Templ<T>::ParameterGradient(const T *x, const double *par, T *grad) const
274  {
275  // evaluate the gradient of the function with respect to the parameters
276  //IMPORTANT NOTE: TF1::GradientPar returns 0 for fixed parameters to avoid computing useless derivatives
277  // BUT the TLinearFitter wants to have the derivatives also for fixed parameters.
278  // so in case of fLinear (or fPolynomial) a non-zero value will be returned for fixed parameters
279 
280  if (!fLinear) {
281  // need to set parameter values
282  fFunc->SetParameters(par);
283  // no need to call InitArgs (it is called in TF1::GradientPar)
284  double prec = this->GetDerivPrecision();
285  fFunc->GradientPar(x, grad, prec);
286  } else { // case of linear functions
287  unsigned int np = NPar();
288  for (unsigned int i = 0; i < np; ++i)
289  grad[i] = DoParameterDerivative(x, par, i);
290  }
291  }
292 
293  template <class T>
294  T WrappedMultiTF1Templ<T>::DoParameterDerivative(const T *x, const double *p, unsigned int ipar) const
295  {
296  // evaluate the derivative of the function with respect to parameter ipar
297  // see note above concerning the fixed parameters
298  if (!fLinear) {
299  fFunc->SetParameters(p);
300  double prec = this->GetDerivPrecision();
301  return fFunc->GradientPar(ipar, x, prec);
302  }
303  if (fPolynomial) {
304  // case of polynomial function (no parameter dependency) (case for dim = 1)
305  assert(fDim == 1);
306  if (ipar == 0) return 1.0;
307 #ifdef R__HAS_VECCORE
308  return vecCore::math::Pow(x[0], static_cast<T>(ipar));
309 #else
310  return std::pow(x[0], static_cast<int>(ipar));
311 #endif
312  } else {
313  // case of general linear function (built in TFormula with ++ )
315  }
316  }
317  template<class T>
319  {
321  }
322 
323  template<class T>
325  {
327  }
328 
329  template<class T>
331  {
332  const TF1 *funcToCopy = (f) ? f : fFunc;
333  fFunc = ::ROOT::Math::Internal::CopyTF1Ptr(funcToCopy);
334  fOwnFunc = true;
335  }
336 
338 
339  } // end namespace Math
340 
341 } // end namespace ROOT
342 
343 
344 #endif /* ROOT_Fit_WrappedMultiTF1 */
ROOT::Math::WrappedMultiTF1Templ
Class to Wrap a ROOT Function class (like TF1) in a IParamMultiFunction interface of multi-dimensions...
Definition: WrappedMultiTF1.h:47
ROOT::Math::WrappedMultiTF1Templ::DoEval
T DoEval(const T *x) const
evaluate function using the cached parameter values (of TF1) re-implement for better efficiency
Definition: WrappedMultiTF1.h:160
f
#define f(i)
Definition: RSha256.hxx:104
TFormula
The Formula class.
Definition: TFormula.h:86
ROOT::Math::WrappedMultiTF1Templ::DoEvalPar
T DoEvalPar(const T *x, const double *p) const
evaluate function passing coordinates x and vector of parameters
Definition: WrappedMultiTF1.h:146
ROOT::Math::WrappedMultiTF1Templ::WrappedMultiTF1Templ
WrappedMultiTF1Templ(TF1 &f, unsigned int dim=0)
constructor from a function pointer to a TF1 If dim = 0 dimension is taken from TF1::GetNdim().
Definition: WrappedMultiTF1.h:214
TF1::GetParameters
virtual Double_t * GetParameters() const
Definition: TF1.h:519
TF1::GetNdim
virtual Int_t GetNdim() const
Definition: TF1.h:484
ROOT::Math::GeneralLinearFunctionDerivation
Auxiliar class to bypass the (provisional) lack of vectorization in TFormula::EvalPar.
Definition: WrappedMultiTF1.h:190
TF1::GetNpar
virtual Int_t GetNpar() const
Definition: TF1.h:480
ROOT::Math::WrappedMultiTF1Templ::fFunc
TF1 * fFunc
Definition: WrappedMultiTF1.h:174
x
Double_t x[n]
Definition: legend1.C:17
ROOT::Math::WrappedMultiTF1Templ::~WrappedMultiTF1Templ
~WrappedMultiTF1Templ()
Destructor (no operations).
Definition: WrappedMultiTF1.h:65
ROOT::Math::WrappedMultiTF1Templ::Clone
IMultiGenFunctionTempl< T > * Clone() const
Clone the wrapper but not the original function.
Definition: WrappedMultiTF1.h:85
ROOT::Math::WrappedMultiTF1Templ::Parameters
const double * Parameters() const
get the parameter values (return values from TF1)
Definition: WrappedMultiTF1.h:99
ROOT::Math::WrappedMultiTF1Templ::GetFunction
const TF1 * GetFunction() const
method to retrieve the internal function pointer
Definition: WrappedMultiTF1.h:135
ROOT::Math::WrappedMultiTF1Templ::BaseFunc
ROOT::Math::IParametricFunctionMultiDimTempl< T >::BaseFunc BaseFunc
Definition: WrappedMultiTF1.h:52
ROOT::Math::GeneralLinearFunctionDerivation::DoParameterDerivative
static T DoParameterDerivative(const WrappedMultiTF1Templ< T > *, const T *, unsigned int)
Definition: WrappedMultiTF1.h:191
ROOT::Math::WrappedMultiTF1Templ::SetParameters
void SetParameters(const double *p)
set parameter values (only the cached one in this class,leave unchanges those of TF1)
Definition: WrappedMultiTF1.h:106
TF1::GetNumber
virtual Int_t GetNumber() const
Definition: TF1.h:497
TF1::SetParameters
virtual void SetParameters(const Double_t *params)
Definition: TF1.h:643
ROOT::Math::IParametricGradFunctionMultiDimTempl
Interface (abstract class) for parametric gradient multi-dimensional functions providing in addition ...
Definition: IParamFunction.h:224
ROOT::Math::WrappedMultiTF1Templ::BaseParamFunc
ROOT::Math::IParametricGradFunctionMultiDimTempl< T > BaseParamFunc
Definition: WrappedMultiTF1.h:51
ROOT::Math::GeneralLinearFunctionDerivation< double >::DoParameterDerivative
static double DoParameterDerivative(const WrappedMultiTF1Templ< double > *wrappedFunc, const double *x, unsigned int ipar)
Definition: WrappedMultiTF1.h:203
ROOT::Math::WrappedMultiTF1Templ::SetAndCopyFunction
void SetAndCopyFunction(const TF1 *f=0)
method to set a new function pointer and copy it inside.
Definition: WrappedMultiTF1.h:330
ROOT::Math::WrappedMultiTF1Templ::DoEvalVec
T DoEvalVec(const T *x) const
evaluate function using the cached parameter values (of TF1) re-implement for better efficiency
Definition: WrappedMultiTF1.h:153
ROOT::Math::WrappedMultiTF1Templ::fPolynomial
bool fPolynomial
Definition: WrappedMultiTF1.h:172
TF1::GetParName
virtual const char * GetParName(Int_t ipar) const
Definition: TF1.h:528
ROOT::Math::WrappedMultiTF1Templ::SetDerivPrecision
static void SetDerivPrecision(double eps)
precision value used for calculating the derivative step-size h = eps * |x|.
Definition: WrappedMultiTF1.h:318
double
double
Definition: Converters.cxx:921
ROOT::Math::WrappedMultiTF1Templ::NPar
unsigned int NPar() const
return number of parameters
Definition: WrappedMultiTF1.h:113
TF1::GetLinearPart
virtual const TObject * GetLinearPart(Int_t i) const
Definition: TF1.h:464
TMath::SignalingNaN
Double_t SignalingNaN()
Returns a signaling NaN as defined by IEEE 754](http://en.wikipedia.org/wiki/NaN#Signaling_NaN)
Definition: TMath.h:908
IParamFunction.h
TF1::EvalPar
virtual Double_t EvalPar(const Double_t *x, const Double_t *params=0)
Evaluate function with given coordinates and parameters.
Definition: TF1.cxx:1479
ROOT::Math::WrappedMultiTF1Templ::ParameterName
std::string ParameterName(unsigned int i) const
return parameter name (from TF1)
Definition: WrappedMultiTF1.h:120
ROOT::Math::WrappedMultiTF1Templ::NDim
unsigned int NDim() const
Retrieve the dimension of the function.
Definition: WrappedMultiTF1.h:93
TF1.h
ROOT::Math::WrappedMultiTF1Templ::DoParameterDerivative
T DoParameterDerivative(const T *x, const double *p, unsigned int ipar) const
evaluate the partial derivative with respect to the parameter
Definition: WrappedMultiTF1.h:294
ROOT::Math::WrappedMultiTF1Templ::operator=
WrappedMultiTF1Templ & operator=(const WrappedMultiTF1Templ< T > &rhs)
Assignment operator.
Definition: WrappedMultiTF1.h:260
ROOT::Math::Internal::DerivPrecision
double DerivPrecision(double eps)
Definition: WrappedTF1.cxx:25
ROOT::Math::WrappedMultiTF1Templ::fDim
unsigned int fDim
Definition: WrappedMultiTF1.h:175
ROOT::Math::Chebyshev::T
double T(double x)
Definition: ChebyshevPol.h:34
ROOT::Math::Internal::CopyTF1Ptr
TF1 * CopyTF1Ptr(const TF1 *funcToCopy)
Definition: WrappedTF1.cxx:33
ROOT::Math::WrappedMultiTF1Templ::fOwnFunc
bool fOwnFunc
Definition: WrappedMultiTF1.h:173
ROOT::Math::IBaseFunctionMultiDimTempl
Documentation for the abstract class IBaseFunctionMultiDim.
Definition: IFunction.h:62
ROOT::Math::WrappedMultiTF1Templ::fLinear
bool fLinear
Definition: WrappedMultiTF1.h:171
TF1
1-Dim function class
Definition: TF1.h:213
pow
double pow(double, double)
ROOT::Math::WrappedMultiTF1Templ::GetDerivPrecision
static double GetDerivPrecision()
get precision value used for calculating the derivative step-size
Definition: WrappedMultiTF1.h:324
ROOT
VSD Structures.
Definition: StringConv.hxx:21
TF1::IsLinear
virtual Bool_t IsLinear() const
Definition: TF1.h:601
Math
Namespace for new Math classes and functions.
ROOT::Math::WrappedMultiTF1Templ::ParameterGradient
void ParameterGradient(const T *x, const double *par, T *grad) const
Evaluate the all the derivatives (gradient vector) of the function with respect to the parameters at ...
Definition: WrappedMultiTF1.h:273
Error
void Error(const char *location, const char *msgfmt,...)
Use this function in case an error occurred.
Definition: TError.cxx:187