ROOT  6.06/09
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 
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
double Tolerance() const
absolute tolerance
Definition: Minimizer.h:428
TLinearFitter * fFitter
ClassImp(TIterator) Bool_t TIterator return false
Compare two iterator objects.
Definition: TIterator.cxx:20
unsigned int fNFree
TLinearMinimizer class: minimizer implementation based on TMinuit.
This class defines a UUID (Universally Unique IDentifier), also known as GUIDs (Globally Unique IDent...
Definition: TUUID.h:44
unsigned int Size() const
return number of fit points
Definition: BinData.h:447
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
void Error(const char *location, const char *msgfmt,...)
Chi2FCN class for binnned fits using the least square methods.
Definition: Chi2FCN.h:66
IParamFunction interface (abstract class) describing multi-dimensional parameteric functions It is a ...
RooCmdArg Minimizer(const char *type, const char *alg=0)
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 char * AsString() const
Return UUID as string. Copy string immediately since it will be reused.
Definition: TUUID.cxx:531
int PrintLevel() const
minimizer configuration parameters
Definition: Minimizer.h:419
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 Double_t GetParameter(Int_t ipar) const
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.
TRObject operator()(const T1 &t1) const
double f(double x)
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
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
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
const DataOptions & Opt() const
access to options
Definition: DataVector.h:97
virtual Double_t GetParError(Int_t ipar) const
Returns the error of parameter #ipar.
void Add(TObject *obj)
Definition: TObjArray.h:75
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
virtual ~TLinearMinimizer()
Destructor (no operations)
Documentation for the abstract class IBaseFunctionMultiDim.
Definition: IFunction.h:63
ClassImp(TLinearMinimizer) TLinearMinimizer
virtual bool SetFixedVariable(unsigned int, const std::string &, double)
set fixed variable (override if minimizer supports them )
virtual Double_t * GetCovarianceMatrix() const
Returns covariance matrix.
virtual void AddPoint(Double_t *x, Double_t y, Double_t e=1)
Adds 1 point to the fitter.