ROOT  6.06/08
Reference Guide
TLinearMinimizer.cxx
Go to the documentation of this file.
1 // @(#)root/minuit:$Id$
2 // Author: L. Moneta Wed Oct 25 16:28:55 2006
3 
4 /**********************************************************************
5  * *
6  * Copyright (c) 2006 LCG ROOT Math Team, CERN/PH-SFT *
7  * *
8  * *
9  **********************************************************************/
10 
11 // Implementation file for class TLinearMinimizer
12 
13 #include "TLinearMinimizer.h"
14 #include "Math/IParamFunction.h"
15 #include "TF1.h"
16 #include "TUUID.h"
17 #include "TROOT.h"
18 #include "Fit/Chi2FCN.h"
19 
20 #include "TLinearFitter.h"
21 #include "TVirtualMutex.h"
22 
23 #include <iostream>
24 #include <cassert>
25 #include <algorithm>
26 #include <functional>
27 
28 
29 
30 // namespace ROOT {
31 
32 // namespace Fit {
33 
34 
35 // structure used for creating the TF1 representing the basis functions
36 // they are the derivatives w.r.t the parameters of the model function
37 template<class Func>
38 struct BasisFunction {
39  BasisFunction(const Func & f, int k) :
40  fKPar(k),
41  fFunc(&f)
42  {}
43 
44  double operator() ( double * x, double *) {
45  return fFunc->ParameterDerivative(x,fKPar);
46  }
47 
48  unsigned int fKPar; // param component
49  const Func * fFunc;
50 };
51 
52 
53 //______________________________________________________________________________
54 //
55 // TLinearMinimizer, simple class implementing the ROOT::Math::Minimizer interface using
56 // TLinearFitter.
57 // This class uses TLinearFitter to find directly (by solving a system of linear equations)
58 // the minimum of a
59 // least-square function which has a linear dependence in the fit parameters.
60 // This class is not used directly, but via the ROOT::Fitter class, when calling the
61 // LinearFit method. It is instantiates using the plug-in manager (plug-in name is "Linear")
62 //
63 //__________________________________________________________________________________________
64 
65 
67 
68 
70  fRobust(false),
71  fDim(0),
72  fNFree(0),
73  fMinVal(0),
74  fObjFunc(0),
75  fFitter(0)
76 {
77  // Default constructor implementation.
78  // type is not used - needed for consistency with other minimizer plug-ins
79 }
80 
82  fRobust(false),
83  fDim(0),
84  fNFree(0),
85  fMinVal(0),
86  fObjFunc(0),
87  fFitter(0)
88 {
89  // constructor passing a type of algorithm, (supported now robust via LTS regression)
90 
91  // select type from the string
92  std::string algoname(type);
93  std::transform(algoname.begin(), algoname.end(), algoname.begin(), (int(*)(int)) tolower );
94 
95  if (algoname.find("robust") != std::string::npos) fRobust = true;
96 
97 }
98 
100 {
101  // Destructor implementation.
102  if (fFitter) delete fFitter;
103 }
104 
106  Minimizer()
107 {
108  // Implementation of copy constructor.
109 }
110 
112 {
113  // Implementation of assignment operator.
114  if (this == &rhs) return *this; // time saving self-test
115  return *this;
116 }
117 
118 
120  // Set function to be minimized. Flag an error since only support Gradient objective functions
121 
122  Error("TLinearMinimizer::SetFunction(IMultiGenFunction)","Wrong type of function used for Linear fitter");
123 }
124 
125 
127  // Set the function to be minimized. The function must be a Chi2 gradient function
128  // When performing a linear fit we need the basis functions, which are the partial derivatives with respect to the parameters of the model function.
129 
131  const Chi2Func * chi2func = dynamic_cast<const Chi2Func *>(&objfunc);
132  if (chi2func ==0) {
133  Error("TLinearMinimizer::SetFunction(IMultiGradFunction)","Wrong type of function used for Linear fitter");
134  return;
135  }
136  fObjFunc = chi2func;
137 
138  // need to get the gradient parametric model function
139  typedef ROOT::Math::IParamMultiGradFunction ModelFunc;
140  const ModelFunc * modfunc = dynamic_cast<const ModelFunc*>( &(chi2func->ModelFunction()) );
141  assert(modfunc != 0);
142 
143  fDim = chi2func->NDim(); // number of parameters
144  fNFree = fDim;
145  // get the basis functions (derivatives of the modelfunc)
146  TObjArray flist(fDim);
147  flist.SetOwner(kFALSE); // we do not want to own the list - it will be owned by the TLinearFitter class
148  for (unsigned int i = 0; i < fDim; ++i) {
149  // t.b.f: should not create TF1 classes
150  // when creating TF1 (if onother function with same name exists it is
151  // deleted since it is added in function list in gROOT
152  // fix the problem using meaniful names (difficult to re-produce)
153  BasisFunction<ModelFunc > bf(*modfunc,i);
154  TUUID u;
155  std::string fname = "_LinearMinimimizer_BasisFunction_" +
156  std::string(u.AsString() );
157  TF1 * f = new TF1(fname.c_str(),ROOT::Math::ParamFunctor(bf),0,1,0,1,TF1::EAddToList::kNo);
158  flist.Add(f);
159  }
160 
161  // create TLinearFitter (do it now because olny now now the coordinate dimensions)
162  if (fFitter) delete fFitter; // reset by deleting previous copy
163  fFitter = new TLinearFitter( static_cast<const ModelFunc::BaseFunc&>(*modfunc).NDim() );
164 
165  fFitter->StoreData(fRobust); // need a copy of data in case of robust fitting
166 
167  fFitter->SetBasisFunctions(&flist);
168 
169  // get the fitter data
170  const ROOT::Fit::BinData & data = chi2func->Data();
171  // add the data but not store them
172  for (unsigned int i = 0; i < data.Size(); ++i) {
173  double y = 0;
174  const double * x = data.GetPoint(i,y);
175  double ey = 1;
176  if (! data.Opt().fErrors1) {
177  ey = data.Error(i);
178  }
179  // interface should take a double *
180  fFitter->AddPoint( const_cast<double *>(x) , y, ey);
181  }
182 
183 }
184 
185 bool TLinearMinimizer::SetFixedVariable(unsigned int ivar, const std::string & /* name */ , double val) {
186  // set a fixed variable.
187  if (!fFitter) return false;
188  fFitter->FixParameter(ivar, val);
189  return true;
190 }
191 
193  // find directly the minimum of the chi2 function
194  // solving the linear equation. Use TVirtualFitter::Eval.
195 
196  if (fFitter == 0 || fObjFunc == 0) return false;
197 
198  int iret = 0;
199  if (!fRobust)
200  iret = fFitter->Eval();
201  else {
202  // robust fitting - get h parameter using tolerance (t.b. improved)
203  double h = Tolerance();
204  if (PrintLevel() > 0)
205  std::cout << "TLinearMinimizer: Robust fitting with h = " << h << std::endl;
206  iret = fFitter->EvalRobust(h);
207  }
208  fStatus = iret;
209 
210  if (iret != 0) {
211  Warning("Minimize","TLinearFitter failed in finding the solution");
212  return false;
213  }
214 
215 
216  // get parameter values
217  fParams.resize( fDim);
218  // no error available for robust fitting
219  if (!fRobust) fErrors.resize( fDim);
220  for (unsigned int i = 0; i < fDim; ++i) {
221  fParams[i] = fFitter->GetParameter( i);
222  if (!fRobust) fErrors[i] = fFitter->GetParError( i );
223  }
224  fCovar.resize(fDim*fDim);
225  double * cov = fFitter->GetCovarianceMatrix();
226 
227  if (!fRobust && cov) std::copy(cov,cov+fDim*fDim,fCovar.begin() );
228 
229  // calculate chi2 value
230 
231  fMinVal = (*fObjFunc)(&fParams.front());
232 
233  return true;
234 
235 }
236 
237 
238 // } // end namespace Fit
239 
240 // } // end namespace ROOT
241 
unsigned int Size() const
return number of fit points
Definition: BinData.h:447
virtual void StoreData(Bool_t store)
Interface (abstract class) for multi-dimensional functions providing a gradient calculation.
Definition: IFunction.h:322
std::vector< double > fErrors
An array of TObjects.
Definition: TObjArray.h:39
virtual void FixParameter(Int_t ipar)
Fixes paramter #ipar at its current value.
The Linear Fitter - For fitting functions that are LINEAR IN PARAMETERS.
std::vector< double > fParams
#define assert(cond)
Definition: unittest.h:542
virtual void SetOwner(Bool_t enable=kTRUE)
Set whether this collection is the owner (enable==true) of its content.
TH1 * h
Definition: legend2.C:5
const Bool_t kFALSE
Definition: Rtypes.h:92
TLinearFitter * fFitter
virtual Double_t * GetCovarianceMatrix() const
Returns covariance matrix.
Minimizer()
Default constructor.
Definition: Minimizer.h:93
unsigned int fNFree
int PrintLevel() const
minimizer configuration parameters
Definition: Minimizer.h:419
TLinearMinimizer class: minimizer implementation based on TMinuit.
TRObject operator()(const T1 &t1) const
const double * GetPoint(unsigned int ipoint, double &value) const
retrieve at the same time a pointer to the coordinate data and the fit value More efficient than call...
Definition: BinData.h:304
This class defines a UUID (Universally Unique IDentifier), also known as GUIDs (Globally Unique IDent...
Definition: TUUID.h:44
Double_t x[n]
Definition: legend1.C:17
TLinearMinimizer & operator=(const TLinearMinimizer &rhs)
Assignment operator.
std::vector< double > fCovar
virtual void SetFunction(const ROOT::Math::IMultiGenFunction &func)
set the fit model function
double Error(unsigned int ipoint) const
return error on the value for the given fit point Safe (but slower) method returning correctly the er...
Definition: BinData.h:249
void Error(const char *location, const char *msgfmt,...)
double Tolerance() const
absolute tolerance
Definition: Minimizer.h:428
Chi2FCN class for binnned fits using the least square methods.
Definition: Chi2FCN.h:66
virtual Double_t GetParameter(Int_t ipar) const
IParamFunction interface (abstract class) describing multi-dimensional parameteric functions It is a ...
const ROOT::Math::IMultiGradFunction * fObjFunc
virtual Int_t EvalRobust(Double_t h=-1)
Finds the parameters of the fitted function in case data contains outliers.
const DataOptions & Opt() const
access to options
Definition: DataVector.h:97
Class describing the binned data sets : vectors of x coordinates, y values and optionally error on y ...
Definition: BinData.h:61
void Warning(const char *location, const char *msgfmt,...)
virtual void SetBasisFunctions(TObjArray *functions)
set the basis functions in case the fitting function is not set directly The TLinearFitter will manag...
virtual Int_t Eval()
Perform the fit and evaluate the parameters Returns 0 if the fit is ok, 1 if there are errors...
TLinearMinimizer(int type=0)
Default constructor.
#define ClassImp(name)
Definition: Rtypes.h:279
double f(double x)
virtual Double_t GetParError(Int_t ipar) const
Returns the error of parameter #ipar.
Interface (abstract class) for parametric gradient multi-dimensional functions providing in addition ...
int type
Definition: TGX11.cxx:120
Double_t y[n]
Definition: legend1.C:17
Double_t ey[n]
Definition: legend1.C:17
virtual bool Minimize()
method to perform the minimization
const char * AsString() const
Return UUID as string. Copy string immediately since it will be reused.
Definition: TUUID.cxx:531
bool fRobust
return reference to the objective function virtual const ROOT::Math::IGenFunction & Function() const;...
1-Dim function class
Definition: TF1.h:149
Param Functor class for Multidimensional functions.
Definition: ParamFunctor.h:209
void Add(TObject *obj)
Definition: TObjArray.h:75
virtual ~TLinearMinimizer()
Destructor (no operations)
Documentation for the abstract class IBaseFunctionMultiDim.
Definition: IFunction.h:63
virtual bool SetFixedVariable(unsigned int, const std::string &, double)
set fixed variable (override if minimizer supports them )
virtual void AddPoint(Double_t *x, Double_t y, Double_t e=1)
Adds 1 point to the fitter.