ROOT  6.06/09
Reference Guide
WrappedTF1.cxx
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 // implementation file for class WrappedTF1 and WrappedMultiTF1
12 
13 #include "Math/WrappedTF1.h"
14 #include "Math/WrappedMultiTF1.h"
15 #include "TClass.h" // needed to copy the TF1 pointer
16 
17 #include <cmath>
18 
19 
20 namespace ROOT {
21 
22 namespace Math {
23 
24 // static value for epsilon used in derivative calculations
25 double WrappedTF1::fgEps = 0.001;
26 double WrappedMultiTF1::fgEps = 0.001;
27 
28 
30  fLinear(false),
31  fPolynomial(false),
32  fFunc(&f),
33  fX ()
34  //fParams(f.GetParameters(),f.GetParameters()+f.GetNpar())
35 {
36  // constructor from a TF1 function pointer.
37 
38  // init the pointers for CINT
39  //if (fFunc->GetMethodCall() ) fFunc->InitArgs(fX, &fParams.front() );
40  if (fFunc->GetMethodCall() ) fFunc->InitArgs(fX, 0 );
41  // distinguish case of polynomial functions and linear functions
42  if (fFunc->GetNumber() >= 300 && fFunc->GetNumber() < 310) {
43  fLinear = true;
44  fPolynomial = true;
45  }
46  // check that in case function is linear the linear terms are not zero
47  if (fFunc->IsLinear() ) {
48  int ip = 0;
49  fLinear = true;
50  while (fLinear && ip < fFunc->GetNpar() ) {
51  fLinear &= (fFunc->GetLinearPart(ip) != 0) ;
52  ip++;
53  }
54  }
55 }
56 
58  BaseFunc(),
59  BaseGradFunc(),
60  IGrad(),
61  fLinear(rhs.fLinear),
62  fPolynomial(rhs.fPolynomial),
63  fFunc(rhs.fFunc),
64  fX()
65  //fParams(rhs.fParams)
66 {
67  // copy constructor
68  fFunc->InitArgs(fX, 0 );
69 }
70 
72  // assignment operator
73  if (this == &rhs) return *this; // time saving self-test
74  fLinear = rhs.fLinear;
75  fPolynomial = rhs.fPolynomial;
76  fFunc = rhs.fFunc;
77  fFunc->InitArgs(fX, 0 );
78  //fParams = rhs.fParams;
79  return *this;
80 }
81 
82 void WrappedTF1::ParameterGradient(double x, const double * par, double * grad ) const {
83  // evaluate the derivative of the function with respect to the parameters
84  if (!fLinear) {
85  // need to set parameter values
86  fFunc->SetParameters( par );
87  // no need to call InitArgs (it is called in TF1::GradientPar)
88  fFunc->GradientPar(&x,grad,fgEps);
89  }
90  else {
91  unsigned int np = NPar();
92  for (unsigned int i = 0; i < np; ++i)
93  grad[i] = DoParameterDerivative(x, par, i);
94  }
95 }
96 
97 double WrappedTF1::DoDerivative( double x ) const {
98  // return the function derivatives w.r.t. x
99 
100  // parameter are passed as non-const in Derivative
101  //double * p = (fParams.size() > 0) ? const_cast<double *>( &fParams.front()) : 0;
102  return fFunc->Derivative(x,(double *) 0,fgEps);
103 }
104 
105 double WrappedTF1::DoParameterDerivative(double x, const double * p, unsigned int ipar ) const {
106  // evaluate the derivative of the function with respect to the parameters
107  //IMPORTANT NOTE: TF1::GradientPar returns 0 for fixed parameters to avoid computing useless derivatives
108  // BUT the TLinearFitter wants to have the derivatives also for fixed parameters.
109  // so in case of fLinear (or fPolynomial) a non-zero value will be returned for fixed parameters
110 
111  if (! fLinear ) {
112  fFunc->SetParameters( p );
113  return fFunc->GradientPar(ipar, &x,fgEps);
114  }
115  else if (fPolynomial) {
116  // case of polynomial function (no parameter dependency)
117  return std::pow(x, static_cast<int>(ipar) );
118  }
119  else {
120  // case of general linear function (built in TFormula with ++ )
121  const TFormula * df = dynamic_cast<const TFormula*>( fFunc->GetLinearPart(ipar) );
122  assert(df != 0);
123  fX[0] = x;
124  // hack since TFormula::EvalPar is not const
125  return (const_cast<TFormula*> ( df) )->Eval( x ) ; // derivatives should not depend on parameters since func is linear
126  }
127 }
128 
129 void WrappedTF1::SetDerivPrecision(double eps) { fgEps = eps; }
130 
132 
133 
134 
135 // impelmentations for WrappedMultiTF1
136 
137 
138 WrappedMultiTF1::WrappedMultiTF1 (TF1 & f, unsigned int dim ) :
139  fLinear(false),
140  fPolynomial(false),
141  fOwnFunc(false),
142  fFunc(&f),
143  fDim(dim)
144  //fParams(f.GetParameters(),f.GetParameters()+f.GetNpar())
145 {
146  // constructor of WrappedMultiTF1
147  // pass a dimension if dimension specified in TF1 does not correspond to real dimension
148  // for example in case of multi-dimensional TF1 objects defined as TF1 (i.e. for functions with dims > 3 )
149  if (fDim == 0) fDim = fFunc->GetNdim();
150 
151  // check that in case function is linear the linear terms are not zero
152  // function is linear when is a TFormula created with "++"
153  // hyperplane are not yet existing in TFormula
154  if (fFunc->IsLinear() ) {
155  int ip = 0;
156  fLinear = true;
157  while (fLinear && ip < fFunc->GetNpar() ) {
158  fLinear &= (fFunc->GetLinearPart(ip) != 0) ;
159  ip++;
160  }
161  }
162  // distinguish case of polynomial functions and linear functions
163  if (fDim == 1 && fFunc->GetNumber() >= 300 && fFunc->GetNumber() < 310) {
164  fLinear = true;
165  fPolynomial = true;
166  }
167 }
168 
169 
171  BaseFunc(),
172  BaseParamFunc(),
173  fLinear(rhs.fLinear),
174  fPolynomial(rhs.fPolynomial),
175  fOwnFunc(rhs.fOwnFunc),
176  fFunc(rhs.fFunc),
177  fDim(rhs.fDim)
178  //fParams(rhs.fParams)
179 {
180  // copy constructor
182 }
183 
184 
186  // Assignment operator
187  if (this == &rhs) return *this; // time saving self-test
188  fLinear = rhs.fLinear;
189  fPolynomial = rhs.fPolynomial;
190  fOwnFunc = rhs.fOwnFunc;
191  fDim = rhs.fDim;
192  //fParams = rhs.fParams;
193  return *this;
194 }
195 
196 
197 void WrappedMultiTF1::ParameterGradient(const double * x, const double * par, double * grad ) const {
198  // evaluate the gradient of the function with respect to the parameters
199  //IMPORTANT NOTE: TF1::GradientPar returns 0 for fixed parameters to avoid computing useless derivatives
200  // BUT the TLinearFitter wants to have the derivatives also for fixed parameters.
201  // so in case of fLinear (or fPolynomial) a non-zero value will be returned for fixed parameters
202 
203  if (!fLinear) {
204  // need to set parameter values
205  fFunc->SetParameters( par );
206  // no need to call InitArgs (it is called in TF1::GradientPar)
207  fFunc->GradientPar(x,grad,fgEps);
208  }
209  else { // case of linear functions
210  unsigned int np = NPar();
211  for (unsigned int i = 0; i < np; ++i)
212  grad[i] = DoParameterDerivative(x, par, i);
213  }
214 }
215 
216 double WrappedMultiTF1::DoParameterDerivative(const double * x, const double * p, unsigned int ipar ) const {
217  // evaluate the derivative of the function with respect to parameter ipar
218  // see note above concerning the fixed parameters
219  if (! fLinear ) {
220  fFunc->SetParameters( p );
221  return fFunc->GradientPar(ipar, x,fgEps);
222  }
223  if (fPolynomial) {
224  // case of polynomial function (no parameter dependency) (case for dim = 1)
225  assert (fDim == 1);
226  if (ipar == 0) return 1.0;
227  return std::pow(x[0], static_cast<int>(ipar) );
228  }
229  else {
230  // case of general linear function (built in TFormula with ++ )
231  const TFormula * df = dynamic_cast<const TFormula*>( fFunc->GetLinearPart(ipar) );
232  assert(df != 0);
233  return (const_cast<TFormula*> ( df) )->EvalPar( x ) ; // derivatives should not depend on parameters since
234  // function is linear
235  }
236 }
237 
238 void WrappedMultiTF1::SetDerivPrecision(double eps) { fgEps = eps; }
239 
241 
243  const TF1 * funcToCopy = (f) ? f : fFunc;
244  TF1 * fnew = (TF1*) funcToCopy->IsA()->New();
245  funcToCopy->Copy(*fnew);
246  fFunc = fnew;
247  fOwnFunc = true;
248 }
249 
250 
251 } // end namespace Fit
252 
253 } // end namespace ROOT
254 
255 
void ParameterGradient(double x, const double *par, double *grad) const
evaluate the derivative of the function with respect to the parameters
Definition: WrappedTF1.cxx:82
double par[1]
Definition: unuranDistr.cxx:38
virtual void SetParameters(const Double_t *params)
Definition: TF1.h:439
Interface (abstract class) for generic functions objects of one-dimension Provides a method to evalua...
Definition: IFunction.h:133
Namespace for new ROOT classes and functions.
Definition: ROOT.py:1
static double GetDerivPrecision()
get precision value used for calculating the derivative step-size
Definition: WrappedTF1.cxx:131
double DoParameterDerivative(const double *x, const double *p, unsigned int ipar) const
evaluate the partial derivative with respect to the parameter
Definition: WrappedTF1.cxx:216
WrappedMultiTF1 & operator=(const WrappedMultiTF1 &rhs)
Assignment operator.
Definition: WrappedTF1.cxx:185
Class to Wrap a ROOT Function class (like TF1) in a IParamMultiFunction interface of multi-dimensions...
WrappedMultiTF1(TF1 &f, unsigned int dim=0)
constructor from a function pointer to a TF1 If dim = 0 dimension is taken from TF1::GetNdim().
Definition: WrappedTF1.cxx:138
#define assert(cond)
Definition: unittest.h:542
virtual const TObject * GetLinearPart(Int_t i) const
Definition: TF1.h:342
Class to Wrap a ROOT Function class (like TF1) in a IParamFunction interface of one dimensions to be ...
Definition: WrappedTF1.h:41
static void SetDerivPrecision(double eps)
precision value used for calculating the derivative step-size h = eps * |x|.
Definition: WrappedTF1.cxx:129
ClassImp(TIterator) Bool_t TIterator return false
Compare two iterator objects.
Definition: TIterator.cxx:20
TMethodCall * GetMethodCall() const
Definition: TF1.h:353
Specialized Gradient interface(abstract class) for one dimensional functions It provides a method to ...
Definition: IFunction.h:247
Double_t x[n]
Definition: legend1.C:17
void SetAndCopyFunction(const TF1 *f=0)
method to set a new function pointer and copy it inside.
Definition: WrappedTF1.cxx:242
double DoDerivative(double x) const
return the function derivatives w.r.t. x
Definition: WrappedTF1.cxx:97
static double GetDerivPrecision()
get precision value used for calculating the derivative step-size
Definition: WrappedTF1.cxx:240
virtual void Copy(TObject &f1) const
Copy this F1 to a new F1.
Definition: TF1.cxx:759
double pow(double, double)
virtual Bool_t IsLinear() const
Definition: TF1.h:412
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:2140
void ParameterGradient(const double *x, const double *par, double *grad) const
evaluate the derivative of the function with respect to the parameters
Definition: WrappedTF1.cxx:197
The F O R M U L A class.
Definition: TFormula.h:89
virtual Int_t GetNdim() const
Definition: TF1.h:350
unsigned int NPar() const
return number of parameters
Definition: WrappedTF1.h:96
static void SetDerivPrecision(double eps)
precision value used for calculating the derivative step-size h = eps * |x|.
Definition: WrappedTF1.cxx:238
Interface (abstract class) for parametric one-dimensional gradient functions providing in addition to...
virtual Double_t Derivative(Double_t x, Double_t *params=0, Double_t epsilon=0.001) const
Returns the first derivative of the function at point x, computed by Richardson's extrapolation metho...
Definition: TF1.cxx:852
double f(double x)
WrappedTF1(TF1 &f)
constructor from a TF1 function pointer.
Definition: WrappedTF1.cxx:29
Interface (abstract class) for parametric gradient multi-dimensional functions providing in addition ...
WrappedTF1 & operator=(const WrappedTF1 &rhs)
Assignment operator.
Definition: WrappedTF1.cxx:71
virtual Int_t GetNumber() const
Definition: TF1.h:354
Namespace for new Math classes and functions.
virtual void InitArgs(const Double_t *x, const Double_t *params)
Initialize parameters addresses.
Definition: TF1.cxx:2221
1-Dim function class
Definition: TF1.h:149
unsigned int NPar() const
return number of parameters
double DoParameterDerivative(double x, const double *p, unsigned int ipar) const
evaluate the derivative of the function with respect to the parameters
Definition: WrappedTF1.cxx:105
Documentation for the abstract class IBaseFunctionMultiDim.
Definition: IFunction.h:63
static double fgEps
cached vector for x value (needed for TF1::EvalPar signature)
Definition: WrappedTF1.h:157