Logo ROOT   6.30.04
Reference Guide
 All Namespaces Files Pages
TVirtualFitter.cxx
Go to the documentation of this file.
1 // @(#)root/hist:$Id$
2 // Author: Rene Brun 31/08/99
3 
4 /*************************************************************************
5  * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers. *
6  * All rights reserved. *
7  * *
8  * For the licensing terms see $ROOTSYS/LICENSE. *
9  * For the list of contributors see $ROOTSYS/README/CREDITS. *
10  *************************************************************************/
11 
12 
13 /** \class TVirtualFitter
14  \ingroup Hist
15  Abstract Base Class for Fitting
16 */
17 
18 #include "TROOT.h"
19 #include "TVirtualFitter.h"
20 #include "TPluginManager.h"
21 #include "TEnv.h"
22 #include "Math/MinimizerOptions.h"
23 #include "ThreadLocalStorage.h"
24 
25 
26 // Implement a thread local static member as a replacement
27 // for TVirtualFitter::fgFitter
28 namespace {
29  struct FitterGlobals {
30  FitterGlobals() : fFitter(nullptr),fMaxPar(0) {}
31 
32  TVirtualFitter *fFitter;
33  Int_t fMaxPar;
34  TString fDefault;
35  };
36  static FitterGlobals &GetGlobals() {
37  TTHREAD_TLS_DECL(FitterGlobals,globals);
38  return globals;
39  }
40  static TVirtualFitter *&GetGlobalFitter() {
41  return GetGlobals().fFitter;
42  }
43  static Int_t &GetGlobalMaxPar() {
44  return GetGlobals().fMaxPar;
45  }
46  static TString &GetGlobalDefault() {
47  return GetGlobals().fDefault;
48  }
49 }
50 //Int_t TVirtualFitter::fgMaxpar = 0;
51 // Int_t TVirtualFitter::fgMaxiter = 5000;
52 // Double_t TVirtualFitter::fgPrecision = 1e-6;
53 // Double_t TVirtualFitter::fgErrorDef = 1;
54 //TString TVirtualFitter::fgDefault = "";
55 
56 ClassImp(TVirtualFitter);
57 
58 #ifdef R__COMPLETE_MEM_TERMINATION
59 namespace {
60  struct TVirtualFitterCleanup {
61  ~TVirtualFitterCleanup() {
62  delete TVirtualFitter::GetFitter();
63  }
64  };
65  TVirtualFitterCleanup cleanup;
66 }
67 #endif
68 
69 ////////////////////////////////////////////////////////////////////////////////
70 /// Default constructor.
71 
72 TVirtualFitter::TVirtualFitter() :
73  fXfirst(0),
74  fXlast(0),
75  fYfirst(0),
76  fYlast(0),
77  fZfirst(0),
78  fZlast(0),
79  fNpoints(0),
80  fPointSize(0),
81  fCacheSize(0),
82  fCache(0),
83  fObjectFit(0),
84  fUserFunc(0),
85  fMethodCall(0),
86  fFCN(0)
87 {
88 }
89 
90 ////////////////////////////////////////////////////////////////////////////////
91 ///copy constructor
92 
93 TVirtualFitter::TVirtualFitter(const TVirtualFitter& tvf) :
94  TNamed(tvf),
95  fOption(tvf.fOption),
96  fXfirst(tvf.fXfirst),
97  fXlast(tvf.fXlast),
98  fYfirst(tvf.fYfirst),
99  fYlast(tvf.fYlast),
100  fZfirst(tvf.fZfirst),
101  fZlast(tvf.fZlast),
102  fNpoints(tvf.fNpoints),
103  fPointSize(tvf.fPointSize),
104  fCacheSize(tvf.fCacheSize),
105  fCache(tvf.fCache),
106  fObjectFit(tvf.fObjectFit),
107  fUserFunc(tvf.fUserFunc),
108  fMethodCall(tvf.fMethodCall),
109  fFCN(tvf.fFCN)
110 {
111 }
112 
113 ////////////////////////////////////////////////////////////////////////////////
114 ///assignment operator
115 
116 TVirtualFitter& TVirtualFitter::operator=(const TVirtualFitter& tvf)
117 {
118  if(this!=&tvf) {
119  TNamed::operator=(tvf);
120  fOption=tvf.fOption;
121  fXfirst=tvf.fXfirst;
122  fXlast=tvf.fXlast;
123  fYfirst=tvf.fYfirst;
124  fYlast=tvf.fYlast;
125  fZfirst=tvf.fZfirst;
126  fZlast=tvf.fZlast;
127  fNpoints=tvf.fNpoints;
128  fPointSize=tvf.fPointSize;
129  fCacheSize=tvf.fCacheSize;
130  fCache=tvf.fCache;
131  fObjectFit=tvf.fObjectFit;
132  fUserFunc=tvf.fUserFunc;
133  fMethodCall=tvf.fMethodCall;
134  fFCN=tvf.fFCN;
135  }
136  return *this;
137 }
138 
139 ////////////////////////////////////////////////////////////////////////////////
140 /// Cleanup virtual fitter.
141 
142 TVirtualFitter::~TVirtualFitter()
143 {
144  delete fMethodCall;
145  delete [] fCache;
146  if ( GetGlobalFitter() == this ) {
147  GetGlobalFitter() = 0;
148  GetGlobalMaxPar() = 0;
149  }
150  fMethodCall = 0;
151  fFCN = 0;
152 }
153 
154 ////////////////////////////////////////////////////////////////////////////////
155 /// Static function returning a pointer to the current fitter.
156 /// If the fitter does not exist, the default TFitter is created.
157 /// Don't delete the returned fitter object, it will be re-used.
158 
159 TVirtualFitter *TVirtualFitter::Fitter(TObject *obj, Int_t maxpar)
160 {
161  if (GetGlobalFitter() && maxpar > GetGlobalMaxPar()) {
162  delete GetGlobalFitter();
163  GetGlobalFitter() = 0;
164  }
165 
166  if (!GetGlobalFitter()) {
167  TPluginHandler *h;
168  if (GetGlobalDefault().Length() == 0) GetGlobalDefault() = gEnv->GetValue("Root.Fitter","Minuit");
169  if ((h = gROOT->GetPluginManager()->FindHandler("TVirtualFitter",GetGlobalDefault()))) {
170  if (h->LoadPlugin() == -1)
171  return 0;
172  GetGlobalFitter() = (TVirtualFitter*) h->ExecPlugin(1, maxpar);
173  GetGlobalMaxPar() = maxpar;
174  }
175  }
176 
177  if (GetGlobalFitter()) GetGlobalFitter()->SetObjectFit(obj);
178  return GetGlobalFitter();
179 }
180 
181 ////////////////////////////////////////////////////////////////////////////////
182 ///return confidence intervals in array x of dimension ndim
183 ///implemented in TFitter and TLinearFitter
184 
185 void TVirtualFitter::GetConfidenceIntervals(Int_t /*n*/, Int_t /*ndim*/, const Double_t * /*x*/, Double_t * /*ci*/, Double_t /*cl*/)
186 {
187 }
188 
189 ////////////////////////////////////////////////////////////////////////////////
190 ///return confidence intervals in TObject obj
191 ///implemented in TFitter and TLinearFitter
192 
193 void TVirtualFitter::GetConfidenceIntervals(TObject * /*obj*/, Double_t /*cl*/)
194 {
195 }
196 
197 ////////////////////////////////////////////////////////////////////////////////
198 /// static: return the name of the default fitter
199 
200 const char *TVirtualFitter::GetDefaultFitter()
201 {
202  //return GetGlobalDefault().Data();
203  return ROOT::Math::MinimizerOptions::DefaultMinimizerType().c_str();
204 }
205 
206 ////////////////////////////////////////////////////////////////////////////////
207 /// static: return the current Fitter
208 
209 TVirtualFitter *TVirtualFitter::GetFitter()
210 {
211  return GetGlobalFitter();
212 }
213 
214 ////////////////////////////////////////////////////////////////////////////////
215 /// static: Return the maximum number of iterations
216 /// actually max number of function calls
217 
218 Int_t TVirtualFitter::GetMaxIterations()
219 {
220  //return fgMaxiter;
221  return ROOT::Math::MinimizerOptions::DefaultMaxFunctionCalls();
222 }
223 
224 ////////////////////////////////////////////////////////////////////////////////
225 /// static: Return the Error Definition
226 
227 Double_t TVirtualFitter::GetErrorDef()
228 {
229 // return fgErrorDef;
230  return ROOT::Math::MinimizerOptions::DefaultErrorDef();
231 }
232 
233 ////////////////////////////////////////////////////////////////////////////////
234 /// static: Return the fit relative precision
235 
236 Double_t TVirtualFitter::GetPrecision()
237 {
238  //return fgPrecision;
239  return ROOT::Math::MinimizerOptions::DefaultTolerance();
240 }
241 
242 ////////////////////////////////////////////////////////////////////////////////
243 /// static: set name of default fitter
244 
245 void TVirtualFitter::SetDefaultFitter(const char *name)
246 {
247  ROOT::Math::MinimizerOptions::SetDefaultMinimizer(name,"");
248  if (GetGlobalDefault() == name) return;
249  delete GetGlobalFitter();
250  GetGlobalFitter() = 0;
251  GetGlobalDefault() = name;
252 }
253 
254 ////////////////////////////////////////////////////////////////////////////////
255 /// Static function to set an alternative fitter
256 
257 void TVirtualFitter::SetFitter(TVirtualFitter *fitter, Int_t maxpar)
258 {
259  GetGlobalFitter() = fitter;
260  GetGlobalMaxPar() = maxpar;
261 }
262 
263 ////////////////////////////////////////////////////////////////////////////////
264 /// To set the address of the minimization objective function
265 /// called by the native compiler (see function below when called by CINT)
266 
267 void TVirtualFitter::SetFCN(void (*fcn)(Int_t &, Double_t *, Double_t &f, Double_t *, Int_t))
268 {
269  fFCN = fcn;
270 }
271 
272 ////////////////////////////////////////////////////////////////////////////////
273 /// Initialize the cache array
274 /// npoints is the number of points to be stored (or already stored) in the cache
275 /// psize is the number of elements per point
276 ///
277 /// if (npoints*psize > fCacheSize) the existing cache is deleted
278 /// and a new array is created.
279 /// The function returns a pointer to the cache
280 
281 Double_t *TVirtualFitter::SetCache(Int_t npoints, Int_t psize)
282 {
283  if (npoints*psize > fCacheSize) {
284  delete [] fCache;
285  fCacheSize = npoints*psize;
286  fCache = new Double_t[fCacheSize];
287  }
288  fNpoints = npoints;
289  fPointSize = psize;
290  return fCache;
291 }
292 
293 ////////////////////////////////////////////////////////////////////////////////
294 /// static: Set the maximum number of function calls for the minimization algorithm
295 /// For example for MIGRAD this is the maxcalls value passed as first argument
296 /// (see https://cern-tex.web.cern.ch/cern-tex/minuit/node18.html )
297 
298 void TVirtualFitter::SetMaxIterations(Int_t niter)
299 {
300  ROOT::Math::MinimizerOptions::SetDefaultMaxFunctionCalls(niter);
301 }
302 
303 ////////////////////////////////////////////////////////////////////////////////
304 /// static: Set the Error Definition (default=1)
305 /// For Minuit this is the value passed with the "SET ERR" command
306 /// (see https://cern-tex.web.cern.ch/cern-tex/minuit/node18.html)
307 
308 void TVirtualFitter::SetErrorDef(Double_t errdef)
309 {
310 // fgErrorDef = errdef;
311  ROOT::Math::MinimizerOptions::SetDefaultErrorDef(errdef);
312  if (!GetGlobalFitter()) return;
313  Double_t arglist[1];
314  arglist[0] = errdef;
315  GetGlobalFitter()->ExecuteCommand("SET ERRORDEF", arglist, 1);
316 }
317 
318 ////////////////////////////////////////////////////////////////////////////////
319 /// static: Set the tolerance used in the minimization algorithm
320 /// For example for MIGRAD this is tolerance value passed as second argument
321 /// (see https://cern-tex.web.cern.ch/cern-tex/minuit/node18.html )
322 
323 void TVirtualFitter::SetPrecision(Double_t prec)
324 {
325  //fgPrecision = prec;
326  ROOT::Math::MinimizerOptions::SetDefaultTolerance(prec);
327 }