Logo ROOT   6.08/07
Reference Guide
TF1.cxx
Go to the documentation of this file.
1 // @(#)root/hist:$Id$
2 // Author: Rene Brun 18/08/95
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 #include "Riostream.h"
13 #include "TROOT.h"
14 #include "TMath.h"
15 #include "TF1.h"
16 #include "TH1.h"
17 #include "TGraph.h"
18 #include "TVirtualPad.h"
19 #include "TStyle.h"
20 #include "TRandom.h"
21 #include "TInterpreter.h"
22 #include "TPluginManager.h"
23 #include "TBrowser.h"
24 #include "TColor.h"
25 #include "TClass.h"
26 #include "TMethodCall.h"
27 #include "TF1Helper.h"
28 #include "TVirtualMutex.h"
29 #include "Math/WrappedFunction.h"
30 #include "Math/WrappedTF1.h"
31 #include "Math/BrentRootFinder.h"
32 #include "Math/BrentMinimizer1D.h"
33 #include "Math/BrentMethods.h"
34 #include "Math/Integrator.h"
36 #include "Math/IntegratorOptions.h"
37 #include "Math/GaussIntegrator.h"
41 #include "Math/Functor.h"
42 #include "Math/Minimizer.h"
43 #include "Math/MinimizerOptions.h"
44 #include "Math/Factory.h"
45 #include "Math/ChebyshevPol.h"
46 #include "Fit/FitResult.h"
47 // for I/O backward compatibility
48 #include "v5/TF1Data.h"
49 
50 #include "AnalyticalIntegrals.h"
51 
52 //#include <iostream>
53 
54 std::atomic<Bool_t> TF1::fgAbsValue(kFALSE);
56 std::atomic<Bool_t> TF1::fgAddToGlobList(kTRUE);
57 static Double_t gErrorTF1 = 0;
58 
60 
61 // class wrapping evaluation of TF1(x) - y0
62 class GFunc {
63  const TF1* fFunction;
64  const double fY0;
65 public:
66  GFunc(const TF1* function , double y ):fFunction(function), fY0(y) {}
67  double operator()(double x) const {
68  return fFunction->Eval(x) - fY0;
69  }
70 };
71 
72 // class wrapping evaluation of -TF1(x)
73 class GInverseFunc {
74  const TF1* fFunction;
75 public:
76  GInverseFunc(const TF1* function):fFunction(function) {}
77 
78  double operator()(double x) const {
79  return - fFunction->Eval(x);
80  }
81 };
82 // class wrapping evaluation of -TF1(x) for multi-dimension
83 class GInverseFuncNdim {
84  TF1* fFunction;
85 public:
86  GInverseFuncNdim(TF1* function):fFunction(function) {}
87 
88  double operator()(const double* x) const {
89  return - fFunction->EvalPar(x, (Double_t*)0);
90  }
91 };
92 
93 // class wrapping function evaluation directly in 1D interface (used for integration)
94 // and implementing the methods for the momentum calculations
95 
96 class TF1_EvalWrapper : public ROOT::Math::IGenFunction {
97 public:
98  TF1_EvalWrapper(TF1 * f, const Double_t * par, bool useAbsVal, Double_t n = 1, Double_t x0 = 0) :
99  fFunc(f),
100  fPar( ( (par) ? par : f->GetParameters() ) ),
101  fAbsVal(useAbsVal),
102  fN(n),
103  fX0(x0)
104  {
105  fFunc->InitArgs(fX, fPar);
106  if (par) fFunc->SetParameters(par);
107  }
108 
109  ROOT::Math::IGenFunction * Clone() const {
110  // use default copy constructor
111  TF1_EvalWrapper * f = new TF1_EvalWrapper( *this);
112  f->fFunc->InitArgs(f->fX, f->fPar);
113  return f;
114  }
115  // evaluate |f(x)|
116  Double_t DoEval( Double_t x) const {
117  // use evaluation with stored parameters (i.e. pass zero)
118  fX[0] = x;
119  Double_t fval = fFunc->EvalPar( fX, 0);
120  if (fAbsVal && fval < 0) return -fval;
121  return fval;
122  }
123  // evaluate x * |f(x)|
124  Double_t EvalFirstMom( Double_t x) {
125  fX[0] = x;
126  return fX[0] * TMath::Abs( fFunc->EvalPar( fX, 0) );
127  }
128  // evaluate (x - x0) ^n * f(x)
129  Double_t EvalNMom( Double_t x) const {
130  fX[0] = x;
131  return TMath::Power( fX[0] - fX0, fN) * TMath::Abs( fFunc->EvalPar( fX, 0) );
132  }
133 
134  TF1 * fFunc;
135  mutable Double_t fX[1];
136  const double * fPar;
137  Bool_t fAbsVal;
138  Double_t fN;
139  Double_t fX0;
140 };
141 
142 ////////////////////////////////////////////////////////////////////////////////
143 /** \class TF1
144  \ingroup Hist
145  \brief 1-Dim function class
146 
147 
148 ## TF1: 1-Dim function class
149 
150 A TF1 object is a 1-Dim function defined between a lower and upper limit.
151 The function may be a simple function based on a TFormula expression or a precompiled user function.
152 The function may have associated parameters.
153 TF1 graphics function is via the TH1 and TGraph drawing functions.
154 
155 The following types of functions can be created:
156 
157 1. [Expression using variable x and no parameters]([#F1)
158 2. [Expression using variable x with parameters](#F2)
159 3. [Lambda Expression with variable x and parameters](#F3)
160 4. [A general C function with parameters](#F4)
161 5. [A general C++ function object (functor) with parameters](#F5)
162 6. [A member function with parameters of a general C++ class](#F6)
163 
164 
165 
166 ### <a name="F1"></a> 1 - Expression using variable x and no parameters
167 
168 #### Case 1: inline expression using standard C++ functions/operators
169 
170 Begin_Macro(source)
171 {
172  TF1 *fa1 = new TF1("fa1","sin(x)/x",0,10);
173  fa1->Draw();
174 }
175 End_Macro
176 
177 #### Case 2: inline expression using a ROOT function (e.g. from TMath) without parameters
178 
179 
180 Begin_Macro(source)
181 {
182  TF1 *fa2 = new TF1("fa2","TMath::DiLog(x)",0,10);
183  fa2->Draw();
184 }
185 End_Macro
186 
187 #### Case 3: inline expression using a user defined CLING function by name
188 
189 ~~~~{.cpp}
190 Double_t myFunc(double x) { return x+sin(x); }
191 ....
192 TF1 *fa3 = new TF1("fa3","myFunc(x)",-3,5);
193 fa3->Draw();
194 ~~~~
195 
196 ### <a name="F2"></a> 2 - Expression using variable x with parameters
197 
198 #### Case 1: inline expression using standard C++ functions/operators
199 
200 * Example a:
201 
202 
203 ~~~~{.cpp}
204 TF1 *fa = new TF1("fa","[0]*x*sin([1]*x)",-3,3);
205 ~~~~
206 
207 This creates a function of variable x with 2 parameters. The parameters must be initialized via:
208 
209 ~~~~{.cpp}
210  fa->SetParameter(0,value_first_parameter);
211  fa->SetParameter(1,value_second_parameter);
212 ~~~~
213 
214 
215 Parameters may be given a name:
216 
217 ~~~~{.cpp}
218  fa->SetParName(0,"Constant");
219 ~~~~
220 
221 * Example b:
222 
223 ~~~~{.cpp}
224  TF1 *fb = new TF1("fb","gaus(0)*expo(3)",0,10);
225 ~~~~
226 
227 
228 ``gaus(0)`` is a substitute for ``[0]*exp(-0.5*((x-[1])/[2])**2)`` and ``(0)`` means start numbering parameters at ``0``. ``expo(3)`` is a substitute for ``exp([3]+[4]*x)``.
229 
230 #### Case 2: inline expression using TMath functions with parameters
231 
232 ~~~~{.cpp}
233  TF1 *fb2 = new TF1("fa3","TMath::Landau(x,[0],[1],0)",-5,10);
234  fb2->SetParameters(0.2,1.3);
235  fb2->Draw();
236 ~~~~
237 
238 
239 
240 Begin_Macro
241 {
242  TCanvas *c = new TCanvas("c","c",0,0,500,300);
243  TF1 *fb2 = new TF1("fa3","TMath::Landau(x,[0],[1],0)",-5,10);
244  fb2->SetParameters(0.2,1.3); fb2->Draw();
245  return c;
246 }
247 End_Macro
248 
249 ###<a name="F3"></a> 3 - A lambda expression with variables and parameters
250 
251 \since **6.00/00:**
252 TF1 supports using lambda expressions in the formula. This allows, by using a full C++ syntax the full power of lambda
253 functions and still maintain the capability of storing the function in a file which cannot be done with
254 function pointer or lambda written not as expression, but as code (see items below).
255 
256 Example on how using lambda to define a sum of two functions.
257 Note that is necessary to provide the number of parameters
258 
259 ~~~~{.cpp}
260 TF1 f1("f1","sin(x)",0,10);
261 TF1 f2("f2","cos(x)",0,10);
262 TF1 fsum("f1","[&](double *x, double *p){ return p[0]*f1(x) + p[1]*f2(x); }",0,10,2);
263 ~~~~
264 
265 ###<a name="F4"></a> 4 - A general C function with parameters
266 
267 Consider the macro myfunc.C below:
268 
269 ~~~~{.cpp}
270  // Macro myfunc.C
271  Double_t myfunction(Double_t *x, Double_t *par)
272  {
273  Float_t xx =x[0];
274  Double_t f = TMath::Abs(par[0]*sin(par[1]*xx)/xx);
275  return f;
276  }
277  void myfunc()
278  {
279  TF1 *f1 = new TF1("myfunc",myfunction,0,10,2);
280  f1->SetParameters(2,1);
281  f1->SetParNames("constant","coefficient");
282  f1->Draw();
283  }
284  void myfit()
285  {
286  TH1F *h1=new TH1F("h1","test",100,0,10);
287  h1->FillRandom("myfunc",20000);
288  TF1 *f1=gROOT->GetFunction("myfunc");
289  f1->SetParameters(800,1);
290  h1->Fit("myfunc");
291  }
292 ~~~~
293 
294 
295 
296 In an interactive session you can do:
297 
298 ~~~~
299  Root > .L myfunc.C
300  Root > myfunc();
301  Root > myfit();
302 ~~~~
303 
304 
305 
306 TF1 objects can reference other TF1 objects of type A or B defined above. This excludes CLing or compiled functions. However, there is a restriction. A function cannot reference a basic function if the basic function is a polynomial polN.
307 
308 Example:
309 
310 ~~~~{.cpp}
311 {
312  TF1 *fcos = new TF1 ("fcos", "[0]*cos(x)", 0., 10.);
313  fcos->SetParNames( "cos");
314  fcos->SetParameter( 0, 1.1);
315 
316  TF1 *fsin = new TF1 ("fsin", "[0]*sin(x)", 0., 10.);
317  fsin->SetParNames( "sin");
318  fsin->SetParameter( 0, 2.1);
319 
320  TF1 *fsincos = new TF1 ("fsc", "fcos+fsin");
321 
322  TF1 *fs2 = new TF1 ("fs2", "fsc+fsc");
323 }
324 ~~~~
325 
326 
327 ### <a name="F5"></a> 5 - A general C++ function object (functor) with parameters
328 
329 A TF1 can be created from any C++ class implementing the operator()(double *x, double *p). The advantage of the function object is that he can have a state and reference therefore what-ever other object. In this way the user can customize his function.
330 
331 Example:
332 
333 
334 ~~~~{.cpp}
335 class MyFunctionObject {
336  public:
337  // use constructor to customize your function object
338 
339  double operator() (double *x, double *p) {
340  // function implementation using class data members
341  }
342 };
343 {
344  ....
345  MyFunctionObject fobj;
346  TF1 * f = new TF1("f",fobj,0,1,npar); // create TF1 class.
347  .....
348 }
349 ~~~~
350 
351 #### Using a lambda function as a general C++ functor object
352 
353 From C++11 we can use both std::function or even better lambda functions to create the TF1.
354 As above the lambda must have the right signature but can capture whatever we want. For example we can make
355 a TF1 from the TGraph::Eval function as shown below where we use as function parameter the graph normalization.
356 
357 ~~~~{.cpp}
358 TGraph * g = new TGraph(npointx, xvec, yvec);
359 TF1 * f = new TF1("f",[&](double*x, double *p){ return p[0]*g->Eval(x[0]); }, xmin, xmax, 1);
360 ~~~~
361 
362 
363 ### <a name="F6"></a> 6 - A member function with parameters of a general C++ class
364 
365 A TF1 can be created in this case from any member function of a class which has the signature of (double * , double *) and returning a double.
366 
367 Example:
368 
369 ~~~~{.cpp}
370 class MyFunction {
371  public:
372  ...
373  double Evaluate() (double *x, double *p) {
374  // function implementation
375  }
376 };
377 {
378  ....
379  MyFunction * fptr = new MyFunction(....); // create the user function class
380  TF1 * f = new TF1("f",fptr,&MyFunction::Evaluate,0,1,npar,"MyFunction","Evaluate"); // create TF1 class.
381 
382  .....
383 }
384 ~~~~
385 
386 See also the tutorial __math/exampleFunctor.C__ for a running example.
387 */
388 ////////////////////////////////////////////////////////////////////////////
389 
390 TF1 *TF1::fgCurrent = 0;
391 
392 
393 ////////////////////////////////////////////////////////////////////////////////
394 /// TF1 default constructor.
395 
397  TNamed(), TAttLine(), TAttFill(), TAttMarker(),
398  fXmin(0), fXmax(0), fNpar(0), fNdim(0),
399  fNpx(100), fType(0),
400  fNpfits(0), fNDF(0), fChisquare(0),
401  fMinimum(-1111), fMaximum(-1111),
402  fParent(0), fHistogram(0),
403  fMethodCall(0), fNormalized(false), fNormIntegral(0),
404  fFormula(0), fParams(0)
405 {
406  SetFillStyle(0);
407 }
408 
409 
410 ////////////////////////////////////////////////////////////////////////////////
411 /// F1 constructor using a formula definition
412 ///
413 /// See TFormula constructor for explanation of the formula syntax.
414 ///
415 /// See tutorials: fillrandom, first, fit1, formula1, multifit
416 /// for real examples.
417 ///
418 /// Creates a function of type A or B between xmin and xmax
419 ///
420 /// if formula has the form "fffffff;xxxx;yyyy", it is assumed that
421 /// the formula string is "fffffff" and "xxxx" and "yyyy" are the
422 /// titles for the X and Y axis respectively.
423 
424 TF1::TF1(const char *name,const char *formula, Double_t xmin, Double_t xmax, EAddToList addToGlobList) :
425  TNamed(name,formula), TAttLine(), TAttFill(), TAttMarker(),
426  fNpx(100), fType(0),
427  fNpfits(0), fNDF(0), fChisquare(0),
428  fMinimum(-1111), fMaximum(-1111),
429  fParent(0), fHistogram(0),
430  fMethodCall(0), fNormalized(false), fNormIntegral(0),
431  fFormula(0), fParams(0)
432 {
433  if (xmin < xmax ) {
434  fXmin = xmin;
435  fXmax = xmax;
436  } else {
437  fXmin = xmax; //when called from TF2,TF3
438  fXmax = xmin;
439  }
440  // create rep formula (no need to add to gROOT list since we will add the TF1 object)
441  fFormula = new TFormula(name,formula,false);
442  fNpar = fFormula->GetNpar();
443  fNdim = fFormula->GetNdim();
444  if (fNpar) {
445  fParErrors.resize(fNpar);
446  fParMin.resize(fNpar);
447  fParMax.resize(fNpar);
448  }
449  if (fNdim > 1 && xmin < xmax) {
450  Error("TF1","function: %s/%s has dimension %d instead of 1",name,formula,fNdim);
451  MakeZombie();
452  }
453 
454  DoInitialize(addToGlobList);
455 }
456 
457 ////////////////////////////////////////////////////////////////////////////////
458 /// F1 constructor using name of an interpreted function.
459 ///
460 /// Creates a function of type C between xmin and xmax.
461 /// name is the name of an interpreted C++ function.
462 /// The function is defined with npar parameters
463 /// fcn must be a function of type:
464 ///
465 /// Double_t fcn(Double_t *x, Double_t *params)
466 ///
467 /// This constructor is called for functions of type C by the C++ interpreter.
468 ///
469 /// WARNING! A function created with this constructor cannot be Cloned.
470 
471 TF1::TF1(const char *name, Double_t xmin, Double_t xmax, Int_t npar,Int_t ndim, EAddToList addToGlobList) :
472  TNamed(name,name), TAttLine(), TAttFill(), TAttMarker(),
473  fXmin(xmin), fXmax(xmax),
474  fNpar(npar), fNdim(ndim),
475  fNpx(100), fType(2),
476  fNpfits(0), fNDF(0), fChisquare(0),
477  fMinimum(-1111), fMaximum(-1111),
478  fParErrors(std::vector<Double_t>(npar)),
479  fParMin(std::vector<Double_t>(npar)),
480  fParMax(std::vector<Double_t>(npar)),
481  fParent(0), fHistogram(0),
482  fMethodCall(0), fNormalized(false), fNormIntegral(0),
483  fFormula(0),
484  fParams(new TF1Parameters(npar) )
485 {
486  if (fName == "*") {
487  Info("TF1","TF1 has name * - it is not well defined");
488  return; //case happens via SavePrimitive
489  }
490  else if (fName.IsNull() ) {
491  Error("TF1","requires a proper function name!");
492  return;
493  }
494 
495  fMethodCall = new TMethodCall();
496  fMethodCall->InitWithPrototype(fName,"Double_t*,Double_t*");
497 
498  if (! fMethodCall->IsValid() ) {
499  Error("TF1","No function found with the signature %s(Double_t*,Double_t*)",name);
500  return;
501  }
502 
503  DoInitialize(addToGlobList);
504 }
505 
506 
507 ////////////////////////////////////////////////////////////////////////////////
508 /// Constructor using a pointer to a real function.
509 ///
510 /// \param npar is the number of free parameters used by the function
511 ///
512 /// This constructor creates a function of type C when invoked
513 /// with the normal C++ compiler.
514 ///
515 /// see test program test/stress.cxx (function stress1) for an example.
516 /// note the interface with an intermediate pointer.
517 ///
518 /// WARNING! A function created with this constructor cannot be Cloned.
519 
520 TF1::TF1(const char *name,Double_t (*fcn)(Double_t *, Double_t *), Double_t xmin, Double_t xmax, Int_t npar, Int_t ndim, EAddToList addToGlobList) :
521  TNamed(name,name), TAttLine(), TAttFill(), TAttMarker(),
522  fXmin(xmin), fXmax(xmax),
523  fNpar(npar), fNdim(ndim),
524  fNpx(100), fType(1),
525  fNpfits(0), fNDF(0), fChisquare(0),
526  fMinimum(-1111), fMaximum(-1111),
527  fParErrors(std::vector<Double_t>(npar)),
528  fParMin(std::vector<Double_t>(npar)),
529  fParMax(std::vector<Double_t>(npar)),
530  fParent(0), fHistogram(0),
531  fMethodCall(0),
532  fNormalized(false), fNormIntegral(0),
533  fFunctor(ROOT::Math::ParamFunctor(fcn)),
534  fFormula(0),
535  fParams(new TF1Parameters(npar) )
536 
537 {
538  DoInitialize(addToGlobList);
539 }
540 
541 ////////////////////////////////////////////////////////////////////////////////
542 /// Constructor using a pointer to real function.
543 ///
544 /// \param npar is the number of free parameters used by the function
545 ///
546 /// This constructor creates a function of type C when invoked
547 /// with the normal C++ compiler.
548 ///
549 /// see test program test/stress.cxx (function stress1) for an example.
550 /// note the interface with an intermediate pointer.
551 ///
552 /// WARNING! A function created with this constructor cannot be Cloned.
553 
554 TF1::TF1(const char *name,Double_t (*fcn)(const Double_t *, const Double_t *), Double_t xmin, Double_t xmax, Int_t npar, Int_t ndim, EAddToList addToGlobList) :
555  TNamed(name,name), TAttLine(), TAttFill(), TAttMarker(),
556  fXmin(xmin), fXmax(xmax),
557  fNpar(npar), fNdim(ndim),
558  fNpx(100), fType(1),
559  fNpfits(0), fNDF(0), fChisquare(0),
560  fMinimum(-1111), fMaximum(-1111),
561  fParErrors(std::vector<Double_t>(npar)),
562  fParMin(std::vector<Double_t>(npar)),
563  fParMax(std::vector<Double_t>(npar)),
564  fParent(0), fHistogram(0),
565  fMethodCall(0),
566  fNormalized(false), fNormIntegral(0),
567  fFunctor(ROOT::Math::ParamFunctor(fcn)),
568  fFormula(0),
569  fParams(new TF1Parameters(npar) )
570 {
571  DoInitialize(addToGlobList);
572 }
573 
574 
575 ////////////////////////////////////////////////////////////////////////////////
576 /// Constructor using the Functor class.
577 ///
578 /// \param xmin and
579 /// \param xmax define the plotting range of the function
580 /// \param npar is the number of free parameters used by the function
581 ///
582 /// This constructor can be used only in compiled code
583 ///
584 /// WARNING! A function created with this constructor cannot be Cloned.
585 
586 TF1::TF1(const char *name, ROOT::Math::ParamFunctor f, Double_t xmin, Double_t xmax, Int_t npar, Int_t ndim, EAddToList addToGlobList ) :
587  TNamed(name,name), TAttLine(), TAttFill(), TAttMarker(),
588  fXmin(xmin), fXmax(xmax),
589  fNpar(npar), fNdim(ndim),
590  fNpx(100), fType(1),
591  fNpfits(0), fNDF(0), fChisquare(0),
592  fMinimum(-1111), fMaximum(-1111),
593  fParErrors(std::vector<Double_t>(npar)),
594  fParMin(std::vector<Double_t>(npar)),
595  fParMax(std::vector<Double_t>(npar)),
596  fParent(0), fHistogram(0),
597  fMethodCall(0),
598  fNormalized(false), fNormIntegral(0),
599  fFunctor(ROOT::Math::ParamFunctor(f)),
600  fFormula(0),
601  fParams(new TF1Parameters(npar) )
602 
603 {
604  DoInitialize(addToGlobList);
605 }
606 
607 ////////////////////////////////////////////////////////////////////////////////
608 /// Common initialization of the TF1. Add to the global list and
609 /// set the default style
610 
611 void TF1::DoInitialize(EAddToList addToGlobalList) {
612 
613  fMinimum = -1111;
614  fMaximum = -1111;
615 
616  // add to global list of functions if default adding is on OR if bit is set
617  bool doAdd = ((addToGlobalList == EAddToList::kDefault && fgAddToGlobList)
618  || addToGlobalList == EAddToList::kAdd);
619  if (doAdd && gROOT) {
622  // Store formula in linked list of formula in ROOT
623  TF1 *f1old = (TF1*)gROOT->GetListOfFunctions()->FindObject(fName);
624  if (f1old) {
625  gROOT->GetListOfFunctions()->Remove(f1old);
626  // We removed f1old from the list, it is not longer global.
627  // (See TF1::AddToGlobalList which requires this flag to be correct).
628  f1old->SetBit(kNotGlobal, kTRUE);
629  }
630  gROOT->GetListOfFunctions()->Add(this);
631  }
632  else
634 
635  if (gStyle) {
639  }
640  SetFillStyle(0);
641 }
642 
643 ////////////////////////////////////////////////////////////////////////////////
644 /// Static method to add/avoid to add automatically functions to the global list (gROOT->GetListOfFunctions() )
645 /// After having called this static method, all the functions created afterwards will follow the
646 /// desired behaviour.
647 ///
648 /// By default the functions are added automatically
649 /// It returns the previous status (true if the functions are added automatically)
650 
652 {
653  return fgAddToGlobList.exchange(on);
654 }
655 
656 ////////////////////////////////////////////////////////////////////////////////
657 /// Add to global list of functions (gROOT->GetListOfFunctions() )
658 /// return previous status (true if the function was already in the list false if not)
659 
661 {
662  if (!gROOT) return false;
663 
664  bool prevStatus = !TestBit(kNotGlobal);
665  if (on ) {
666  if (prevStatus) {
668  assert (gROOT->GetListOfFunctions()->FindObject(this) != nullptr);
669  return on; // do nothing
670  }
671  // do I need to delete previous one with the same name ???
672  //TF1 * old = dynamic_cast<TF1*>( gROOT->GetListOfFunctions()->FindObject(GetName()) );
673  //if (old) { gROOT->GetListOfFunctions()->Remove(old); old->SetBit(kNotGlobal, kTRUE); }
675  gROOT->GetListOfFunctions()->Add(this);
677  }
678  else if (prevStatus) {
679  // if previous status was on and now is off we need to remove the function
682  TF1 * old = dynamic_cast<TF1*>( gROOT->GetListOfFunctions()->FindObject(GetName()) );
683  if (!old) {
684  Warning("AddToGlobalList","Function is supposed to be in the global list but it is not present");
685  return kFALSE;
686  }
687  gROOT->GetListOfFunctions()->Remove(this);
688  }
689  return prevStatus;
690 }
691 
692 
693 ////////////////////////////////////////////////////////////////////////////////
694 /// Operator =
695 
696 TF1& TF1::operator=(const TF1 &rhs)
697 {
698  if (this != &rhs) {
699  rhs.Copy(*this);
700  }
701  return *this;
702 }
703 
704 
705 ////////////////////////////////////////////////////////////////////////////////
706 /// TF1 default destructor.
707 
709 {
710  if (fHistogram) delete fHistogram;
711  if (fMethodCall) delete fMethodCall;
712 
713  // this was before in TFormula destructor
714  {
716  if (gROOT) gROOT->GetListOfFunctions()->Remove(this);
717  }
718 
719  if (fParent) fParent->RecursiveRemove(this);
720 
721  if (fFormula) delete fFormula;
722  if (fParams) delete fParams;
723 }
724 
725 
726 ////////////////////////////////////////////////////////////////////////////////
727 
728 TF1::TF1(const TF1 &f1) :
729  TNamed(f1), TAttLine(f1), TAttFill(f1), TAttMarker(f1),
730  fXmin(0), fXmax(0), fNpar(0), fNdim(0),
731  fNpx(100), fType(0),
732  fNpfits(0), fNDF(0), fChisquare(0),
733  fMinimum(-1111), fMaximum(-1111),
734  fParent(0), fHistogram(0),
735  fMethodCall(0),
736  fNormalized(false), fNormIntegral(0),
737  fFormula(0), fParams(0)
738 {
739  ((TF1&)f1).Copy(*this);
740 }
741 
742 
743 ////////////////////////////////////////////////////////////////////////////////
744 /// Static function: set the fgAbsValue flag.
745 /// By default TF1::Integral uses the original function value to compute the integral
746 /// However, TF1::Moment, CentralMoment require to compute the integral
747 /// using the absolute value of the function.
748 
750 {
751  fgAbsValue = flag;
752 }
753 
754 
755 ////////////////////////////////////////////////////////////////////////////////
756 /// Browse.
757 
759 {
760  Draw(b ? b->GetDrawOption() : "");
761  gPad->Update();
762 }
763 
764 
765 ////////////////////////////////////////////////////////////////////////////////
766 /// Copy this F1 to a new F1.
767 /// Note that the cached integral with its related arrays are not copied
768 /// (they are also set as transient data members)
769 
770 void TF1::Copy(TObject &obj) const
771 {
772  delete ((TF1&)obj).fHistogram;
773  delete ((TF1&)obj).fMethodCall;
774 
775  TNamed::Copy((TF1&)obj);
776  TAttLine::Copy((TF1&)obj);
777  TAttFill::Copy((TF1&)obj);
778  TAttMarker::Copy((TF1&)obj);
779  ((TF1&)obj).fXmin = fXmin;
780  ((TF1&)obj).fXmax = fXmax;
781  ((TF1&)obj).fNpx = fNpx;
782  ((TF1&)obj).fNpar = fNpar;
783  ((TF1&)obj).fNdim = fNdim;
784  ((TF1&)obj).fType = fType;
785  ((TF1&)obj).fFunctor = fFunctor;
786  ((TF1&)obj).fChisquare = fChisquare;
787  ((TF1&)obj).fNpfits = fNpfits;
788  ((TF1&)obj).fNDF = fNDF;
789  ((TF1&)obj).fMinimum = fMinimum;
790  ((TF1&)obj).fMaximum = fMaximum;
791 
792  ((TF1&)obj).fParErrors = fParErrors;
793  ((TF1&)obj).fParMin = fParMin;
794  ((TF1&)obj).fParMax = fParMax;
795  ((TF1&)obj).fParent = fParent;
796  ((TF1&)obj).fSave = fSave;
797  ((TF1&)obj).fHistogram = 0;
798  ((TF1&)obj).fMethodCall = 0;
799  ((TF1&)obj).fNormalized = fNormalized;
800  ((TF1&)obj).fNormIntegral = fNormIntegral;
801  ((TF1&)obj).fFormula = 0;
802 
803  if (fFormula) assert(fFormula->GetNpar() == fNpar);
804 
805  if (fMethodCall) {
806  // use copy-constructor of TMethodCall
807  if (((TF1&)obj).fMethodCall) delete ((TF1&)obj).fMethodCall;
809 // m->InitWithPrototype(fMethodCall->GetMethodName(),fMethodCall->GetProto());
810  ((TF1&)obj).fMethodCall = m;
811  }
812  if(fFormula)
813  {
814  TFormula * formulaToCopy = ((TF1&)obj).fFormula;
815  if (formulaToCopy) delete formulaToCopy;
816  formulaToCopy = new TFormula();
817  fFormula->Copy( *formulaToCopy );
818  ((TF1&)obj).fFormula = formulaToCopy;
819  }
820  if (fParams) {
821  TF1Parameters * paramsToCopy = ((TF1&)obj).fParams;
822  if (paramsToCopy) *paramsToCopy = *fParams;
823  else ((TF1&)obj).fParams = new TF1Parameters(*fParams);
824  }
825 }
826 
827 
828 ////////////////////////////////////////////////////////////////////////////////
829 /// Returns the first derivative of the function at point x,
830 /// computed by Richardson's extrapolation method (use 2 derivative estimates
831 /// to compute a third, more accurate estimation)
832 /// first, derivatives with steps h and h/2 are computed by central difference formulas
833 /// \f[
834 /// D(h) = \frac{f(x+h) - f(x-h)}{2h}
835 /// \f]
836 /// the final estimate
837 /// \f[
838 /// D = \frac{4D(h/2) - D(h)}{3}
839 /// \f]
840 /// "Numerical Methods for Scientists and Engineers", H.M.Antia, 2nd edition"
841 ///
842 /// if the argument params is null, the current function parameters are used,
843 /// otherwise the parameters in params are used.
844 ///
845 /// the argument eps may be specified to control the step size (precision).
846 /// the step size is taken as eps*(xmax-xmin).
847 /// the default value (0.001) should be good enough for the vast majority
848 /// of functions. Give a smaller value if your function has many changes
849 /// of the second derivative in the function range.
850 ///
851 /// Getting the error via TF1::DerivativeError:
852 /// (total error = roundoff error + interpolation error)
853 /// the estimate of the roundoff error is taken as follows:
854 /// \f[
855 /// err = k\sqrt{f(x)^{2} + x^{2}deriv^{2}}\sqrt{\sum ai^{2}},
856 /// \f]
857 /// where k is the double precision, ai are coefficients used in
858 /// central difference formulas
859 /// interpolation error is decreased by making the step size h smaller.
860 ///
861 /// \author Anna Kreshuk
862 
864 {
865  if (GetNdim() > 1) {
866  Warning("Derivative","Function dimension is larger than one");
867  }
868 
870  double xmin, xmax;
871  GetRange(xmin, xmax);
872  // this is not optimal (should be used the average x instead of the range)
873  double h = eps* std::abs(xmax-xmin);
874  if ( h <= 0 ) h = 0.001;
875  double der = 0;
876  if (params) {
877  ROOT::Math::WrappedTF1 wtf(*( const_cast<TF1 *> (this) ));
878  wtf.SetParameters(params);
879  der = rd.Derivative1(wtf,x,h);
880  }
881  else {
882  // no need to set parameters used a non-parametric wrapper to avoid allocating
883  // an array with parameter values
885  der = rd.Derivative1(wf,x,h);
886  }
887 
888  gErrorTF1 = rd.Error();
889  return der;
890 
891 }
892 
893 
894 ////////////////////////////////////////////////////////////////////////////////
895 /// Returns the second derivative of the function at point x,
896 /// computed by Richardson's extrapolation method (use 2 derivative estimates
897 /// to compute a third, more accurate estimation)
898 /// first, derivatives with steps h and h/2 are computed by central difference formulas
899 /// \f[
900 /// D(h) = \frac{f(x+h) - 2f(x) + f(x-h)}{h^{2}}
901 /// \f]
902 /// the final estimate
903 /// \f[
904 /// D = \frac{4D(h/2) - D(h)}{3}
905 /// \f]
906 /// "Numerical Methods for Scientists and Engineers", H.M.Antia, 2nd edition"
907 ///
908 /// if the argument params is null, the current function parameters are used,
909 /// otherwise the parameters in params are used.
910 ///
911 /// the argument eps may be specified to control the step size (precision).
912 /// the step size is taken as eps*(xmax-xmin).
913 /// the default value (0.001) should be good enough for the vast majority
914 /// of functions. Give a smaller value if your function has many changes
915 /// of the second derivative in the function range.
916 ///
917 /// Getting the error via TF1::DerivativeError:
918 /// (total error = roundoff error + interpolation error)
919 /// the estimate of the roundoff error is taken as follows:
920 /// \f[
921 /// err = k\sqrt{f(x)^{2} + x^{2}deriv^{2}}\sqrt{\sum ai^{2}},
922 /// \f]
923 /// where k is the double precision, ai are coefficients used in
924 /// central difference formulas
925 /// interpolation error is decreased by making the step size h smaller.
926 ///
927 /// \author Anna Kreshuk
928 
930 {
931  if (GetNdim() > 1) {
932  Warning("Derivative2","Function dimension is larger than one");
933  }
934 
936  double xmin, xmax;
937  GetRange(xmin, xmax);
938  // this is not optimal (should be used the average x instead of the range)
939  double h = eps* std::abs(xmax-xmin);
940  if ( h <= 0 ) h = 0.001;
941  double der = 0;
942  if (params) {
943  ROOT::Math::WrappedTF1 wtf(*( const_cast<TF1 *> (this) ));
944  wtf.SetParameters(params);
945  der = rd.Derivative2(wtf,x,h);
946  }
947  else {
948  // no need to set parameters used a non-parametric wrapper to avoid allocating
949  // an array with parameter values
951  der = rd.Derivative2(wf,x,h);
952  }
953 
954  gErrorTF1 = rd.Error();
955 
956  return der;
957 }
958 
959 
960 ////////////////////////////////////////////////////////////////////////////////
961 /// Returns the third derivative of the function at point x,
962 /// computed by Richardson's extrapolation method (use 2 derivative estimates
963 /// to compute a third, more accurate estimation)
964 /// first, derivatives with steps h and h/2 are computed by central difference formulas
965 /// \f[
966 /// D(h) = \frac{f(x+2h) - 2f(x+h) + 2f(x-h) - f(x-2h)}{2h^{3}}
967 /// \f]
968 /// the final estimate
969 /// \f[
970 /// D = \frac{4D(h/2) - D(h)}{3}
971 /// \f]
972 /// "Numerical Methods for Scientists and Engineers", H.M.Antia, 2nd edition"
973 ///
974 /// if the argument params is null, the current function parameters are used,
975 /// otherwise the parameters in params are used.
976 ///
977 /// the argument eps may be specified to control the step size (precision).
978 /// the step size is taken as eps*(xmax-xmin).
979 /// the default value (0.001) should be good enough for the vast majority
980 /// of functions. Give a smaller value if your function has many changes
981 /// of the second derivative in the function range.
982 ///
983 /// Getting the error via TF1::DerivativeError:
984 /// (total error = roundoff error + interpolation error)
985 /// the estimate of the roundoff error is taken as follows:
986 /// \f[
987 /// err = k\sqrt{f(x)^{2} + x^{2}deriv^{2}}\sqrt{\sum ai^{2}},
988 /// \f]
989 /// where k is the double precision, ai are coefficients used in
990 /// central difference formulas
991 /// interpolation error is decreased by making the step size h smaller.
992 ///
993 /// \author Anna Kreshuk
994 
996 {
997  if (GetNdim() > 1) {
998  Warning("Derivative3","Function dimension is larger than one");
999  }
1000 
1002  double xmin, xmax;
1003  GetRange(xmin, xmax);
1004  // this is not optimal (should be used the average x instead of the range)
1005  double h = eps* std::abs(xmax-xmin);
1006  if ( h <= 0 ) h = 0.001;
1007  double der = 0;
1008  if (params) {
1009  ROOT::Math::WrappedTF1 wtf(*( const_cast<TF1 *> (this) ));
1010  wtf.SetParameters(params);
1011  der = rd.Derivative3(wtf,x,h);
1012  }
1013  else {
1014  // no need to set parameters used a non-parametric wrapper to avoid allocating
1015  // an array with parameter values
1017  der = rd.Derivative3(wf,x,h);
1018  }
1019 
1020  gErrorTF1 = rd.Error();
1021  return der;
1022 
1023 }
1024 
1025 
1026 ////////////////////////////////////////////////////////////////////////////////
1027 /// Static function returning the error of the last call to the of Derivative's
1028 /// functions
1029 
1031 {
1032  return gErrorTF1;
1033 }
1034 
1035 
1036 ////////////////////////////////////////////////////////////////////////////////
1037 /// Compute distance from point px,py to a function.
1038 ///
1039 /// Compute the closest distance of approach from point px,py to this
1040 /// function. The distance is computed in pixels units.
1041 ///
1042 /// Note that px is called with a negative value when the TF1 is in
1043 /// TGraph or TH1 list of functions. In this case there is no point
1044 /// looking at the histogram axis.
1045 
1047 {
1048  if (!fHistogram) return 9999;
1049  Int_t distance = 9999;
1050  if (px >= 0) {
1051  distance = fHistogram->DistancetoPrimitive(px,py);
1052  if (distance <= 1) return distance;
1053  } else {
1054  px = -px;
1055  }
1056 
1057  Double_t xx[1];
1058  Double_t x = gPad->AbsPixeltoX(px);
1059  xx[0] = gPad->PadtoX(x);
1060  if (xx[0] < fXmin || xx[0] > fXmax) return distance;
1061  Double_t fval = Eval(xx[0]);
1062  Double_t y = gPad->YtoPad(fval);
1063  Int_t pybin = gPad->YtoAbsPixel(y);
1064  return TMath::Abs(py - pybin);
1065 }
1066 
1067 
1068 ////////////////////////////////////////////////////////////////////////////////
1069 /// Draw this function with its current attributes.
1070 ///
1071 /// Possible option values are:
1072 ///
1073 /// option | description
1074 /// -------|----------------------------------------
1075 /// "SAME" | superimpose on top of existing picture
1076 /// "L" | connect all computed points with a straight line
1077 /// "C" | connect all computed points with a smooth curve
1078 /// "FC" | draw a fill area below a smooth curve
1079 ///
1080 /// Note that the default value is "L". Therefore to draw on top
1081 /// of an existing picture, specify option "LSAME"
1082 ///
1083 /// NB. You must use DrawCopy if you want to draw several times the same
1084 /// function in the current canvas.
1085 
1086 void TF1::Draw(Option_t *option)
1087 {
1088  TString opt = option;
1089  opt.ToLower();
1090  if (gPad && !opt.Contains("same")) gPad->Clear();
1091 
1092  AppendPad(option);
1093 }
1094 
1095 
1096 ////////////////////////////////////////////////////////////////////////////////
1097 /// Draw a copy of this function with its current attributes.
1098 ///
1099 /// This function MUST be used instead of Draw when you want to draw
1100 /// the same function with different parameters settings in the same canvas.
1101 ///
1102 /// Possible option values are:
1103 ///
1104 /// option | description
1105 /// -------|----------------------------------------
1106 /// "SAME" | superimpose on top of existing picture
1107 /// "L" | connect all computed points with a straight line
1108 /// "C" | connect all computed points with a smooth curve
1109 /// "FC" | draw a fill area below a smooth curve
1110 ///
1111 /// Note that the default value is "L". Therefore to draw on top
1112 /// of an existing picture, specify option "LSAME"
1113 
1114 TF1 *TF1::DrawCopy(Option_t *option) const
1115 {
1116  TF1 *newf1 = (TF1*)this->IsA()->New();
1117  Copy(*newf1);
1118  newf1->AppendPad(option);
1119  newf1->SetBit(kCanDelete);
1120  return newf1;
1121 }
1122 
1123 
1124 ////////////////////////////////////////////////////////////////////////////////
1125 /// Draw derivative of this function
1126 ///
1127 /// An intermediate TGraph object is built and drawn with option.
1128 /// The function returns a pointer to the TGraph object. Do:
1129 ///
1130 /// TGraph *g = (TGraph*)myfunc.DrawDerivative(option);
1131 ///
1132 /// The resulting graph will be drawn into the current pad.
1133 /// If this function is used via the context menu, it recommended
1134 /// to create a new canvas/pad before invoking this function.
1135 
1137 {
1138  TVirtualPad *pad = gROOT->GetSelectedPad();
1139  TVirtualPad *padsav = gPad;
1140  if (pad) pad->cd();
1141 
1142  TGraph *gr = new TGraph(this,"d");
1143  gr->Draw(option);
1144  if (padsav) padsav->cd();
1145  return gr;
1146 }
1147 
1148 
1149 ////////////////////////////////////////////////////////////////////////////////
1150 /// Draw integral of this function
1151 ///
1152 /// An intermediate TGraph object is built and drawn with option.
1153 /// The function returns a pointer to the TGraph object. Do:
1154 ///
1155 /// TGraph *g = (TGraph*)myfunc.DrawIntegral(option);
1156 ///
1157 /// The resulting graph will be drawn into the current pad.
1158 /// If this function is used via the context menu, it recommended
1159 /// to create a new canvas/pad before invoking this function.
1160 
1162 {
1163  TVirtualPad *pad = gROOT->GetSelectedPad();
1164  TVirtualPad *padsav = gPad;
1165  if (pad) pad->cd();
1166 
1167  TGraph *gr = new TGraph(this,"i");
1168  gr->Draw(option);
1169  if (padsav) padsav->cd();
1170  return gr;
1171 }
1172 
1173 
1174 ////////////////////////////////////////////////////////////////////////////////
1175 /// Draw function between xmin and xmax.
1176 
1178 {
1179 // //if(Compile(formula)) return ;
1180  SetRange(xmin, xmax);
1181 
1182  Draw(option);
1183 }
1184 
1185 
1186 ////////////////////////////////////////////////////////////////////////////////
1187 /// Evaluate this function.
1188 ///
1189 /// Computes the value of this function (general case for a 3-d function)
1190 /// at point x,y,z.
1191 /// For a 1-d function give y=0 and z=0
1192 /// The current value of variables x,y,z is passed through x, y and z.
1193 /// The parameters used will be the ones in the array params if params is given
1194 /// otherwise parameters will be taken from the stored data members fParams
1195 
1197 {
1198  if (fType == 0) return fFormula->Eval(x,y,z,t);
1199 
1200  Double_t xx[4] = {x, y, z, t};
1202  if (fType==2) ((TF1*)this)->InitArgs(xx,pp);
1203  return ((TF1*)this)->EvalPar(xx,pp);
1204 }
1205 
1206 
1207 ////////////////////////////////////////////////////////////////////////////////
1208 /// Evaluate function with given coordinates and parameters.
1209 ///
1210 /// Compute the value of this function at point defined by array x
1211 /// and current values of parameters in array params.
1212 /// If argument params is omitted or equal 0, the internal values
1213 /// of parameters (array fParams) will be used instead.
1214 /// For a 1-D function only x[0] must be given.
1215 /// In case of a multi-dimensional function, the arrays x must be
1216 /// filled with the corresponding number of dimensions.
1217 ///
1218 /// WARNING. In case of an interpreted function (fType=2), it is the
1219 /// user's responsibility to initialize the parameters via InitArgs
1220 /// before calling this function.
1221 /// InitArgs should be called at least once to specify the addresses
1222 /// of the arguments x and params.
1223 /// InitArgs should be called every time these addresses change.
1224 
1225 Double_t TF1::EvalPar(const Double_t *x, const Double_t *params)
1226 {
1227  //fgCurrent = this;
1228 
1229  if (fType == 0)
1230  {
1231  assert(fFormula);
1232  if (fNormalized && fNormIntegral != 0)
1233  return fFormula->EvalPar(x,params)/fNormIntegral;
1234  else
1235  return fFormula->EvalPar(x,params);
1236  }
1237  Double_t result = 0;
1238  if (fType == 1) {
1239  if (!fFunctor.Empty()) {
1240  assert(fParams);
1241  if (params) result = fFunctor((Double_t*)x,(Double_t*)params);
1242  else result = fFunctor((Double_t*)x,(Double_t*)fParams->GetParameters());
1243 
1244  }else result = GetSave(x);
1245 
1246  if (fNormalized && fNormIntegral!=0)
1247  result = result/fNormIntegral;
1248 
1249  return result;
1250  }
1251  if (fType == 2) {
1252  if (fMethodCall) fMethodCall->Execute(result);
1253  else result = GetSave(x);
1254 
1255  if (fNormalized && fNormIntegral!=0)
1256  result = result/fNormIntegral;
1257 
1258  return result;
1259  }
1260 
1261  return result;
1262 }
1263 
1264 
1265 ////////////////////////////////////////////////////////////////////////////////
1266 /// Execute action corresponding to one event.
1267 ///
1268 /// This member function is called when a F1 is clicked with the locator
1269 
1270 void TF1::ExecuteEvent(Int_t event, Int_t px, Int_t py)
1271 {
1272  if (!gPad) return;
1273 
1274  if (fHistogram) fHistogram->ExecuteEvent(event,px,py);
1275 
1276  if (!gPad->GetView()) {
1277  if (event == kMouseMotion) gPad->SetCursor(kHand);
1278  }
1279 }
1280 
1281 
1282 ////////////////////////////////////////////////////////////////////////////////
1283 /// Fix the value of a parameter
1284 /// The specified value will be used in a fit operation
1285 
1287 {
1288  if (ipar < 0 || ipar > GetNpar()-1) return;
1289  SetParameter(ipar,value);
1290  if (value != 0) SetParLimits(ipar,value,value);
1291  else SetParLimits(ipar,1,1);
1292 }
1293 
1294 
1295 ////////////////////////////////////////////////////////////////////////////////
1296 /// Static function returning the current function being processed
1297 
1299 {
1300  ::Warning("TF1::GetCurrent","This function is obsolete and is working only for the current painted functions");
1301  return fgCurrent;
1302 }
1303 
1304 
1305 ////////////////////////////////////////////////////////////////////////////////
1306 /// Return a pointer to the histogram used to visualise the function
1307 
1309 {
1310  if (fHistogram) return fHistogram;
1311 
1312  // histogram has not been yet created - create it
1313  // should not we make this function not const ??
1314  const_cast<TF1*>(this)->fHistogram = const_cast<TF1*>(this)->CreateHistogram();
1315  if (!fHistogram) Error("GetHistogram","Error creating histogram for function %s of type %s",GetName(),IsA()->GetName() );
1316  return fHistogram;
1317 }
1318 
1319 
1320 ////////////////////////////////////////////////////////////////////////////////
1321 /// Returns the maximum value of the function
1322 ///
1323 /// Method:
1324 /// First, the grid search is used to bracket the maximum
1325 /// with the step size = (xmax-xmin)/fNpx.
1326 /// This way, the step size can be controlled via the SetNpx() function.
1327 /// If the function is unimodal or if its extrema are far apart, setting
1328 /// the fNpx to a small value speeds the algorithm up many times.
1329 /// Then, Brent's method is applied on the bracketed interval
1330 /// epsilon (default = 1.E-10) controls the relative accuracy (if |x| > 1 )
1331 /// and absolute (if |x| < 1) and maxiter (default = 100) controls the maximum number
1332 /// of iteration of the Brent algorithm
1333 /// If the flag logx is set the grid search is done in log step size
1334 /// This is done automatically if the log scale is set in the current Pad
1335 ///
1336 /// NOTE: see also TF1::GetMaximumX and TF1::GetX
1337 
1339 {
1340  if (xmin >= xmax) {xmin = fXmin; xmax = fXmax;}
1341 
1342  if (!logx && gPad != 0) logx = gPad->GetLogx();
1343 
1345  GInverseFunc g(this);
1347  bm.SetFunction( wf1, xmin, xmax );
1348  bm.SetNpx(fNpx);
1349  bm.SetLogScan(logx);
1350  bm.Minimize(maxiter, epsilon, epsilon );
1351  Double_t x;
1352  x = - bm.FValMinimum();
1353 
1354  return x;
1355 }
1356 
1357 
1358 ////////////////////////////////////////////////////////////////////////////////
1359 /// Returns the X value corresponding to the maximum value of the function
1360 ///
1361 /// Method:
1362 /// First, the grid search is used to bracket the maximum
1363 /// with the step size = (xmax-xmin)/fNpx.
1364 /// This way, the step size can be controlled via the SetNpx() function.
1365 /// If the function is unimodal or if its extrema are far apart, setting
1366 /// the fNpx to a small value speeds the algorithm up many times.
1367 /// Then, Brent's method is applied on the bracketed interval
1368 /// epsilon (default = 1.E-10) controls the relative accuracy (if |x| > 1 )
1369 /// and absolute (if |x| < 1) and maxiter (default = 100) controls the maximum number
1370 /// of iteration of the Brent algorithm
1371 /// If the flag logx is set the grid search is done in log step size
1372 /// This is done automatically if the log scale is set in the current Pad
1373 ///
1374 /// NOTE: see also TF1::GetX
1375 
1377 {
1378  if (xmin >= xmax) {xmin = fXmin; xmax = fXmax;}
1379 
1380  if (!logx && gPad != 0) logx = gPad->GetLogx();
1381 
1383  GInverseFunc g(this);
1385  bm.SetFunction( wf1, xmin, xmax );
1386  bm.SetNpx(fNpx);
1387  bm.SetLogScan(logx);
1388  bm.Minimize(maxiter, epsilon, epsilon );
1389  Double_t x;
1390  x = bm.XMinimum();
1391 
1392  return x;
1393 }
1394 
1395 
1396 ////////////////////////////////////////////////////////////////////////////////
1397 /// Returns the minimum value of the function on the (xmin, xmax) interval
1398 ///
1399 /// Method:
1400 /// First, the grid search is used to bracket the maximum
1401 /// with the step size = (xmax-xmin)/fNpx. This way, the step size
1402 /// can be controlled via the SetNpx() function. If the function is
1403 /// unimodal or if its extrema are far apart, setting the fNpx to
1404 /// a small value speeds the algorithm up many times.
1405 /// Then, Brent's method is applied on the bracketed interval
1406 /// epsilon (default = 1.E-10) controls the relative accuracy (if |x| > 1 )
1407 /// and absolute (if |x| < 1) and maxiter (default = 100) controls the maximum number
1408 /// of iteration of the Brent algorithm
1409 /// If the flag logx is set the grid search is done in log step size
1410 /// This is done automatically if the log scale is set in the current Pad
1411 ///
1412 /// NOTE: see also TF1::GetMaximumX and TF1::GetX
1413 
1415 {
1416  if (xmin >= xmax) {xmin = fXmin; xmax = fXmax;}
1417 
1418  if (!logx && gPad != 0) logx = gPad->GetLogx();
1419 
1422  bm.SetFunction( wf1, xmin, xmax );
1423  bm.SetNpx(fNpx);
1424  bm.SetLogScan(logx);
1425  bm.Minimize(maxiter, epsilon, epsilon );
1426  Double_t x;
1427  x = bm.FValMinimum();
1428 
1429  return x;
1430 }
1431 
1432 ////////////////////////////////////////////////////////////////////////////////
1433 /// Find the minimum of a function of whatever dimension.
1434 /// While GetMinimum works only for 1D function , GetMinimumNDim works for all dimensions
1435 /// since it uses the minimizer interface
1436 /// vector x at beginning will contained the initial point, on exit will contain the result
1437 
1438 Double_t TF1::GetMinMaxNDim(Double_t * x , bool findmax, Double_t epsilon, Int_t maxiter ) const
1439 {
1440  R__ASSERT(x != 0);
1441 
1442  int ndim = GetNdim();
1443  if (ndim == 0) {
1444  Error("GetMinimumNDim","Function of dimension 0 - return Eval(x)");
1445  return (const_cast<TF1&>(*this))(x);
1446  }
1447 
1448  // create minimizer class
1449  const char * minimName = ROOT::Math::MinimizerOptions::DefaultMinimizerType().c_str();
1450  const char * minimAlgo = ROOT::Math::MinimizerOptions::DefaultMinimizerAlgo().c_str();
1451  ROOT::Math::Minimizer * min = ROOT::Math::Factory::CreateMinimizer(minimName, minimAlgo);
1452 
1453  if (min == 0) {
1454  Error("GetMinimumNDim","Error creating minimizer %s",minimName);
1455  return 0;
1456  }
1457 
1458  // minimizer will be set using default values
1459  if (epsilon > 0) min->SetTolerance(epsilon);
1460  if (maxiter > 0) min->SetMaxFunctionCalls(maxiter);
1461 
1462  // create wrapper class from TF1 (cannot use Functor, t.b.i.)
1463  ROOT::Math::WrappedMultiFunction<TF1&> objFunc(const_cast<TF1&>(*this),ndim);
1464  // create -f(x) when searching for the maximum
1465  GInverseFuncNdim invFunc(const_cast<TF1*>(this));
1466  ROOT::Math::WrappedMultiFunction<GInverseFuncNdim&> objFuncInv(invFunc,ndim);
1467  if (!findmax)
1468  min->SetFunction(objFunc);
1469  else
1470  min->SetFunction(objFuncInv);
1471 
1472  std::vector<double> rmin(ndim);
1473  std::vector<double> rmax(ndim);
1474  GetRange(&rmin[0],&rmax[0]);
1475  for (int i = 0; i < ndim; ++i) {
1476  const char * xname = 0;
1477  double stepSize = 0.1;
1478  // use range for step size or give some value depending on x if range is not defined
1479  if (rmax[i] > rmin[i])
1480  stepSize = (rmax[i] - rmin[i])/100;
1481  else if (std::abs(x[i]) > 1.)
1482  stepSize = 0.1*x[i];
1483 
1484  // set variable names
1485  if (ndim <= 3) {
1486  if (i == 0) {
1487  xname = "x";
1488  }
1489  else if (i == 1) {
1490  xname = "y";
1491  }
1492  else {
1493  xname = "z";
1494  }
1495  }
1496  else {
1497  xname = TString::Format("x_%d",i);
1498  // arbitrary step sie (should be computed from range)
1499  }
1500 
1501  if (rmin[i] < rmax[i] ) {
1502  //Info("GetMinMax","setting limits on %s - [ %f , %f ]",xname,rmin[i],rmax[i]);
1503  min->SetLimitedVariable(i,xname,x[i], stepSize, rmin[i], rmax[i]);
1504  }
1505  else {
1506  min->SetVariable(i,xname,x[i], stepSize);
1507  }
1508  }
1509 
1510  bool ret = min->Minimize();
1511  if (!ret) {
1512  Error("GetMinimumNDim","Error minimizing function %s",GetName() );
1513  }
1514  if (min->X() ) std::copy (min->X(), min->X()+ndim, x);
1515  double fmin = min->MinValue();
1516  delete min;
1517  // need to revert sign in case looking for maximum
1518  return (findmax) ? -fmin : fmin;
1519 
1520 }
1521 
1522 
1523 ////////////////////////////////////////////////////////////////////////////////
1524 /// Returns the X value corresponding to the minimum value of the function
1525 /// on the (xmin, xmax) interval
1526 ///
1527 /// Method:
1528 /// First, the grid search is used to bracket the maximum
1529 /// with the step size = (xmax-xmin)/fNpx. This way, the step size
1530 /// can be controlled via the SetNpx() function. If the function is
1531 /// unimodal or if its extrema are far apart, setting the fNpx to
1532 /// a small value speeds the algorithm up many times.
1533 /// Then, Brent's method is applied on the bracketed interval
1534 /// epsilon (default = 1.E-10) controls the relative accuracy (if |x| > 1 )
1535 /// and absolute (if |x| < 1) and maxiter (default = 100) controls the maximum number
1536 /// of iteration of the Brent algorithm
1537 /// If the flag logx is set the grid search is done in log step size
1538 /// This is done automatically if the log scale is set in the current Pad
1539 ///
1540 /// NOTE: see also TF1::GetX
1541 
1543 {
1544  if (xmin >= xmax) {xmin = fXmin; xmax = fXmax;}
1545 
1548  bm.SetFunction( wf1, xmin, xmax );
1549  bm.SetNpx(fNpx);
1550  bm.SetLogScan(logx);
1551  bm.Minimize(maxiter, epsilon, epsilon );
1552  Double_t x;
1553  x = bm.XMinimum();
1554 
1555  return x;
1556 }
1557 
1558 
1559 ////////////////////////////////////////////////////////////////////////////////
1560 /// Returns the X value corresponding to the function value fy for (xmin<x<xmax).
1561 /// in other words it can find the roots of the function when fy=0 and successive calls
1562 /// by changing the next call to [xmin+eps,xmax] where xmin is the previous root.
1563 ///
1564 /// Method:
1565 /// First, the grid search is used to bracket the maximum
1566 /// with the step size = (xmax-xmin)/fNpx. This way, the step size
1567 /// can be controlled via the SetNpx() function. If the function is
1568 /// unimodal or if its extrema are far apart, setting the fNpx to
1569 /// a small value speeds the algorithm up many times.
1570 /// Then, Brent's method is applied on the bracketed interval
1571 /// epsilon (default = 1.E-10) controls the relative accuracy (if |x| > 1 )
1572 /// and absolute (if |x| < 1) and maxiter (default = 100) controls the maximum number
1573 /// of iteration of the Brent algorithm
1574 /// If the flag logx is set the grid search is done in log step size
1575 /// This is done automatically if the log scale is set in the current Pad
1576 ///
1577 /// NOTE: see also TF1::GetMaximumX, TF1::GetMinimumX
1578 
1580 {
1581  if (xmin >= xmax) {xmin = fXmin; xmax = fXmax;}
1582 
1583  if (!logx && gPad != 0) logx = gPad->GetLogx();
1584 
1585  GFunc g(this, fy);
1588  brf.SetFunction(wf1,xmin,xmax);
1589  brf.SetNpx(fNpx);
1590  brf.SetLogScan(logx);
1591  brf.Solve(maxiter, epsilon, epsilon);
1592  return brf.Root();
1593 
1594 }
1595 
1596 ////////////////////////////////////////////////////////////////////////////////
1597 /// Return the number of degrees of freedom in the fit
1598 /// the fNDF parameter has been previously computed during a fit.
1599 /// The number of degrees of freedom corresponds to the number of points
1600 /// used in the fit minus the number of free parameters.
1601 
1603 {
1604  Int_t npar = GetNpar();
1605  if (fNDF == 0 && (fNpfits > npar) ) return fNpfits-npar;
1606  return fNDF;
1607 }
1608 
1609 
1610 ////////////////////////////////////////////////////////////////////////////////
1611 /// Return the number of free parameters
1612 
1614 {
1615  Int_t nfree = GetNpar();
1616  Double_t al,bl;
1617  for (Int_t i=0;i<nfree;i++) {
1618  ((TF1*)this)->GetParLimits(i,al,bl);
1619  if (al*bl != 0 && al >= bl) nfree--;
1620  }
1621  return nfree;
1622 }
1623 
1624 
1625 ////////////////////////////////////////////////////////////////////////////////
1626 /// Redefines TObject::GetObjectInfo.
1627 /// Displays the function info (x, function value)
1628 /// corresponding to cursor position px,py
1629 
1630 char *TF1::GetObjectInfo(Int_t px, Int_t /* py */) const
1631 {
1632  static char info[64];
1633  Double_t x = gPad->PadtoX(gPad->AbsPixeltoX(px));
1634  snprintf(info,64,"(x=%g, f=%g)",x,((TF1*)this)->Eval(x));
1635  return info;
1636 }
1637 
1638 
1639 ////////////////////////////////////////////////////////////////////////////////
1640 /// Return value of parameter number ipar
1641 
1643 {
1644  if (ipar < 0 || ipar > GetNpar()-1) return 0;
1645  return fParErrors[ipar];
1646 }
1647 
1648 
1649 ////////////////////////////////////////////////////////////////////////////////
1650 /// Return limits for parameter ipar.
1651 
1652 void TF1::GetParLimits(Int_t ipar, Double_t &parmin, Double_t &parmax) const
1653 {
1654  parmin = 0;
1655  parmax = 0;
1656  int n = fParMin.size();
1657  assert(n == int(fParMax.size()) && n <= fNpar);
1658  if (ipar < 0 || ipar > n-1) return;
1659  parmin = fParMin[ipar];
1660  parmax = fParMax[ipar];
1661 }
1662 
1663 
1664 ////////////////////////////////////////////////////////////////////////////////
1665 /// Return the fit probability
1666 
1668 {
1669  if (fNDF <= 0) return 0;
1670  return TMath::Prob(fChisquare,fNDF);
1671 }
1672 
1673 
1674 ////////////////////////////////////////////////////////////////////////////////
1675 /// Compute Quantiles for density distribution of this function
1676 ///
1677 /// Quantile x_q of a probability distribution Function F is defined as
1678 /// \f[
1679 /// F(x_{q}) = \int_{xmin}^{x_{q}} f dx = q with 0 <= q <= 1.
1680 /// \f]
1681 /// For instance the median \f$ x_{\frac{1}{2}} \f$ of a distribution is defined as that value
1682 /// of the random variable for which the distribution function equals 0.5:
1683 /// \f[
1684 /// F(x_{\frac{1}{2}}) = \prod(x < x_{\frac{1}{2}}) = \frac{1}{2}
1685 /// \f]
1686 ///
1687 /// \param[in] this TF1 function
1688 /// \param[in] nprobSum maximum size of array q and size of array probSum
1689 /// \param[in] probSum array of positions where quantiles will be computed.
1690 /// It is assumed to contain at least nprobSum values.
1691 /// \param[out] return value nq (<=nprobSum) with the number of quantiles computed
1692 /// \param[out] array q filled with nq quantiles
1693 ///
1694 /// Getting quantiles from two histograms and storing results in a TGraph,
1695 /// a so-called QQ-plot
1696 ///
1697 /// TGraph *gr = new TGraph(nprob);
1698 /// f1->GetQuantiles(nprob,gr->GetX());
1699 /// f2->GetQuantiles(nprob,gr->GetY());
1700 /// gr->Draw("alp");
1701 ///
1702 /// \author Eddy Offermann
1703 
1704 
1705 Int_t TF1::GetQuantiles(Int_t nprobSum, Double_t *q, const Double_t *probSum)
1706 {
1707  // LM: change to use fNpx
1708  // should we change code to use a root finder ?
1709  // It should be more precise and more efficient
1710  const Int_t npx = TMath::Max(fNpx, 2*nprobSum);
1711  const Double_t xMin = GetXmin();
1712  const Double_t xMax = GetXmax();
1713  const Double_t dx = (xMax-xMin)/npx;
1714 
1715  TArrayD integral(npx+1);
1716  TArrayD alpha(npx);
1717  TArrayD beta(npx);
1718  TArrayD gamma(npx);
1719 
1720  integral[0] = 0;
1721  Int_t intNegative = 0;
1722  Int_t i;
1723  for (i = 0; i < npx; i++) {
1724  Double_t integ = Integral(Double_t(xMin+i*dx),Double_t(xMin+i*dx+dx));
1725  if (integ < 0) {intNegative++; integ = -integ;}
1726  integral[i+1] = integral[i] + integ;
1727  }
1728 
1729  if (intNegative > 0)
1730  Warning("GetQuantiles","function:%s has %d negative values: abs assumed",
1731  GetName(),intNegative);
1732  if (integral[npx] == 0) {
1733  Error("GetQuantiles","Integral of function is zero");
1734  return 0;
1735  }
1736 
1737  const Double_t total = integral[npx];
1738  for (i = 1; i <= npx; i++) integral[i] /= total;
1739  //the integral r for each bin is approximated by a parabola
1740  // x = alpha + beta*r +gamma*r**2
1741  // compute the coefficients alpha, beta, gamma for each bin
1742  for (i = 0; i < npx; i++) {
1743  const Double_t x0 = xMin+dx*i;
1744  const Double_t r2 = integral[i+1]-integral[i];
1745  const Double_t r1 = Integral(x0,x0+0.5*dx)/total;
1746  gamma[i] = (2*r2-4*r1)/(dx*dx);
1747  beta[i] = r2/dx-gamma[i]*dx;
1748  alpha[i] = x0;
1749  gamma[i] *= 2;
1750  }
1751 
1752  // Be careful because of finite precision in the integral; Use the fact that the integral
1753  // is monotone increasing
1754  for (i = 0; i < nprobSum; i++) {
1755  const Double_t r = probSum[i];
1756  Int_t bin = TMath::Max(TMath::BinarySearch(npx+1,integral.GetArray(),r),(Long64_t)0);
1757  // LM use a tolerance 1.E-12 (integral precision)
1758  while (bin < npx-1 && TMath::AreEqualRel(integral[bin+1], r, 1E-12) ) {
1759  if (TMath::AreEqualRel(integral[bin+2], r, 1E-12) ) bin++;
1760  else break;
1761  }
1762 
1763  const Double_t rr = r-integral[bin];
1764  if (rr != 0.0) {
1765  Double_t xx = 0.0;
1766  const Double_t fac = -2.*gamma[bin]*rr/beta[bin]/beta[bin];
1767  if (fac != 0 && fac <= 1)
1768  xx = (-beta[bin]+TMath::Sqrt(beta[bin]*beta[bin]+2*gamma[bin]*rr))/gamma[bin];
1769  else if (beta[bin] != 0.)
1770  xx = rr/beta[bin];
1771  q[i] = alpha[bin]+xx;
1772  } else {
1773  q[i] = alpha[bin];
1774  if (integral[bin+1] == r) q[i] += dx;
1775  }
1776  }
1777 
1778  return nprobSum;
1779 }
1780 
1781 
1782 ////////////////////////////////////////////////////////////////////////////////
1783 /// Return a random number following this function shape
1784 ///
1785 /// The distribution contained in the function fname (TF1) is integrated
1786 /// over the channel contents.
1787 /// It is normalized to 1.
1788 /// For each bin the integral is approximated by a parabola.
1789 /// The parabola coefficients are stored as non persistent data members
1790 /// Getting one random number implies:
1791 /// - Generating a random number between 0 and 1 (say r1)
1792 /// - Look in which bin in the normalized integral r1 corresponds to
1793 /// - Evaluate the parabolic curve in the selected bin to find the corresponding X value.
1794 ///
1795 /// If the ratio fXmax/fXmin > fNpx the integral is tabulated in log scale in x
1796 /// The parabolic approximation is very good as soon as the number of bins is greater than 50.
1797 
1799 {
1800  // Check if integral array must be build
1801  if (fIntegral.size() == 0) {
1802  // fIntegral = new Double_t[fNpx+1];
1803  // fAlpha = new Double_t[fNpx+1];
1804  // fBeta = new Double_t[fNpx];
1805  // fGamma = new Double_t[fNpx];
1806  fIntegral.resize(fNpx+1);
1807  fAlpha.resize(fNpx+1);
1808  fBeta.resize(fNpx);
1809  fGamma.resize(fNpx);
1810  fIntegral[0] = 0;
1811  fAlpha[fNpx] = 0;
1812  Double_t integ;
1813  Int_t intNegative = 0;
1814  Int_t i;
1815  Bool_t logbin = kFALSE;
1816  Double_t dx;
1817  Double_t xmin = fXmin;
1818  Double_t xmax = fXmax;
1819  if (xmin > 0 && xmax/xmin> fNpx) {
1820  logbin = kTRUE;
1821  fAlpha[fNpx] = 1;
1822  xmin = TMath::Log10(fXmin);
1823  xmax = TMath::Log10(fXmax);
1824  }
1825  dx = (xmax-xmin)/fNpx;
1826 
1827  Double_t *xx = new Double_t[fNpx+1];
1828  for (i=0;i<fNpx;i++) {
1829  xx[i] = xmin +i*dx;
1830  }
1831  xx[fNpx] = xmax;
1832  for (i=0;i<fNpx;i++) {
1833  if (logbin) {
1834  integ = Integral(TMath::Power(10,xx[i]), TMath::Power(10,xx[i+1]));
1835  } else {
1836  integ = Integral(xx[i],xx[i+1]);
1837  }
1838  if (integ < 0) {intNegative++; integ = -integ;}
1839  fIntegral[i+1] = fIntegral[i] + integ;
1840  }
1841  if (intNegative > 0) {
1842  Warning("GetRandom","function:%s has %d negative values: abs assumed",GetName(),intNegative);
1843  }
1844  if (fIntegral[fNpx] == 0) {
1845  delete [] xx;
1846  Error("GetRandom","Integral of function is zero");
1847  return 0;
1848  }
1850  for (i=1;i<=fNpx;i++) { // normalize integral to 1
1851  fIntegral[i] /= total;
1852  }
1853  //the integral r for each bin is approximated by a parabola
1854  // x = alpha + beta*r +gamma*r**2
1855  // compute the coefficients alpha, beta, gamma for each bin
1856  Double_t x0,r1,r2,r3;
1857  for (i=0;i<fNpx;i++) {
1858  x0 = xx[i];
1859  r2 = fIntegral[i+1] - fIntegral[i];
1860  if (logbin) r1 = Integral(TMath::Power(10,x0),TMath::Power(10,x0+0.5*dx))/total;
1861  else r1 = Integral(x0,x0+0.5*dx)/total;
1862  r3 = 2*r2 - 4*r1;
1863  if (TMath::Abs(r3) > 1e-8) fGamma[i] = r3/(dx*dx);
1864  else fGamma[i] = 0;
1865  fBeta[i] = r2/dx - fGamma[i]*dx;
1866  fAlpha[i] = x0;
1867  fGamma[i] *= 2;
1868  }
1869  delete [] xx;
1870  }
1871 
1872  // return random number
1873  Double_t r = gRandom->Rndm();
1874  Int_t bin = TMath::BinarySearch(fNpx,fIntegral.data(),r);
1875  Double_t rr = r - fIntegral[bin];
1876 
1877  Double_t yy;
1878  if(fGamma[bin] != 0)
1879  yy = (-fBeta[bin] + TMath::Sqrt(fBeta[bin]*fBeta[bin]+2*fGamma[bin]*rr))/fGamma[bin];
1880  else
1881  yy = rr/fBeta[bin];
1882  Double_t x = fAlpha[bin] + yy;
1883  if (fAlpha[fNpx] > 0) return TMath::Power(10,x);
1884  return x;
1885 }
1886 
1887 
1888 ////////////////////////////////////////////////////////////////////////////////
1889 /// Return a random number following this function shape in [xmin,xmax]
1890 ///
1891 /// The distribution contained in the function fname (TF1) is integrated
1892 /// over the channel contents.
1893 /// It is normalized to 1.
1894 /// For each bin the integral is approximated by a parabola.
1895 /// The parabola coefficients are stored as non persistent data members
1896 /// Getting one random number implies:
1897 /// - Generating a random number between 0 and 1 (say r1)
1898 /// - Look in which bin in the normalized integral r1 corresponds to
1899 /// - Evaluate the parabolic curve in the selected bin to find
1900 /// the corresponding X value.
1901 ///
1902 /// The parabolic approximation is very good as soon as the number
1903 /// of bins is greater than 50.
1904 ///
1905 /// IMPORTANT NOTE
1906 ///
1907 /// The integral of the function is computed at fNpx points. If the function
1908 /// has sharp peaks, you should increase the number of points (SetNpx)
1909 /// such that the peak is correctly tabulated at several points.
1910 
1912 {
1913  // Check if integral array must be build
1914  if (fIntegral.size() == 0) {
1915  // fIntegral = new Double_t[fNpx+1];
1916  // fAlpha = new Double_t[fNpx+1];
1917  // fBeta = new Double_t[fNpx];
1918  // fGamma = new Double_t[fNpx];
1919  fIntegral.resize(fNpx+1);
1920  fAlpha.resize(fNpx);
1921  fBeta.resize(fNpx);
1922  fGamma.resize(fNpx);
1923 
1924  Double_t dx = (fXmax-fXmin)/fNpx;
1925  Double_t integ;
1926  Int_t intNegative = 0;
1927  Int_t i;
1928  for (i=0;i<fNpx;i++) {
1929  integ = Integral(Double_t(fXmin+i*dx), Double_t(fXmin+i*dx+dx));
1930  if (integ < 0) {intNegative++; integ = -integ;}
1931  fIntegral[i+1] = fIntegral[i] + integ;
1932  }
1933  if (intNegative > 0) {
1934  Warning("GetRandom","function:%s has %d negative values: abs assumed",GetName(),intNegative);
1935  }
1936  if (fIntegral[fNpx] == 0) {
1937  Error("GetRandom","Integral of function is zero");
1938  return 0;
1939  }
1941  for (i=1;i<=fNpx;i++) { // normalize integral to 1
1942  fIntegral[i] /= total;
1943  }
1944  //the integral r for each bin is approximated by a parabola
1945  // x = alpha + beta*r +gamma*r**2
1946  // compute the coefficients alpha, beta, gamma for each bin
1947  Double_t x0,r1,r2,r3;
1948  for (i=0;i<fNpx;i++) {
1949  x0 = fXmin+i*dx;
1950  r2 = fIntegral[i+1] - fIntegral[i];
1951  r1 = Integral(x0,x0+0.5*dx)/total;
1952  r3 = 2*r2 - 4*r1;
1953  if (TMath::Abs(r3) > 1e-8) fGamma[i] = r3/(dx*dx);
1954  else fGamma[i] = 0;
1955  fBeta[i] = r2/dx - fGamma[i]*dx;
1956  fAlpha[i] = x0;
1957  fGamma[i] *= 2;
1958  }
1959  }
1960 
1961  // return random number
1962  Double_t dx = (fXmax-fXmin)/fNpx;
1963  Int_t nbinmin = (Int_t)((xmin-fXmin)/dx);
1964  Int_t nbinmax = (Int_t)((xmax-fXmin)/dx)+2;
1965  if(nbinmax>fNpx) nbinmax=fNpx;
1966 
1967  Double_t pmin=fIntegral[nbinmin];
1968  Double_t pmax=fIntegral[nbinmax];
1969 
1970  Double_t r,x,xx,rr;
1971  do {
1972  r = gRandom->Uniform(pmin,pmax);
1973 
1974  Int_t bin = TMath::BinarySearch(fNpx,fIntegral.data(),r);
1975  rr = r - fIntegral[bin];
1976 
1977  if(fGamma[bin] != 0)
1978  xx = (-fBeta[bin] + TMath::Sqrt(fBeta[bin]*fBeta[bin]+2*fGamma[bin]*rr))/fGamma[bin];
1979  else
1980  xx = rr/fBeta[bin];
1981  x = fAlpha[bin] + xx;
1982  } while(x<xmin || x>xmax);
1983  return x;
1984 }
1985 
1986 ////////////////////////////////////////////////////////////////////////////////
1987 /// Return range of a generic N-D function.
1988 
1989 void TF1::GetRange(Double_t *rmin, Double_t *rmax) const
1990 {
1991  int ndim = GetNdim();
1992 
1993  double xmin = 0, ymin = 0, zmin = 0, xmax = 0, ymax = 0, zmax = 0;
1994  GetRange(xmin, ymin, zmin, xmax, ymax, zmax);
1995  for (int i = 0; i < ndim; ++i) {
1996  if (i == 0) {
1997  rmin[0] = xmin; rmax[0] = xmax;
1998  }
1999  else if (i == 1) {
2000  rmin[1] = ymin; rmax[1] = ymax;
2001  }
2002  else if (i == 2) {
2003  rmin[2] = zmin; rmax[2] = zmax;
2004  }
2005  else {
2006  rmin[i] = 0;
2007  rmax[i] = 0;
2008  }
2009  }
2010 }
2011 
2012 
2013 ////////////////////////////////////////////////////////////////////////////////
2014 /// Return range of a 1-D function.
2015 
2017 {
2018  xmin = fXmin;
2019  xmax = fXmax;
2020 }
2021 
2022 
2023 ////////////////////////////////////////////////////////////////////////////////
2024 /// Return range of a 2-D function.
2025 
2027 {
2028  xmin = fXmin;
2029  xmax = fXmax;
2030  ymin = 0;
2031  ymax = 0;
2032 }
2033 
2034 
2035 ////////////////////////////////////////////////////////////////////////////////
2036 /// Return range of function.
2037 
2039 {
2040  xmin = fXmin;
2041  xmax = fXmax;
2042  ymin = 0;
2043  ymax = 0;
2044  zmin = 0;
2045  zmax = 0;
2046 }
2047 
2048 
2049 ////////////////////////////////////////////////////////////////////////////////
2050 /// Get value corresponding to X in array of fSave values
2051 
2053 {
2054  if (fSave.size() == 0) return 0;
2055  //if (fSave == 0) return 0;
2056  int fNsave = fSave.size();
2057  Double_t x = Double_t(xx[0]);
2058  Double_t y,dx,xmin,xmax,xlow,xup,ylow,yup;
2059  if (fParent && fParent->InheritsFrom(TH1::Class())) {
2060  //if parent is a histogram the function had been saved at the center of the bins
2061  //we make a linear interpolation between the saved values
2062  xmin = fSave[fNsave-3];
2063  xmax = fSave[fNsave-2];
2064  if (fSave[fNsave-1] == xmax) {
2065  TH1 *h = (TH1*)fParent;
2066  TAxis *xaxis = h->GetXaxis();
2067  Int_t bin1 = xaxis->FindBin(xmin);
2068  Int_t binup = xaxis->FindBin(xmax);
2069  Int_t bin = xaxis->FindBin(x);
2070  if (bin < binup) {
2071  xlow = xaxis->GetBinCenter(bin);
2072  xup = xaxis->GetBinCenter(bin+1);
2073  ylow = fSave[bin-bin1];
2074  yup = fSave[bin-bin1+1];
2075  } else {
2076  xlow = xaxis->GetBinCenter(bin-1);
2077  xup = xaxis->GetBinCenter(bin);
2078  ylow = fSave[bin-bin1-1];
2079  yup = fSave[bin-bin1];
2080  }
2081  dx = xup-xlow;
2082  y = ((xup*ylow-xlow*yup) + x*(yup-ylow))/dx;
2083  return y;
2084  }
2085  }
2086  Int_t np = fNsave - 3;
2087  xmin = Double_t(fSave[np+1]);
2088  xmax = Double_t(fSave[np+2]);
2089  dx = (xmax-xmin)/np;
2090  if (x < xmin || x > xmax) return 0;
2091  // return a Nan in case of x=nan, otherwise will crash later
2092  if (TMath::IsNaN(x) ) return x;
2093  if (dx <= 0) return 0;
2094 
2095  Int_t bin = Int_t((x-xmin)/dx);
2096  xlow = xmin + bin*dx;
2097  xup = xlow + dx;
2098  ylow = fSave[bin];
2099  yup = fSave[bin+1];
2100  y = ((xup*ylow-xlow*yup) + x*(yup-ylow))/dx;
2101  return y;
2102 }
2103 
2104 
2105 ////////////////////////////////////////////////////////////////////////////////
2106 /// Get x axis of the function.
2107 
2109 {
2110  TH1 *h = GetHistogram();
2111  if (!h) return 0;
2112  return h->GetXaxis();
2113 }
2114 
2115 
2116 ////////////////////////////////////////////////////////////////////////////////
2117 /// Get y axis of the function.
2118 
2120 {
2121  TH1 *h = GetHistogram();
2122  if (!h) return 0;
2123  return h->GetYaxis();
2124 }
2125 
2126 
2127 ////////////////////////////////////////////////////////////////////////////////
2128 /// Get z axis of the function. (In case this object is a TF2 or TF3)
2129 
2131 {
2132  TH1 *h = GetHistogram();
2133  if (!h) return 0;
2134  return h->GetZaxis();
2135 }
2136 
2137 
2138 
2139 ////////////////////////////////////////////////////////////////////////////////
2140 /// Compute the gradient (derivative) wrt a parameter ipar
2141 ///
2142 /// \param ipar index of parameter for which the derivative is computed
2143 /// \param x point, where the derivative is computed
2144 /// \param eps - if the errors of parameters have been computed, the step used in
2145 /// numerical differentiation is eps*parameter_error.
2146 ///
2147 /// if the errors have not been computed, step=eps is used
2148 /// default value of eps = 0.01
2149 /// Method is the same as in Derivative() function
2150 ///
2151 /// If a parameter is fixed, the gradient on this parameter = 0
2152 
2154 {
2155  if (GetNpar() == 0) return 0;
2156 
2157  if(eps< 1e-10 || eps > 1) {
2158  Warning("Derivative","parameter esp=%g out of allowed range[1e-10,1], reset to 0.01",eps);
2159  eps = 0.01;
2160  }
2161  Double_t h;
2162  Double_t *parameters = GetParameters();
2163  TF1 *func = (TF1*)this;
2164  //save original parameters
2165  Double_t par0 = parameters[ipar];
2166 
2167 
2168  func->InitArgs(x, parameters);
2169 
2170  Double_t al, bl;
2171  Double_t f1, f2, g1, g2, h2, d0, d2;
2172 
2173  ((TF1*)this)->GetParLimits(ipar,al,bl);
2174  if (al*bl != 0 && al >= bl) {
2175  //this parameter is fixed
2176  return 0;
2177  }
2178 
2179  // check if error has been computer (is not zero)
2180  if (func->GetParError(ipar)!=0)
2181  h = eps*func->GetParError(ipar);
2182  else
2183  h=eps;
2184 
2185 
2186 
2187  parameters[ipar] = par0 + h; f1 = func->EvalPar(x,parameters);
2188  parameters[ipar] = par0 - h; f2 = func->EvalPar(x,parameters);
2189  parameters[ipar] = par0 + h/2; g1 = func->EvalPar(x,parameters);
2190  parameters[ipar] = par0 - h/2; g2 = func->EvalPar(x,parameters);
2191 
2192  //compute the central differences
2193  h2 = 1/(2.*h);
2194  d0 = f1 - f2;
2195  d2 = 2*(g1 - g2);
2196 
2197  Double_t grad = h2*(4*d2 - d0)/3.;
2198 
2199  // restore original value
2200  parameters[ipar] = par0;
2201 
2202  return grad;
2203 }
2204 
2205 ////////////////////////////////////////////////////////////////////////////////
2206 /// Compute the gradient wrt parameters
2207 ///
2208 /// \param x point, were the gradient is computed
2209 /// \param grad used to return the computed gradient, assumed to be of at least fNpar size
2210 /// \param eps if the errors of parameters have been computed, the step used in
2211 /// numerical differentiation is eps*parameter_error.
2212 ///
2213 /// if the errors have not been computed, step=eps is used
2214 /// default value of eps = 0.01
2215 /// Method is the same as in Derivative() function
2216 ///
2217 /// If a parameter is fixed, the gradient on this parameter = 0
2218 
2219 void TF1::GradientPar(const Double_t *x, Double_t *grad, Double_t eps)
2220 {
2221  if(eps< 1e-10 || eps > 1) {
2222  Warning("Derivative","parameter esp=%g out of allowed range[1e-10,1], reset to 0.01",eps);
2223  eps = 0.01;
2224  }
2225 
2226  for (Int_t ipar=0; ipar< GetNpar(); ipar++){
2227  grad[ipar] = GradientPar(ipar,x,eps);
2228  }
2229 }
2230 
2231 ////////////////////////////////////////////////////////////////////////////////
2232 /// Initialize parameters addresses.
2233 
2234 void TF1::InitArgs(const Double_t *x, const Double_t *params)
2235 {
2236  if (fMethodCall) {
2237  Long_t args[2];
2238  args[0] = (Long_t)x;
2239  if (params) args[1] = (Long_t)params;
2240  else args[1] = (Long_t)GetParameters();
2241  fMethodCall->SetParamPtrs(args);
2242  }
2243 }
2244 
2245 
2246 ////////////////////////////////////////////////////////////////////////////////
2247 /// Create the basic function objects
2248 
2250 {
2251  TF1 *f1;
2253  if (!gROOT->GetListOfFunctions()->FindObject("gaus")) {
2254  f1 = new TF1("gaus","gaus",-1,1); f1->SetParameters(1,0,1);
2255  f1 = new TF1("gausn","gausn",-1,1); f1->SetParameters(1,0,1);
2256  f1 = new TF1("landau","landau",-1,1); f1->SetParameters(1,0,1);
2257  f1 = new TF1("landaun","landaun",-1,1); f1->SetParameters(1,0,1);
2258  f1 = new TF1("expo","expo",-1,1); f1->SetParameters(1,1);
2259  for (Int_t i=0;i<10;i++) {
2260  f1 = new TF1(Form("pol%d",i),Form("pol%d",i),-1,1);
2261  f1->SetParameters(1,1,1,1,1,1,1,1,1,1);
2262  // create also chebyshev polynomial
2263  // (note polynomial object will not be deleted)
2264  // note that these functions cannot be stored
2266  Double_t min = -1;
2267  Double_t max = 1;
2268  f1 = new TF1(TString::Format("chebyshev%d",i),pol,min,max,i+1,1);
2269  f1->SetParameters(1,1,1,1,1,1,1,1,1,1);
2270  }
2271 
2272  }
2273 }
2274 ////////////////////////////////////////////////////////////////////////////////
2275 /// IntegralOneDim or analytical integral
2276 
2278 {
2279  Double_t error = 0;
2280  if (GetNumber() > 0)
2281  {
2282  Double_t result = 0.;
2283  if (gDebug) {
2284  Info("computing analytical integral for function %s with number %d",GetName(), GetNumber() );
2285  }
2286  result = AnalyticalIntegral(this, a, b);
2287  // if it is a formula that havent been implemented in analytical integral a NaN is return
2288  if (!TMath::IsNaN(result)) return result;
2289  if (gDebug)
2290  Warning("analytical integral not available for %s - with number %d compute numerical integral",GetName(),GetNumber());
2291  }
2292  return IntegralOneDim(a,b, epsrel, epsrel, error);
2293 }
2294 
2295 ////////////////////////////////////////////////////////////////////////////////
2296 /// Return Integral of function between a and b using the given parameter values and
2297 /// relative and absolute tolerance.
2298 ///
2299 /// The default integrator defined in ROOT::Math::IntegratorOneDimOptions::DefaultIntegrator() is used
2300 /// If ROOT contains the MathMore library the default integrator is set to be
2301 /// the adaptive ROOT::Math::GSLIntegrator (based on QUADPACK) or otherwise the
2302 /// ROOT::Math::GaussIntegrator is used
2303 /// See the reference documentation of these classes for more information about the
2304 /// integration algorithms
2305 /// To change integration algorithm just do :
2306 /// ROOT::Math::IntegratorOneDimOptions::SetDefaultIntegrator(IntegratorName);
2307 /// Valid integrator names are:
2308 /// - Gauss : for ROOT::Math::GaussIntegrator
2309 /// - GaussLegendre : for ROOT::Math::GaussLegendreIntegrator
2310 /// - Adaptive : for ROOT::Math::GSLIntegrator adaptive method (QAG)
2311 /// - AdaptiveSingular : for ROOT::Math::GSLIntegrator adaptive singular method (QAGS)
2312 /// - NonAdaptive : for ROOT::Math::GSLIntegrator non adaptive (QNG)
2313 ///
2314 /// In order to use the GSL integrators one needs to have the MathMore library installed
2315 ///
2316 /// Note 1:
2317 ///
2318 /// Values of the function f(x) at the interval end-points A and B are not
2319 /// required. The subprogram may therefore be used when these values are
2320 /// undefined.
2321 ///
2322 /// Note 2:
2323 ///
2324 /// Instead of TF1::Integral, you may want to use the combination of
2325 /// TF1::CalcGaussLegendreSamplingPoints and TF1::IntegralFast.
2326 /// See an example with the following script:
2327 ///
2328 /// ~~~ {.cpp}
2329 /// void gint() {
2330 /// TF1 *g = new TF1("g","gaus",-5,5);
2331 /// g->SetParameters(1,0,1);
2332 /// //default gaus integration method uses 6 points
2333 /// //not suitable to integrate on a large domain
2334 /// double r1 = g->Integral(0,5);
2335 /// double r2 = g->Integral(0,1000);
2336 ///
2337 /// //try with user directives computing more points
2338 /// Int_t np = 1000;
2339 /// double *x=new double[np];
2340 /// double *w=new double[np];
2341 /// g->CalcGaussLegendreSamplingPoints(np,x,w,1e-15);
2342 /// double r3 = g->IntegralFast(np,x,w,0,5);
2343 /// double r4 = g->IntegralFast(np,x,w,0,1000);
2344 /// double r5 = g->IntegralFast(np,x,w,0,10000);
2345 /// double r6 = g->IntegralFast(np,x,w,0,100000);
2346 /// printf("g->Integral(0,5) = %g\n",r1);
2347 /// printf("g->Integral(0,1000) = %g\n",r2);
2348 /// printf("g->IntegralFast(n,x,w,0,5) = %g\n",r3);
2349 /// printf("g->IntegralFast(n,x,w,0,1000) = %g\n",r4);
2350 /// printf("g->IntegralFast(n,x,w,0,10000) = %g\n",r5);
2351 /// printf("g->IntegralFast(n,x,w,0,100000)= %g\n",r6);
2352 /// delete [] x;
2353 /// delete [] w;
2354 /// }
2355 /// ~~~
2356 ///
2357 /// This example produces the following results:
2358 ///
2359 /// ~~~ {.cpp}
2360 /// g->Integral(0,5) = 1.25331
2361 /// g->Integral(0,1000) = 1.25319
2362 /// g->IntegralFast(n,x,w,0,5) = 1.25331
2363 /// g->IntegralFast(n,x,w,0,1000) = 1.25331
2364 /// g->IntegralFast(n,x,w,0,10000) = 1.25331
2365 /// g->IntegralFast(n,x,w,0,100000)= 1.253
2366 /// ~~~
2367 
2369 {
2370  //Double_t *parameters = GetParameters();
2371  TF1_EvalWrapper wf1( this, 0, fgAbsValue );
2372  Double_t result = 0;
2373  Int_t status = 0;
2375  ROOT::Math::GaussIntegrator iod(epsabs, epsrel);
2376  iod.SetFunction(wf1);
2377  if (a != - TMath::Infinity() && b != TMath::Infinity() )
2378  result = iod.Integral(a, b);
2379  else if (a == - TMath::Infinity() && b != TMath::Infinity() )
2380  result = iod.IntegralLow(b);
2381  else if (a != - TMath::Infinity() && b == TMath::Infinity() )
2382  result = iod.IntegralUp(a);
2383  else if (a == - TMath::Infinity() && b == TMath::Infinity() )
2384  result = iod.Integral();
2385  error = iod.Error();
2386  status = iod.Status();
2387  }
2388  else {
2390  if (a != - TMath::Infinity() && b != TMath::Infinity() )
2391  result = iod.Integral(a, b);
2392  else if (a == - TMath::Infinity() && b != TMath::Infinity() )
2393  result = iod.IntegralLow(b);
2394  else if (a != - TMath::Infinity() && b == TMath::Infinity() )
2395  result = iod.IntegralUp(a);
2396  else if (a == - TMath::Infinity() && b == TMath::Infinity() )
2397  result = iod.Integral();
2398  error = iod.Error();
2399  status = iod.Status();
2400  }
2401  if (status != 0) {
2403  Warning("IntegralOneDim","Error found in integrating function %s in [%f,%f] using %s. Result = %f +/- %f - status = %d",GetName(),a,b,igName.c_str(),result,error,status);
2404  TString msg("\t\tFunction Parameters = {");
2405  for (int ipar = 0; ipar < GetNpar(); ++ipar) {
2406  msg += TString::Format(" %s = %f ",GetParName(ipar), GetParameter(ipar));
2407  if (ipar < GetNpar()-1) msg += TString(",");
2408  else msg += TString("}");
2409  }
2410  Info("IntegralOneDim","%s",msg.Data());
2411  }
2412  return result;
2413 }
2414 
2415 
2416 //______________________________________________________________________________
2417 // Double_t TF1::Integral(Double_t, Double_t, Double_t, Double_t, Double_t, Double_t)
2418 // {
2419 // // Return Integral of a 2d function in range [ax,bx],[ay,by]
2420 
2421 // Error("Integral","Must be called with a TF2 only");
2422 // return 0;
2423 // }
2424 
2425 
2426 // //______________________________________________________________________________
2427 // Double_t TF1::Integral(Double_t, Double_t, Double_t, Double_t, Double_t, Double_t, Double_t, Double_t)
2428 // {
2429 // // Return Integral of a 3d function in range [ax,bx],[ay,by],[az,bz]
2430 
2431 // Error("Integral","Must be called with a TF3 only");
2432 // return 0;
2433 // }
2434 
2435 ////////////////////////////////////////////////////////////////////////////////
2436 /// Return Error on Integral of a parametric function between a and b
2437 /// due to the parameter uncertainties.
2438 /// A pointer to a vector of parameter values and to the elements of the covariance matrix (covmat)
2439 /// can be optionally passed. By default (i.e. when a zero pointer is passed) the current stored
2440 /// parameter values are used to estimate the integral error together with the covariance matrix
2441 /// from the last fit (retrieved from the global fitter instance)
2442 ///
2443 /// IMPORTANT NOTE1:
2444 ///
2445 /// When no covariance matrix is passed and in the meantime a fit is done
2446 /// using another function, the routine will signal an error and it will return zero only
2447 /// when the number of fit parameter is different than the values stored in TF1 (TF1::GetNpar() ).
2448 /// In the case that npar is the same, an incorrect result is returned.
2449 ///
2450 /// IMPORTANT NOTE2:
2451 ///
2452 /// The user must pass a pointer to the elements of the full covariance matrix
2453 /// dimensioned with the right size (npar*npar), where npar is the total number of parameters (TF1::GetNpar()),
2454 /// including also the fixed parameters. When there are fixed parameters, the pointer returned from
2455 /// TVirtualFitter::GetCovarianceMatrix() cannot be used.
2456 /// One should use the TFitResult class, as shown in the example below.
2457 ///
2458 /// To get the matrix and values from an old fit do for example:
2459 /// TFitResultPtr r = histo->Fit(func, "S");
2460 /// ..... after performing other fits on the same function do
2461 ///
2462 /// func->IntegralError(x1,x2,r->GetParams(), r->GetCovarianceMatrix()->GetMatrixArray() );
2463 
2465 {
2466  Double_t x1[1];
2467  Double_t x2[1];
2468  x1[0] = a, x2[0] = b;
2469  return ROOT::TF1Helper::IntegralError(this,1,x1,x2,params,covmat,epsilon);
2470 }
2471 
2472 ////////////////////////////////////////////////////////////////////////////////
2473 /// Return Error on Integral of a parametric function with dimension larger tan one
2474 /// between a[] and b[] due to the parameters uncertainties.
2475 /// For a TF1 with dimension larger than 1 (for example a TF2 or TF3)
2476 /// TF1::IntegralMultiple is used for the integral calculation
2477 ///
2478 /// A pointer to a vector of parameter values and to the elements of the covariance matrix (covmat) can be optionally passed.
2479 /// By default (i.e. when a zero pointer is passed) the current stored parameter values are used to estimate the integral error
2480 /// together with the covariance matrix from the last fit (retrieved from the global fitter instance).
2481 ///
2482 /// IMPORTANT NOTE1:
2483 ///
2484 /// When no covariance matrix is passed and in the meantime a fit is done
2485 /// using another function, the routine will signal an error and it will return zero only
2486 /// when the number of fit parameter is different than the values stored in TF1 (TF1::GetNpar() ).
2487 /// In the case that npar is the same, an incorrect result is returned.
2488 ///
2489 /// IMPORTANT NOTE2:
2490 ///
2491 /// The user must pass a pointer to the elements of the full covariance matrix
2492 /// dimensioned with the right size (npar*npar), where npar is the total number of parameters (TF1::GetNpar()),
2493 /// including also the fixed parameters. When there are fixed parameters, the pointer returned from
2494 /// TVirtualFitter::GetCovarianceMatrix() cannot be used.
2495 /// One should use the TFitResult class, as shown in the example below.
2496 ///
2497 /// To get the matrix and values from an old fit do for example:
2498 /// TFitResultPtr r = histo->Fit(func, "S");
2499 /// ..... after performing other fits on the same function do
2500 ///
2501 /// func->IntegralError(x1,x2,r->GetParams(), r->GetCovarianceMatrix()->GetMatrixArray() );
2502 
2503 Double_t TF1::IntegralError(Int_t n, const Double_t * a, const Double_t * b, const Double_t * params, const Double_t * covmat, Double_t epsilon )
2504 {
2505  return ROOT::TF1Helper::IntegralError(this,n,a,b,params,covmat,epsilon);
2506 }
2507 
2508 #ifdef INTHEFUTURE
2509 ////////////////////////////////////////////////////////////////////////////////
2510 /// Gauss-Legendre integral, see CalcGaussLegendreSamplingPoints
2511 
2513 {
2514  if (!g) return 0;
2515  return IntegralFast(g->GetN(), g->GetX(), g->GetY(), a, b, params);
2516 }
2517 #endif
2518 
2519 
2520 ////////////////////////////////////////////////////////////////////////////////
2521 /// Gauss-Legendre integral, see CalcGaussLegendreSamplingPoints
2522 
2524 {
2525  // Now x and w are not used!
2526 
2527  ROOT::Math::WrappedTF1 wf1(*this);
2528  if ( params )
2529  wf1.SetParameters( params );
2530  ROOT::Math::GaussLegendreIntegrator gli(num,epsilon);
2531  gli.SetFunction( wf1 );
2532  return gli.Integral(a, b);
2533 
2534 }
2535 
2536 
2537 ////////////////////////////////////////////////////////////////////////////////
2538 /// See more general prototype below.
2539 /// This interface kept for back compatibility
2540 /// It is recommended to use the other interface where one can specify also epsabs and the maximum number of
2541 /// points
2542 
2544 {
2545  Int_t nfnevl,ifail;
2546  Int_t maxpts = TMath::Min( Int_t( 20*TMath::Power(fNpx,GetNdim())), 10000000);
2547  Double_t result = IntegralMultiple(n,a,b,maxpts,epsrel,epsrel,relerr,nfnevl,ifail);
2548  if (ifail > 0) {
2549  Warning("IntegralMultiple","failed code=%d, ",ifail);
2550  }
2551  return result;
2552 }
2553 
2554 
2555 ////////////////////////////////////////////////////////////////////////////////
2556 /// This function computes, to an attempted specified accuracy, the value of
2557 /// the integral
2558 ///
2559 /// \param[in] n Number of dimensions [2,15]
2560 /// \param[in] a,b One-dimensional arrays of length >= N . On entry A[i], and B[i],
2561 /// contain the lower and upper limits of integration, respectively.
2562 /// \param[in] maxpts Maximum number of function evaluations to be allowed.
2563 /// maxpts >= 2^n +2*n*(n+1) +1
2564 /// if maxpts<minpts, maxpts is set to 10*minpts
2565 /// \param[in] epsrel Specified relative accuracy.
2566 /// \param[in] epsabs Specified absolute accuracy.
2567 /// The integration algorithm will attempt to reach either the relative or the absolute accuracy.
2568 /// In case the maximum function called is reached the algorithm will stop earlier without having reached
2569 /// the desired accuracy
2570 ///
2571 /// \param[out] relerr Contains, on exit, an estimation of the relative accuracy of the result.
2572 /// \param[out] nfnevl number of function evaluations performed.
2573 /// \param[out] ifail
2574 /// \parblock
2575 /// 0 Normal exit. At least minpts and at most maxpts calls to the function were performed.
2576 ///
2577 /// 1 maxpts is too small for the specified accuracy eps. The result and relerr contain the values obtainable for the
2578 /// specified value of maxpts.
2579 ///
2580 /// 3 n<2 or n>15
2581 /// \endparblock
2582 ///
2583 /// Method:
2584 ///
2585 /// The default method used is the Genz-Mallik adaptive multidimensional algorithm
2586 /// using the class ROOT::Math::AdaptiveIntegratorMultiDim (see the reference documentation of the class)
2587 ///
2588 /// Other methods can be used by setting ROOT::Math::IntegratorMultiDimOptions::SetDefaultIntegrator()
2589 /// to different integrators.
2590 /// Other possible integrators are MC integrators based on the ROOT::Math::GSLMCIntegrator class
2591 /// Possible methods are : Vegas, Miser or Plain
2592 /// IN case of MC integration the accuracy is determined by the number of function calls, one should be
2593 /// careful not to use a too large value of maxpts
2594 ///
2595 
2596 Double_t TF1::IntegralMultiple(Int_t n, const Double_t *a, const Double_t *b, Int_t maxpts, Double_t epsrel, Double_t epsabs, Double_t &relerr,Int_t &nfnevl, Int_t &ifail)
2597 {
2599 
2600  double result = 0;
2602  ROOT::Math::AdaptiveIntegratorMultiDim aimd(wf1, epsabs, epsrel, maxpts);
2603  //aimd.SetMinPts(minpts); // use default minpts ( n^2 + 2 * n * (n+1) +1 )
2604  result = aimd.Integral(a,b);
2605  relerr = aimd.RelError();
2606  nfnevl = aimd.NEval();
2607  ifail = aimd.Status();
2608  }
2609  else {
2610  // use default abs tolerance = relative tolerance
2612  result = imd.Integral(a,b);
2613  relerr = (result != 0) ? imd.Error()/ std::abs(result) : imd.Error();
2614  nfnevl = 0;
2615  ifail = imd.Status();
2616  }
2617 
2618 
2619  return result;
2620 }
2621 
2622 
2623 ////////////////////////////////////////////////////////////////////////////////
2624 /// Return kTRUE if the function is valid
2625 
2627 {
2628  if (fFormula) return fFormula->IsValid();
2629  if (fMethodCall) return fMethodCall->IsValid();
2630  // function built on compiled functors are always valid by definition
2631  // (checked at compiled time)
2632  if (fFunctor.Empty() && fSave.empty()) return kFALSE;
2633  return kTRUE;
2634 }
2635 
2636 
2637 //______________________________________________________________________________
2638 
2639 
2640 void TF1::Print(Option_t *option) const
2641 {
2642  if (fType == 0) {
2643  printf("Formula based function: %s \n",GetName());
2644  assert(fFormula);
2645  fFormula->Print(option);
2646  }
2647  else if (fType > 0) {
2648  if (fType == 2)
2649  printf("Interpreted based function: %s(double *x, double *p). Ndim = %d, Npar = %d \n",GetName(), GetNpar(), GetNdim());
2650  else {
2651  if (!fFunctor.Empty())
2652  printf("Compiled based function: %s based on a functor object. Ndim = %d, Npar = %d\n",GetName(),GetNpar(), GetNdim());
2653  else {
2654  printf("Function based on a list of points from a compiled based function: %s. Ndim = %d, Npar = %d, Npx = %d\n",GetName(),GetNpar(), GetNdim(),int(fSave.size()));
2655  if (fSave.empty() )
2656  Warning("Print","Function %s is based on a list of points but list is empty",GetName());
2657  }
2658  }
2659  TString opt(option);
2660  opt.ToUpper();
2661  if (opt.Contains("V") ) {
2662  // print list of parameters
2663  if (fNpar > 0) {
2664  printf("List of Parameters: \n");
2665  for ( int i = 0; i < fNpar; ++i)
2666  printf(" %20s = %10f \n",GetParName(i), GetParameter(i) );
2667  }
2668  if (!fSave.empty() ) {
2669  // print list of saved points
2670  printf("List of Saved points (N=%d): \n",int(fSave.size()));
2671  for ( auto & x : fSave)
2672  printf("( %10f ) ",x);
2673  printf("\n");
2674  }
2675  }
2676  }
2677  if (fHistogram) {
2678  printf("Contained histogram\n");
2679  fHistogram->Print(option);
2680  }
2681 }
2682 
2683 ////////////////////////////////////////////////////////////////////////////////
2684 /// Paint this function with its current attributes.
2685 /// The function is going to be converted in an histogram and the corresponding
2686 /// histogram is painted.
2687 /// The painted histogram can be retrieved calling afterwards the method TF1::GetHistogram()
2688 
2689 void TF1::Paint(Option_t *option)
2690 {
2691  fgCurrent = this;
2692 
2693  TString opt = option;
2694  opt.ToLower();
2695  Bool_t optSAME = kFALSE;
2696  if (opt.Contains("same")) optSAME = kTRUE;
2697 
2698  Double_t xmin=fXmin, xmax=fXmax, pmin=fXmin, pmax=fXmax;
2699  if (gPad) {
2700  pmin = gPad->PadtoX(gPad->GetUxmin());
2701  pmax = gPad->PadtoX(gPad->GetUxmax());
2702  }
2703  if (optSAME) {
2704  if (xmax < pmin) return; // Completely outside.
2705  if (xmin > pmax) return;
2706  if (xmin < pmin) xmin = pmin;
2707  if (xmax > pmax) xmax = pmax;
2708  }
2709 
2710  // create an histogram using the function content (re-use it if already existing)
2711  fHistogram = DoCreateHistogram(xmin, xmax, kFALSE);
2712 
2713  // set the optimal minimum and maximum
2714  Double_t minimum = fHistogram->GetMinimumStored();
2715  Double_t maximum = fHistogram->GetMaximumStored();
2716  if (minimum <= 0 && gPad && gPad->GetLogy()) minimum = -1111; // This can happen when switching from lin to log scale.
2717  if (gPad && gPad->GetUymin() < fHistogram->GetMinimum() &&
2718  !fHistogram->TestBit(TH1::kIsZoomed)) minimum = -1111; // This can happen after unzooming a fit.
2719  if (minimum == -1111) { // This can happen after unzooming.
2721  minimum = fHistogram->GetYaxis()->GetXmin();
2722  } else {
2723  minimum = fMinimum;
2724  // Optimize the computation of the scale in Y in case the min/max of the
2725  // function oscillate around a constant value
2726  if (minimum == -1111) {
2727  Double_t hmin;
2728  if (optSAME && gPad) hmin = gPad->GetUymin();
2729  else hmin = fHistogram->GetMinimum();
2730  if (hmin > 0) {
2731  Double_t hmax;
2732  Double_t hminpos = hmin;
2733  if (optSAME && gPad) hmax = gPad->GetUymax();
2734  else hmax = fHistogram->GetMaximum();
2735  hmin -= 0.05*(hmax-hmin);
2736  if (hmin < 0) hmin = 0;
2737  if (hmin <= 0 && gPad && gPad->GetLogy()) hmin = hminpos;
2738  minimum = hmin;
2739  }
2740  }
2741  }
2742  fHistogram->SetMinimum(minimum);
2743  }
2744  if (maximum == -1111) {
2746  maximum = fHistogram->GetYaxis()->GetXmax();
2747  } else {
2748  maximum = fMaximum;
2749  }
2750  fHistogram->SetMaximum(maximum);
2751  }
2752 
2753 
2754  // Draw the histogram.
2755  if (!gPad) return;
2756  if (opt.Length() == 0) fHistogram->Paint("lf");
2757  else if (optSAME) fHistogram->Paint("lfsame");
2758  else fHistogram->Paint(option);
2759 }
2760 
2761 ////////////////////////////////////////////////////////////////////////////////
2762 /// Create histogram with bin content equal to function value
2763 /// computed at the bin center
2764 /// This histogram will be used to paint the function
2765 /// A re-creation is forced and a new histogram is done if recreate=true
2766 
2768 {
2769  Int_t i;
2770  Double_t xv[1];
2771 
2772  TH1 * histogram = 0;
2773 
2774 
2775  // Create a temporary histogram and fill each channel with the function value
2776  // Preserve axis titles
2777  TString xtitle = "";
2778  TString ytitle = "";
2779  char *semicol = (char*)strstr(GetTitle(),";");
2780  if (semicol) {
2781  Int_t nxt = strlen(semicol);
2782  char *ctemp = new char[nxt];
2783  strlcpy(ctemp,semicol+1,nxt);
2784  semicol = (char*)strstr(ctemp,";");
2785  if (semicol) {
2786  *semicol = 0;
2787  ytitle = semicol+1;
2788  }
2789  xtitle = ctemp;
2790  delete [] ctemp;
2791  }
2792  if (fHistogram) {
2793  // delete previous histograms if were done if done in different mode
2794  xtitle = fHistogram->GetXaxis()->GetTitle();
2795  ytitle = fHistogram->GetYaxis()->GetTitle();
2796  if (!gPad->GetLogx() && fHistogram->TestBit(TH1::kLogX)) { delete fHistogram; fHistogram = 0; recreate = kTRUE;}
2797  if ( gPad->GetLogx() && !fHistogram->TestBit(TH1::kLogX)) { delete fHistogram; fHistogram = 0; recreate = kTRUE;}
2798  }
2799 
2800  if (fHistogram && !recreate) {
2801  histogram = fHistogram;
2802  fHistogram->GetXaxis()->SetLimits(xmin,xmax);
2803  } else {
2804  // If logx, we must bin in logx and not in x
2805  // otherwise in case of several decades, one gets wrong results.
2806  if (xmin > 0 && gPad && gPad->GetLogx()) {
2807  Double_t *xbins = new Double_t[fNpx+1];
2808  Double_t xlogmin = TMath::Log10(xmin);
2809  Double_t xlogmax = TMath::Log10(xmax);
2810  Double_t dlogx = (xlogmax-xlogmin)/((Double_t)fNpx);
2811  for (i=0;i<=fNpx;i++) {
2812  xbins[i] = gPad->PadtoX(xlogmin+ i*dlogx);
2813  }
2814  histogram = new TH1D("Func",GetTitle(),fNpx,xbins);
2815  histogram->SetBit(TH1::kLogX);
2816  delete [] xbins;
2817  } else {
2818  histogram = new TH1D("Func",GetTitle(),fNpx,xmin,xmax);
2819  }
2820  if (fMinimum != -1111) histogram->SetMinimum(fMinimum);
2821  if (fMaximum != -1111) histogram->SetMaximum(fMaximum);
2822  histogram->SetDirectory(0);
2823  }
2824  R__ASSERT(histogram);
2825 
2826  // Restore axis titles.
2827  histogram->GetXaxis()->SetTitle(xtitle.Data());
2828  histogram->GetYaxis()->SetTitle(ytitle.Data());
2829  Double_t *parameters = GetParameters();
2830 
2831  InitArgs(xv,parameters);
2832  for (i=1;i<=fNpx;i++) {
2833  xv[0] = histogram->GetBinCenter(i);
2834  histogram->SetBinContent(i,EvalPar(xv,parameters));
2835  }
2836 
2837  // Copy Function attributes to histogram attributes.
2838  histogram->SetBit(TH1::kNoStats);
2839  histogram->SetLineColor(GetLineColor());
2840  histogram->SetLineStyle(GetLineStyle());
2841  histogram->SetLineWidth(GetLineWidth());
2842  histogram->SetFillColor(GetFillColor());
2843  histogram->SetFillStyle(GetFillStyle());
2844  histogram->SetMarkerColor(GetMarkerColor());
2845  histogram->SetMarkerStyle(GetMarkerStyle());
2846  histogram->SetMarkerSize(GetMarkerSize());
2847 
2848  // update saved histogram in case it was deleted or if it is the first time the method is called
2849  // for example when called from TF1::GetHistogram()
2850  if (!fHistogram) fHistogram = histogram;
2851  return histogram;
2852 
2853 }
2854 
2855 
2856 ////////////////////////////////////////////////////////////////////////////////
2857 /// Release parameter number ipar If used in a fit, the parameter
2858 /// can vary freely. The parameter limits are reset to 0,0.
2859 
2861 {
2862  if (ipar < 0 || ipar > GetNpar()-1) return;
2863  SetParLimits(ipar,0,0);
2864 }
2865 
2866 
2867 ////////////////////////////////////////////////////////////////////////////////
2868 /// Save values of function in array fSave
2869 
2871 {
2872  Double_t *parameters = GetParameters();
2873  //if (fSave != 0) {delete [] fSave; fSave = 0;}
2874  if (fParent && fParent->InheritsFrom(TH1::Class())) {
2875  //if parent is a histogram save the function at the center of the bins
2876  if ((xmin >0 && xmax > 0) && TMath::Abs(TMath::Log10(xmax/xmin) > TMath::Log10(fNpx))) {
2877  TH1 *h = (TH1*)fParent;
2878  Int_t bin1 = h->GetXaxis()->FindBin(xmin);
2879  Int_t bin2 = h->GetXaxis()->FindBin(xmax);
2880  int fNsave = bin2-bin1+4;
2881  //fSave = new Double_t[fNsave];
2882  fSave.resize(fNsave);
2883  Double_t xv[1];
2884 
2885  InitArgs(xv,parameters);
2886  for (Int_t i=bin1;i<=bin2;i++) {
2887  xv[0] = h->GetXaxis()->GetBinCenter(i);
2888  fSave[i-bin1] = EvalPar(xv,parameters);
2889  }
2890  fSave[fNsave-3] = xmin;
2891  fSave[fNsave-2] = xmax;
2892  fSave[fNsave-1] = xmax;
2893  return;
2894  }
2895  }
2896  int fNsave = fNpx+3;
2897  if (fNsave <= 3) { return;}
2898  //fSave = new Double_t[fNsave];
2899  fSave.resize(fNsave);
2900  Double_t dx = (xmax-xmin)/fNpx;
2901  if (dx <= 0) {
2902  dx = (fXmax-fXmin)/fNpx;
2903  fNsave--;
2904  xmin = fXmin +0.5*dx;
2905  xmax = fXmax -0.5*dx;
2906  }
2907  Double_t xv[1];
2908  InitArgs(xv,parameters);
2909  for (Int_t i=0;i<=fNpx;i++) {
2910  xv[0] = xmin + dx*i;
2911  fSave[i] = EvalPar(xv,parameters);
2912  }
2913  fSave[fNpx+1] = xmin;
2914  fSave[fNpx+2] = xmax;
2915 }
2916 
2917 
2918 ////////////////////////////////////////////////////////////////////////////////
2919 /// Save primitive as a C++ statement(s) on output stream out
2920 
2921 void TF1::SavePrimitive(std::ostream &out, Option_t *option /*= ""*/)
2922 {
2923  Int_t i;
2924  char quote = '"';
2925 
2926  // Save the function as C code independant from ROOT.
2927  if (strstr(option,"cc")) {
2928  out << "double " << GetName() << "(double xv) {"<<std::endl;
2929  Double_t dx = (fXmax-fXmin)/(fNpx-1);
2930  out << " double x[" << fNpx << "] = {" << std::endl;
2931  out << " ";
2932  Int_t n = 0;
2933  for (i=0; i<fNpx; i++) {
2934  out << fXmin + dx*i ;
2935  if (i<fNpx-1) out << ", ";
2936  if (n++ == 10) { out << std::endl; out << " "; n = 0;}
2937  }
2938  out << std::endl;
2939  out << " };" << std::endl;
2940  out << " double y[" << fNpx << "] = {" << std::endl;
2941  out << " ";
2942  n = 0;
2943  for (i=0; i<fNpx; i++) {
2944  out << Eval(fXmin + dx*i);
2945  if (i<fNpx-1) out << ", ";
2946  if (n++ == 10) { out << std::endl; out << " "; n = 0;}
2947  }
2948  out << std::endl;
2949  out << " };" << std::endl;
2950  out << " if (xv<x[0]) return y[0];" << std::endl;
2951  out << " if (xv>x[" << fNpx-1 << "]) return y[" << fNpx-1 << "];" << std::endl;
2952  out << " int i, j=0;" << std::endl;
2953  out << " for (i=1; i<" << fNpx << "; i++) { if (xv < x[i]) break; j++; }" << std::endl;
2954  out << " return y[j] + (y[j + 1] - y[j]) / (x[j + 1] - x[j]) * (xv - x[j]);" << std::endl;
2955  out <<"}"<<std::endl;
2956  return;
2957  }
2958 
2959  out<<" "<<std::endl;
2960 
2961  // Either f1Number is computed locally or set from outside
2962  static Int_t f1Number = 0;
2963  TString f1Name(GetName());
2964  const char *l = strstr(option,"#");
2965  if (l != 0) {
2966  sscanf(&l[1],"%d",&f1Number);
2967  } else {
2968  ++f1Number;
2969  }
2970  f1Name += f1Number;
2971 
2972  if (!fType) {
2973  out<<" TF1 *"<<f1Name.Data()<<" = new TF1("<<quote<<GetName()<<quote<<","<<quote<<GetTitle()<<quote<<","<<fXmin<<","<<fXmax<<");"<<std::endl;
2974  if (fNpx != 100) {
2975  out<<" "<<f1Name.Data()<<"->SetNpx("<<fNpx<<");"<<std::endl;
2976  }
2977  } else {
2978  out<<" TF1 *"<<f1Name.Data()<<" = new TF1("<<quote<<"*"<<GetName()<<quote<<","<<fXmin<<","<<fXmax<<","<<GetNpar()<<");"<<std::endl;
2979  out<<" //The original function : "<<GetTitle()<<" had originally been created by:" <<std::endl;
2980  out<<" //TF1 *"<<GetName()<<" = new TF1("<<quote<<GetName()<<quote<<","<<GetTitle()<<","<<fXmin<<","<<fXmax<<","<<GetNpar()<<");"<<std::endl;
2981  out<<" "<<f1Name.Data()<<"->SetRange("<<fXmin<<","<<fXmax<<");"<<std::endl;
2982  out<<" "<<f1Name.Data()<<"->SetName("<<quote<<GetName()<<quote<<");"<<std::endl;
2983  out<<" "<<f1Name.Data()<<"->SetTitle("<<quote<<GetTitle()<<quote<<");"<<std::endl;
2984  if (fNpx != 100) {
2985  out<<" "<<f1Name.Data()<<"->SetNpx("<<fNpx<<");"<<std::endl;
2986  }
2987  Double_t dx = (fXmax-fXmin)/fNpx;
2988  Double_t xv[1];
2989  Double_t *parameters = GetParameters();
2990  InitArgs(xv,parameters);
2991  for (i=0;i<=fNpx;i++) {
2992  xv[0] = fXmin + dx*i;
2993  Double_t save = EvalPar(xv,parameters);
2994  out<<" "<<f1Name.Data()<<"->SetSavedPoint("<<i<<","<<save<<");"<<std::endl;
2995  }
2996  out<<" "<<f1Name.Data()<<"->SetSavedPoint("<<fNpx+1<<","<<fXmin<<");"<<std::endl;
2997  out<<" "<<f1Name.Data()<<"->SetSavedPoint("<<fNpx+2<<","<<fXmax<<");"<<std::endl;
2998  }
2999 
3000  if (TestBit(kNotDraw)) {
3001  out<<" "<<f1Name.Data()<<"->SetBit(TF1::kNotDraw);"<<std::endl;
3002  }
3003  if (GetFillColor() != 0) {
3004  if (GetFillColor() > 228) {
3006  out<<" "<<f1Name.Data()<<"->SetFillColor(ci);" << std::endl;
3007  } else
3008  out<<" "<<f1Name.Data()<<"->SetFillColor("<<GetFillColor()<<");"<<std::endl;
3009  }
3010  if (GetFillStyle() != 1001) {
3011  out<<" "<<f1Name.Data()<<"->SetFillStyle("<<GetFillStyle()<<");"<<std::endl;
3012  }
3013  if (GetMarkerColor() != 1) {
3014  if (GetMarkerColor() > 228) {
3016  out<<" "<<f1Name.Data()<<"->SetMarkerColor(ci);" << std::endl;
3017  } else
3018  out<<" "<<f1Name.Data()<<"->SetMarkerColor("<<GetMarkerColor()<<");"<<std::endl;
3019  }
3020  if (GetMarkerStyle() != 1) {
3021  out<<" "<<f1Name.Data()<<"->SetMarkerStyle("<<GetMarkerStyle()<<");"<<std::endl;
3022  }
3023  if (GetMarkerSize() != 1) {
3024  out<<" "<<f1Name.Data()<<"->SetMarkerSize("<<GetMarkerSize()<<");"<<std::endl;
3025  }
3026  if (GetLineColor() != 1) {
3027  if (GetLineColor() > 228) {
3029  out<<" "<<f1Name.Data()<<"->SetLineColor(ci);" << std::endl;
3030  } else
3031  out<<" "<<f1Name.Data()<<"->SetLineColor("<<GetLineColor()<<");"<<std::endl;
3032  }
3033  if (GetLineWidth() != 4) {
3034  out<<" "<<f1Name.Data()<<"->SetLineWidth("<<GetLineWidth()<<");"<<std::endl;
3035  }
3036  if (GetLineStyle() != 1) {
3037  out<<" "<<f1Name.Data()<<"->SetLineStyle("<<GetLineStyle()<<");"<<std::endl;
3038  }
3039  if (GetChisquare() != 0) {
3040  out<<" "<<f1Name.Data()<<"->SetChisquare("<<GetChisquare()<<");"<<std::endl;
3041  out<<" "<<f1Name.Data()<<"->SetNDF("<<GetNDF()<<");"<<std::endl;
3042  }
3043 
3044  if (GetXaxis()) GetXaxis()->SaveAttributes(out,f1Name.Data(),"->GetXaxis()");
3045  if (GetYaxis()) GetYaxis()->SaveAttributes(out,f1Name.Data(),"->GetYaxis()");
3046 
3047  Double_t parmin, parmax;
3048  for (i=0;i<GetNpar();i++) {
3049  out<<" "<<f1Name.Data()<<"->SetParameter("<<i<<","<<GetParameter(i)<<");"<<std::endl;
3050  out<<" "<<f1Name.Data()<<"->SetParError("<<i<<","<<GetParError(i)<<");"<<std::endl;
3051  GetParLimits(i,parmin,parmax);
3052  out<<" "<<f1Name.Data()<<"->SetParLimits("<<i<<","<<parmin<<","<<parmax<<");"<<std::endl;
3053  }
3054  if (!strstr(option,"nodraw")) {
3055  out<<" "<<f1Name.Data()<<"->Draw("
3056  <<quote<<option<<quote<<");"<<std::endl;
3057  }
3058 }
3059 
3060 
3061 ////////////////////////////////////////////////////////////////////////////////
3062 /// Static function setting the current function.
3063 /// the current function may be accessed in static C-like functions
3064 /// when fitting or painting a function.
3065 
3067 {
3068  fgCurrent = f1;
3069 }
3070 
3071 ////////////////////////////////////////////////////////////////////////////////
3072 /// Set the result from the fit
3073 /// parameter values, errors, chi2, etc...
3074 /// Optionally a pointer to a vector (with size fNpar) of the parameter indices in the FitResult can be passed
3075 /// This is useful in the case of a combined fit with different functions, and the FitResult contains the global result
3076 /// By default it is assume that indpar = {0,1,2,....,fNpar-1}.
3077 
3079 {
3080  Int_t npar = GetNpar();
3081  if (result.IsEmpty()) {
3082  Warning("SetFitResult","Empty Fit result - nothing is set in TF1");
3083  return;
3084  }
3085  if (indpar == 0 && npar != (int) result.NPar() ) {
3086  Error("SetFitResult","Invalid Fit result passed - number of parameter is %d , different than TF1::GetNpar() = %d",npar,result.NPar());
3087  return;
3088  }
3089  if (result.Chi2() > 0)
3090  SetChisquare(result.Chi2() );
3091  else
3092  SetChisquare(result.MinFcnValue() );
3093 
3094  SetNDF(result.Ndf() );
3095  SetNumberFitPoints(result.Ndf() + result.NFreeParameters() );
3096 
3097 
3098  for (Int_t i = 0; i < npar; ++i) {
3099  Int_t ipar = (indpar != 0) ? indpar[i] : i;
3100  if (ipar < 0) continue;
3101  GetParameters()[i] = result.Parameter(ipar);
3102  // in case errors are not present do not set them
3103  if (ipar < (int) result.Errors().size() )
3104  fParErrors[i] = result.Error(ipar);
3105  }
3106  //invalidate cached integral since parameters have changed
3107  Update();
3108 
3109 }
3110 
3111 
3112 ////////////////////////////////////////////////////////////////////////////////
3113 /// Set the maximum value along Y for this function
3114 /// In case the function is already drawn, set also the maximum in the
3115 /// helper histogram
3116 
3118 {
3119  fMaximum = maximum;
3120  if (fHistogram) fHistogram->SetMaximum(maximum);
3121  if (gPad) gPad->Modified();
3122 }
3123 
3124 
3125 ////////////////////////////////////////////////////////////////////////////////
3126 /// Set the minimum value along Y for this function
3127 /// In case the function is already drawn, set also the minimum in the
3128 /// helper histogram
3129 
3131 {
3132  fMinimum = minimum;
3133  if (fHistogram) fHistogram->SetMinimum(minimum);
3134  if (gPad) gPad->Modified();
3135 }
3136 
3137 
3138 ////////////////////////////////////////////////////////////////////////////////
3139 /// Set the number of degrees of freedom
3140 /// ndf should be the number of points used in a fit - the number of free parameters
3141 
3143 {
3144  fNDF = ndf;
3145 }
3146 
3147 
3148 ////////////////////////////////////////////////////////////////////////////////
3149 /// Set the number of points used to draw the function
3150 ///
3151 /// The default number of points along x is 100 for 1-d functions and 30 for 2-d/3-d functions
3152 /// You can increase this value to get a better resolution when drawing
3153 /// pictures with sharp peaks or to get a better result when using TF1::GetRandom
3154 /// the minimum number of points is 4, the maximum is 10000000 for 1-d and 10000 for 2-d/3-d functions
3155 
3157 {
3158  const Int_t minPx = 4;
3159  Int_t maxPx = 10000000;
3160  if (GetNdim() > 1) maxPx = 10000;
3161  if (npx >= minPx && npx <= maxPx) {
3162  fNpx = npx;
3163  }
3164  else {
3165  if(npx < minPx) fNpx = minPx;
3166  if(npx > maxPx) fNpx = maxPx;
3167  Warning("SetNpx","Number of points must be >=%d && <= %d, fNpx set to %d",minPx,maxPx,fNpx);
3168  }
3169  Update();
3170 }
3171 ////////////////////////////////////////////////////////////////////////////////
3172 /// Set name of parameter number ipar
3173 
3174 void TF1::SetParName(Int_t ipar, const char *name)
3175 {
3176  if (fFormula) {
3177  if (ipar <0 || ipar >= GetNpar()) return;
3178  fFormula->SetParName(ipar,name);
3179  }
3180  else
3181  fParams->SetParName(ipar,name);
3182 }
3183 
3184 ////////////////////////////////////////////////////////////////////////////////
3185 /// Set up to 10 parameter names
3186 
3187 void TF1::SetParNames(const char*name0,const char*name1,const char*name2,const char*name3,const char*name4,
3188  const char*name5,const char*name6,const char*name7,const char*name8,const char*name9,const char*name10)
3189 {
3190  if (fFormula)
3191  fFormula->SetParNames(name0,name1,name2,name3,name4,name5,name6,name7,name8,name9,name10);
3192  else
3193  fParams->SetParNames(name0,name1,name2,name3,name4,name5,name6,name7,name8,name9,name10);
3194 }
3195 ////////////////////////////////////////////////////////////////////////////////
3196 /// Set error for parameter number ipar
3197 
3199 {
3200  if (ipar < 0 || ipar > GetNpar()-1) return;
3201  fParErrors[ipar] = error;
3202 }
3203 
3204 
3205 ////////////////////////////////////////////////////////////////////////////////
3206 /// Set errors for all active parameters
3207 /// when calling this function, the array errors must have at least fNpar values
3208 
3209 void TF1::SetParErrors(const Double_t *errors)
3210 {
3211  if (!errors) return;
3212  for (Int_t i=0;i<GetNpar();i++) fParErrors[i] = errors[i];
3213 }
3214 
3215 
3216 ////////////////////////////////////////////////////////////////////////////////
3217 /// Set limits for parameter ipar.
3218 ///
3219 /// The specified limits will be used in a fit operation
3220 /// when the option "B" is specified (Bounds).
3221 /// To fix a parameter, use TF1::FixParameter
3222 
3223 void TF1::SetParLimits(Int_t ipar, Double_t parmin, Double_t parmax)
3224 {
3225  Int_t npar = GetNpar();
3226  if (ipar < 0 || ipar > npar-1) return;
3227  if (int(fParMin.size()) != npar) {fParMin.resize(npar); }
3228  if (int(fParMax.size()) != npar) {fParMax.resize(npar); }
3229  fParMin[ipar] = parmin;
3230  fParMax[ipar] = parmax;
3231 }
3232 
3233 
3234 ////////////////////////////////////////////////////////////////////////////////
3235 /// Initialize the upper and lower bounds to draw the function.
3236 ///
3237 /// The function range is also used in an histogram fit operation
3238 /// when the option "R" is specified.
3239 
3241 {
3242  fXmin = xmin;
3243  fXmax = xmax;
3244  Update();
3245 }
3246 
3247 
3248 ////////////////////////////////////////////////////////////////////////////////
3249 /// Restore value of function saved at point
3250 
3252 {
3253  if (fSave.size() == 0) {
3254  fSave.resize(fNpx+3);
3255  }
3256  if (point < 0 || point >= int(fSave.size())) return;
3257  fSave[point] = value;
3258 }
3259 
3260 
3261 ////////////////////////////////////////////////////////////////////////////////
3262 /// Set function title
3263 /// if title has the form "fffffff;xxxx;yyyy", it is assumed that
3264 /// the function title is "fffffff" and "xxxx" and "yyyy" are the
3265 /// titles for the X and Y axis respectively.
3266 
3267 void TF1::SetTitle(const char *title)
3268 {
3269  if (!title) return;
3270  fTitle = title;
3271  if (!fHistogram) return;
3272  fHistogram->SetTitle(title);
3273  if (gPad) gPad->Modified();
3274 }
3275 
3276 
3277 ////////////////////////////////////////////////////////////////////////////////
3278 /// Stream a class object.
3279 
3280 void TF1::Streamer(TBuffer &b)
3281 {
3282  if (b.IsReading()) {
3283  UInt_t R__s, R__c;
3284  Version_t v = b.ReadVersion(&R__s, &R__c);
3285  // process new version with new TFormula class which is contained in TF1
3286  //printf("reading TF1....- version %d..\n",v);
3287 
3288  if (v > 7) {
3289  // new classes with new TFormula
3290  // need to register the objects
3291  b.ReadClassBuffer(TF1::Class(), this, v, R__s, R__c);
3292  if (!TestBit(kNotGlobal)) {
3294  gROOT->GetListOfFunctions()->Add(this);
3295  }
3296  return;
3297  }
3298  else {
3299  ROOT::v5::TF1Data fold;
3300  //printf("Reading TF1 as v5::TF1Data- version %d \n",v);
3301  fold.Streamer(b, v, R__s, R__c, TF1::Class());
3302  // convert old TF1 to new one
3303  fNpar = fold.GetNpar();
3304  fNdim = fold.GetNdim();
3305  if (fold.fType == 0) {
3306  // formula functions
3307  // if ndim is not 1 set xmin max to zero to avoid error in ctor
3308  double xmin = fold.fXmin;
3309  double xmax = fold.fXmax;
3310  if (fNdim > 1) {
3311  xmin = 0; xmax = 0;
3312  }
3313  TF1 fnew(fold.GetName(), fold.GetExpFormula(), xmin, xmax );
3314  if (fNdim > 1) {
3315  fnew.SetRange(fold.fXmin, fold.fXmax);
3316  }
3317  fnew.Copy(*this);
3318  } else {
3319  // case of a function pointers
3320  fParams = new TF1Parameters(fNpar);
3321  fName = fold.GetName();
3322  fTitle = fold.GetTitle();
3323  }
3324  // need to set parameter values
3325  SetParameters(fold.GetParameters() );
3326  // copy the other data members
3327  fNpx = fold.fNpx;
3328  fType = fold.fType;
3329  fNpfits = fold.fNpfits;
3330  fNDF = fold.fNDF;
3331  fChisquare = fold.fChisquare;
3332  fMaximum = fold.fMaximum;
3333  fMinimum = fold.fMinimum;
3334  fXmin = fold.fXmin;
3335  fXmax = fold.fXmax;
3336 
3337  if (fold.fParErrors) fParErrors = std::vector<Double_t>(fold.fParErrors, fold.fParErrors+fNpar);
3338  if (fold.fParMin) fParMin = std::vector<Double_t>(fold.fParMin, fold.fParMin+fNpar);
3339  if (fold.fParMax) fParMax = std::vector<Double_t>(fold.fParMax, fold.fParMax+fNpar);
3340  if (fold.fNsave > 0) {
3341  assert(fold.fSave);
3342  fSave = std::vector<Double_t>(fold.fSave, fold.fSave+fold.fNsave);
3343  }
3344  // set the bits
3345  for (int ibit = 0; ibit < 24; ++ibit)
3346  if (fold.TestBit(BIT(ibit) ) ) SetBit(BIT(ibit));
3347 
3348  // copy the graph attributes
3349  TAttLine & fOldLine = static_cast<TAttLine &>(fold);
3350  fOldLine.Copy(*this);
3351  TAttFill & fOldFill = static_cast<TAttFill &>(fold);
3352  fOldFill.Copy(*this);
3353  TAttMarker & fOldMarker = static_cast<TAttMarker &>(fold);
3354  fOldMarker.Copy(*this);
3355 
3356  }
3357  }
3358 
3359  // Writing
3360  else {
3361  Int_t saved = 0;
3362  // save not-formula functions as array of points
3363  if (fType > 0 && fSave.empty()) { saved = 1; Save(fXmin,fXmax,0,0,0,0);}
3364 
3365  b.WriteClassBuffer(TF1::Class(),this);
3366 
3367  // clear vector contents
3368  if (saved) { fSave.clear(); }
3369  }
3370 }
3371 
3372 
3373 ////////////////////////////////////////////////////////////////////////////////
3374 /// Called by functions such as SetRange, SetNpx, SetParameters
3375 /// to force the deletion of the associated histogram or Integral
3376 
3378 {
3379  delete fHistogram;
3380  fHistogram = 0;
3381  if (!fIntegral.empty()) {
3382  fIntegral.clear();
3383  fAlpha.clear();
3384  fBeta.clear();
3385  fGamma.clear();
3386  }
3387  if (fNormalized) {
3388  // need to compute the integral of the not-normalized function
3389  fNormalized = false;
3391  fNormalized = true;
3392  }
3393  else
3394  fNormIntegral = 0;
3395 
3396  // std::vector<double>x(fNdim);
3397  // if ((fType == 1) && !fFunctor.Empty()) fFunctor(x.data(), (Double_t*)fParams);
3398 }
3399 
3400 ////////////////////////////////////////////////////////////////////////////////
3401 /// Static function to set the global flag to reject points
3402 /// the fgRejectPoint global flag is tested by all fit functions
3403 /// if TRUE the point is not included in the fit.
3404 /// This flag can be set by a user in a fitting function.
3405 /// The fgRejectPoint flag is reset by the TH1 and TGraph fitting functions.
3406 
3408 {
3409  fgRejectPoint = reject;
3410 }
3411 
3412 
3413 ////////////////////////////////////////////////////////////////////////////////
3414 /// See TF1::RejectPoint above
3415 
3417 {
3418  return fgRejectPoint;
3419 }
3420 
3421 ////////////////////////////////////////////////////////////////////////////////
3422 /// Return nth moment of function between a and b
3423 ///
3424 /// See TF1::Integral() for parameter definitions
3425 
3427 {
3428  // wrapped function in interface for integral calculation
3429  // using abs value of integral
3430 
3431  TF1_EvalWrapper func(this, params, kTRUE, n);
3432 
3434 
3435  giod.SetFunction(func);
3436  giod.SetRelTolerance(epsilon);
3437 
3438  Double_t norm = giod.Integral(a, b);
3439  if (norm == 0) {
3440  Error("Moment", "Integral zero over range");
3441  return 0;
3442  }
3443 
3444  // calculate now integral of x^n f(x)
3445  // wrapped the member function EvalNum in interface required by integrator using the functor class
3446  ROOT::Math::Functor1D xnfunc( &func, &TF1_EvalWrapper::EvalNMom);
3447  giod.SetFunction(xnfunc);
3448 
3449  Double_t res = giod.Integral(a,b)/norm;
3450 
3451  return res;
3452 }
3453 
3454 
3455 ////////////////////////////////////////////////////////////////////////////////
3456 /// Return nth central moment of function between a and b
3457 /// (i.e the n-th moment around the mean value)
3458 ///
3459 /// See TF1::Integral() for parameter definitions
3460 ///
3461 /// \author Gene Van Buren <gene@bnl.gov>
3462 
3464 {
3465  TF1_EvalWrapper func(this, params, kTRUE, n);
3466 
3468 
3469  giod.SetFunction(func);
3470  giod.SetRelTolerance(epsilon);
3471 
3472  Double_t norm = giod.Integral(a, b);
3473  if (norm == 0) {
3474  Error("Moment", "Integral zero over range");
3475  return 0;
3476  }
3477 
3478  // calculate now integral of xf(x)
3479  // wrapped the member function EvalFirstMom in interface required by integrator using the functor class
3480  ROOT::Math::Functor1D xfunc( &func, &TF1_EvalWrapper::EvalFirstMom);
3481  giod.SetFunction(xfunc);
3482 
3483  // estimate of mean value
3484  Double_t xbar = giod.Integral(a,b)/norm;
3485 
3486  // use different mean value in function wrapper
3487  func.fX0 = xbar;
3488  ROOT::Math::Functor1D xnfunc( &func, &TF1_EvalWrapper::EvalNMom);
3489  giod.SetFunction(xnfunc);
3490 
3491  Double_t res = giod.Integral(a,b)/norm;
3492  return res;
3493 }
3494 
3495 
3496 //______________________________________________________________________________
3497 // some useful static utility functions to compute sampling points for IntegralFast
3498 ////////////////////////////////////////////////////////////////////////////////
3499 /// Type safe interface (static method)
3500 /// The number of sampling points are taken from the TGraph
3501 
3502 #ifdef INTHEFUTURE
3504 {
3505  if (!g) return;
3506  CalcGaussLegendreSamplingPoints(g->GetN(), g->GetX(), g->GetY(), eps);
3507 }
3508 
3509 
3510 ////////////////////////////////////////////////////////////////////////////////
3511 /// Type safe interface (static method)
3512 /// A TGraph is created with new with num points and the pointer to the
3513 /// graph is returned by the function. It is the responsibility of the
3514 /// user to delete the object.
3515 /// if num is invalid (<=0) NULL is returned
3516 
3518 {
3519  if (num<=0)
3520  return 0;
3521 
3522  TGraph *g = new TGraph(num);
3523  CalcGaussLegendreSamplingPoints(g->GetN(), g->GetX(), g->GetY(), eps);
3524  return g;
3525 }
3526 #endif
3527 
3528 
3529 ////////////////////////////////////////////////////////////////////////////////
3530 /// Type: unsafe but fast interface filling the arrays x and w (static method)
3531 ///
3532 /// Given the number of sampling points this routine fills the arrays x and w
3533 /// of length num, containing the abscissa and weight of the Gauss-Legendre
3534 /// n-point quadrature formula.
3535 ///
3536 /// Gauss-Legendre:
3537 /** \f[
3538  W(x)=1 -1<x<1 \\
3539  (j+1)P_{j+1} = (2j+1)xP_j-jP_{j-1}
3540  \f]
3541 **/
3542 /// num is the number of sampling points (>0)
3543 /// x and w are arrays of size num
3544 /// eps is the relative precision
3545 ///
3546 /// If num<=0 or eps<=0 no action is done.
3547 ///
3548 /// Reference: Numerical Recipes in C, Second Edition
3549 
3551 {
3552  // This function is just kept like this for backward compatibility!
3553 
3555  gli.GetWeightVectors(x, w);
3556 
3557 
3558 }
3559 
3560 
3561 /** \class TF1Parameters
3562 TF1 Parameters class
3563 */
3564 
3565 ////////////////////////////////////////////////////////////////////////////////
3566 /// Returns the parameter number given a name
3567 /// not very efficient but list of parameters is typically small
3568 /// could use a map if needed
3569 
3570 Int_t TF1Parameters::GetParNumber(const char * name) const
3571 {
3572  for (unsigned int i = 0; i < fParNames.size(); ++i) {
3573  if (fParNames[i] == std::string(name) ) return i;
3574  }
3575  return -1;
3576 }
3577 
3578 ////////////////////////////////////////////////////////////////////////////////
3579 /// Set parameter values
3580 
3582  Double_t p5,Double_t p6,Double_t p7,Double_t p8,
3583  Double_t p9,Double_t p10)
3584 {
3585  unsigned int npar = fParameters.size();
3586  if (npar > 0) fParameters[0] = p0;
3587  if (npar > 1) fParameters[1] = p1;
3588  if (npar > 2) fParameters[2] = p2;
3589  if (npar > 3) fParameters[3] = p3;
3590  if (npar > 4) fParameters[4] = p4;
3591  if (npar > 5) fParameters[5] = p5;
3592  if (npar > 6) fParameters[6] = p6;
3593  if (npar > 7) fParameters[7] = p7;
3594  if (npar > 8) fParameters[8] = p8;
3595  if (npar > 9) fParameters[9] = p9;
3596  if (npar >10) fParameters[10]= p10;
3597 }
3598 
3599 ////////////////////////////////////////////////////////////////////////////////
3600 /// Set parameter names
3601 
3602 void TF1Parameters::SetParNames(const char *name0,const char *name1,const char *name2,const char *name3,
3603  const char *name4, const char *name5,const char *name6,const char *name7,
3604  const char *name8,const char *name9,const char *name10)
3605 {
3606  unsigned int npar = fParNames.size();
3607  if (npar > 0) fParNames[0] = name0;
3608  if (npar > 1) fParNames[1] = name1;
3609  if (npar > 2) fParNames[2] = name2;
3610  if (npar > 3) fParNames[3] = name3;
3611  if (npar > 4) fParNames[4] = name4;
3612  if (npar > 5) fParNames[5] = name5;
3613  if (npar > 6) fParNames[6] = name6;
3614  if (npar > 7) fParNames[7] = name7;
3615  if (npar > 8) fParNames[8] = name8;
3616  if (npar > 9) fParNames[9] = name9;
3617  if (npar >10) fParNames[10]= name10;
3618 }
TString fTitle
Definition: TNamed.h:37
ROOT::Math::ParamFunctor fFunctor
Definition: TF1.h:187
virtual const char * GetName() const
Returns name of object.
Definition: TNamed.h:51
Double_t fMaximum
Definition: TF1.h:173
virtual void Print(Option_t *option="") const
Print some global quantities for this histogram.
Definition: TH1.cxx:6324
virtual Double_t GetMaximumStored() const
Definition: TH1.h:293
virtual Int_t GetQuantiles(Int_t nprobSum, Double_t *q, const Double_t *probSum)
Compute Quantiles for density distribution of this function.
Definition: TF1.cxx:1705
virtual void SetLineWidth(Width_t lwidth)
Set the line width.
Definition: TAttLine.h:49
double par[1]
Definition: unuranDistr.cxx:38
Bool_t IsReading() const
Definition: TBuffer.h:83
virtual Double_t GetMaximum(Double_t xmin=0, Double_t xmax=0, Double_t epsilon=1.E-10, Int_t maxiter=100, Bool_t logx=false) const
Returns the maximum value of the function.
Definition: TF1.cxx:1338
double Derivative3(double x)
Returns the third derivative of the function at point x, computed by Richardson&#39;s extrapolation metho...
virtual Double_t GetMaximum(Double_t maxval=FLT_MAX) const
Return maximum value smaller than maxval of bins in the range, unless the value has been overridden b...
Definition: TH1.cxx:7664
virtual void SaveAttributes(std::ostream &out, const char *name, const char *subname)
Save axis attributes as C++ statement(s) on output stream out.
Definition: TAxis.cxx:646
virtual void Paint(Option_t *option="")
Control routine to paint any kind of histograms.
Definition: TH1.cxx:5538
virtual void SetParameters(const Double_t *params)
Definition: TF1.h:439
virtual Double_t GetRandom()
Return a random number following this function shape.
Definition: TF1.cxx:1798
Int_t fNpx
Definition: TF1.h:167
Bool_t fNormalized
Pointer to MethodCall in case of interpreted function.
Definition: TF1.h:185
double IntegralUp(double a)
Returns Integral of function on an upper semi-infinite interval.
float xmin
Definition: THbookFile.cxx:93
virtual Int_t WriteClassBuffer(const TClass *cl, void *pointer)=0
virtual Double_t GetBinCenter(Int_t bin) const
Return bin center for 1D histogram.
Definition: TH1.cxx:8251
virtual void Info(const char *method, const char *msgfmt,...) const
Issue info message.
Definition: TObject.cxx:899
Double_t Eval(Double_t x) const
Definition: TFormula.cxx:2569
double Error() const
Return the estimate of the absolute Error of the last Integral calculation.
Interface (abstract class) for generic functions objects of one-dimension Provides a method to evalua...
Definition: IFunction.h:133
virtual void SetNpx(Int_t npx=100)
Set the number of points used to draw the function.
Definition: TF1.cxx:3156
virtual void ReleaseParameter(Int_t ipar)
Release parameter number ipar If used in a fit, the parameter can vary freely.
Definition: TF1.cxx:2860
long long Long64_t
Definition: RtypesCore.h:69
virtual void SetMaximum(Double_t maximum=-1111)
Definition: TH1.h:399
bool Solve(int maxIter=100, double absTol=1E-8, double relTol=1E-10)
Returns the X value corresponding to the function value fy for (xmin<x<xmax).
virtual Double_t GetMinimumX(Double_t xmin=0, Double_t xmax=0, Double_t epsilon=1.E-10, Int_t maxiter=100, Bool_t logx=false) const
Returns the X value corresponding to the minimum value of the function on the (xmin, xmax) interval.
Definition: TF1.cxx:1542
static double p3(double t, double a, double b, double c, double d)
virtual void SetParName(Int_t ipar, const char *name)
Set name of parameter number ipar.
Definition: TF1.cxx:3174
virtual void Copy(TObject &f1) const
Copy this F1 to a new F1.
Definition: TF1.cxx:770
virtual void SetLimits(Double_t xmin, Double_t xmax)
Definition: TAxis.h:160
This namespace contains pre-defined functions to be used in conjuction with TExecutor::Map and TExecu...
Definition: StringConv.hxx:21
int Status() const
return the Error Status of the last Integral calculation
Definition: Integrator.h:425
short Version_t
Definition: RtypesCore.h:61
double Error(unsigned int i) const
parameter error by index
Definition: FitResult.h:191
virtual void SetParNames(const char *name0="p0", const char *name1="p1", const char *name2="p2", const char *name3="p3", const char *name4="p4", const char *name5="p5", const char *name6="p6", const char *name7="p7", const char *name8="p8", const char *name9="p9", const char *name10="p10")
Set up to 10 parameter names.
Definition: TF1.cxx:3187
virtual void SetDirectory(TDirectory *dir)
By default when an histogram is created, it is added to the list of histogram objects in the current ...
Definition: TH1.cxx:8051
virtual TF1 * DrawCopy(Option_t *option="") const
Draw a copy of this function with its current attributes.
Definition: TF1.cxx:1114
static std::atomic< Bool_t > fgAbsValue
Definition: TF1.h:191
const char Option_t
Definition: RtypesCore.h:62
float ymin
Definition: THbookFile.cxx:93
virtual Int_t GetNumberFreeParameters() const
Return the number of free parameters.
Definition: TF1.cxx:1613
const std::vector< double > & Errors() const
parameter errors (return st::vector)
Definition: FitResult.h:174
void SetLogScan(bool on)
Set a log grid scan (default is equidistant bins) will work only if xlow > 0.
unsigned int NPar() const
total number of parameters (abbreviation)
Definition: FitResult.h:136
virtual Double_t GetMinimumStored() const
Definition: TH1.h:297
R__EXTERN TStyle * gStyle
Definition: TStyle.h:418
const Double_t * GetArray() const
Definition: TArrayD.h:45
Double_t fXmax
Definition: TF1Data.h:48
Bool_t TestBit(UInt_t f) const
Definition: TObject.h:157
int Status() const
return status of integration
void DoInitialize(EAddToList addToGlobList)
Common initialization of the TF1.
Definition: TF1.cxx:611
#define BIT(n)
Definition: Rtypes.h:120
virtual Double_t IntegralFast(Int_t num, Double_t *x, Double_t *w, Double_t a, Double_t b, Double_t *params=0, Double_t epsilon=1e-12)
Gauss-Legendre integral, see CalcGaussLegendreSamplingPoints.
Definition: TF1.cxx:2523
static TF1 * GetCurrent()
Static function returning the current function being processed.
Definition: TF1.cxx:1298
TH1 * h
Definition: legend2.C:5
static void SaveColor(std::ostream &out, Int_t ci)
Save a color with index > 228 as a C++ statement(s) on output stream out.
Definition: TColor.cxx:2021
Int_t fNpar
Definition: TF1.h:165
virtual void Copy(TObject &f1) const
Copy this to obj.
Definition: TFormula.cxx:520
void SetParNames(const char *name0="p0", const char *name1="p1", const char *name2="p2", const char *name3="p3", const char *name4="p4", const char *name5="p5", const char *name6="p6", const char *name7="p7", const char *name8="p8", const char *name9="p9", const char *name10="p10")
Definition: TFormula.cxx:2469
TObject * fParent
Array gamma.
Definition: TF1.h:182
Double_t * fParErrors
Definition: TF1Data.h:55
virtual void SetRange(Double_t xmin, Double_t xmax)
Initialize the upper and lower bounds to draw the function.
Definition: TF1.cxx:3240
virtual void ExecuteEvent(Int_t event, Int_t px, Int_t py)
Execute action corresponding to one event.
Definition: TF1.cxx:1270
void ToUpper()
Change string to upper case.
Definition: TString.cxx:1102
Double_t fChisquare
Definition: TF1.h:171
Buffer base class used for serializing objects.
Definition: TBuffer.h:42
virtual void Save(Double_t xmin, Double_t xmax, Double_t ymin, Double_t ymax, Double_t zmin, Double_t zmax)
Save values of function in array fSave.
Definition: TF1.cxx:2870
#define R__ASSERT(e)
Definition: TError.h:98
virtual Double_t IntegralMultiple(Int_t n, const Double_t *a, const Double_t *b, Int_t maxpts, Double_t epsrel, Double_t epsabs, Double_t &relerr, Int_t &nfnevl, Int_t &ifail)
This function computes, to an attempted specified accuracy, the value of the integral.
Definition: TF1.cxx:2596
virtual void SetMinimum(Double_t minimum=-1111)
Definition: TH1.h:400
#define gROOT
Definition: TROOT.h:364
double Integral(const double *xmin, const double *xmax)
evaluate the integral with the previously given function between xmin[] and xmax[] ...
unsigned int Ndf() const
Number of degree of freedom.
Definition: FitResult.h:168
static ROOT::Math::Minimizer * CreateMinimizer(const std::string &minimizerType="", const std::string &algoType="")
static method to create the corrisponding Minimizer given the string Supported Minimizers types are: ...
Definition: Factory.cxx:63
Basic string class.
Definition: TString.h:137
Class to Wrap a ROOT Function class (like TF1) in a IParamFunction interface of one dimensions to be ...
Definition: WrappedTF1.h:41
Int_t GetNpar() const
Definition: TFormula.h:175
TAxis * GetXaxis() const
Get x axis of the function.
Definition: TF1.cxx:2108
virtual void SetNumberFitPoints(Int_t npfits)
Definition: TF1.h:428
static Bool_t DefaultAddToGlobalList(Bool_t on=kTRUE)
Static method to add/avoid to add automatically functions to the global list (gROOT->GetListOfFunctio...
Definition: TF1.cxx:651
static Double_t DerivativeError()
Static function returning the error of the last call to the of Derivative&#39;s functions.
Definition: TF1.cxx:1030
Double_t fNormIntegral
Definition: TF1.h:186
Short_t Min(Short_t a, Short_t b)
Definition: TMathBase.h:170
void ToLower()
Change string to lower-case.
Definition: TString.cxx:1089
int Int_t
Definition: RtypesCore.h:41
bool Bool_t
Definition: RtypesCore.h:59
virtual Double_t GetMaximumX(Double_t xmin=0, Double_t xmax=0, Double_t epsilon=1.E-10, Int_t maxiter=100, Bool_t logx=false) const
Returns the X value corresponding to the maximum value of the function.
Definition: TF1.cxx:1376
TArc * a
Definition: textangle.C:12
R__EXTERN TVirtualMutex * gROOTMutex
Definition: TROOT.h:63
const Bool_t kFALSE
Definition: Rtypes.h:92
void Copy(TAttMarker &attmarker) const
Copy this marker attributes to a new TAttMarker.
Definition: TAttMarker.cxx:194
virtual void Draw(Option_t *option="")
Draw this function with its current attributes.
Definition: TF1.cxx:1086
virtual void SetFillStyle(Style_t fstyle)
Set the fill area style.
Definition: TAttFill.h:44
virtual Double_t GetParError(Int_t ipar) const
Return value of parameter number ipar.
Definition: TF1.cxx:1642
double Parameter(unsigned int i) const
parameter value by index
Definition: FitResult.h:186
virtual Double_t Derivative2(Double_t x, Double_t *params=0, Double_t epsilon=0.001) const
Returns the second derivative of the function at point x, computed by Richardson&#39;s extrapolation meth...
Definition: TF1.cxx:929
double MinFcnValue() const
Return value of the objective function (chi2 or likelihood) used in the fit.
Definition: FitResult.h:125
double Integral(double a, double b)
Returns Integral of function between a and b.
STL namespace.
virtual void SetMinimum(Double_t minimum=-1111)
Set the minimum value along Y for this function In case the function is already drawn, set also the minimum in the helper histogram.
Definition: TF1.cxx:3130
double Derivative2(double x)
Returns the second derivative of the function at point x, computed by Richardson&#39;s extrapolation meth...
virtual Double_t Integral(Double_t a, Double_t b, Double_t epsrel=1.e-12)
IntegralOneDim or analytical integral.
Definition: TF1.cxx:2277
const char * Class
Definition: TXMLSetup.cxx:64
User class for performing function integration.
virtual TObject * DrawIntegral(Option_t *option="al")
Draw integral of this function.
Definition: TF1.cxx:1161
Short_t Abs(Short_t d)
Definition: TMathBase.h:110
virtual void Draw(Option_t *chopt="")
Draw this graph with its current attributes.
Definition: TGraph.cxx:747
virtual TVirtualPad * cd(Int_t subpadnumber=0)=0
virtual Double_t Derivative3(Double_t x, Double_t *params=0, Double_t epsilon=0.001) const
Returns the third derivative of the function at point x, computed by Richardson&#39;s extrapolation metho...
Definition: TF1.cxx:995
virtual Int_t GetNdim() const
Definition: TFormula.h:243
virtual Width_t GetLineWidth() const
Return the line width.
Definition: TAttLine.h:41
Double_t Prob(Double_t chi2, Int_t ndf)
Computation of the probability for a certain Chi-squared (chi2) and number of degrees of freedom (ndf...
Definition: TMath.cxx:624
Width_t GetFuncWidth() const
Definition: TStyle.h:222
LongDouble_t Power(LongDouble_t x, LongDouble_t y)
Definition: TMath.h:501
virtual bool SetLimitedVariable(unsigned int ivar, const std::string &name, double val, double step, double lower, double upper)
set a new upper/lower limited variable (override if minimizer supports them ) otherwise as default se...
Definition: Minimizer.h:171
void SetBit(UInt_t f, Bool_t set)
Set or unset the user status bits as specified in f.
Definition: TObject.cxx:739
double IntegralLow(double b)
Returns Integral of function on a lower semi-infinite interval.
double beta(double x, double y)
Calculates the beta function.
static void SetCurrent(TF1 *f1)
Static function setting the current function.
Definition: TF1.cxx:3066
if object in a list can be deleted
Definition: TObject.h:56
TF1 Parameters class.
Definition: TF1.h:56
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&#39;s extrapolation metho...
Definition: TF1.cxx:863
virtual void AppendPad(Option_t *option="")
Append graphics object to current pad.
Definition: TObject.cxx:165
virtual void RecursiveRemove(TObject *obj)
Recursively remove this object from a list.
Definition: TObject.cxx:617
virtual Double_t GetProb() const
Return the fit probability.
Definition: TF1.cxx:1667
virtual Style_t GetMarkerStyle() const
Return the marker style.
Definition: TAttMarker.h:37
Template class to wrap any C++ callable object which takes one argument i.e.
void SetParamPtrs(void *paramArr, Int_t nparam=-1)
ParamArr is an array containing the function argument values.
Marker Attributes class.
Definition: TAttMarker.h:24
virtual Int_t DistancetoPrimitive(Int_t px, Int_t py)
Compute distance from point px,py to a function.
Definition: TF1.cxx:1046
virtual Style_t GetLineStyle() const
Return the line style.
Definition: TAttLine.h:40
virtual Int_t GetNDF() const
Return the number of degrees of freedom in the fit the fNDF parameter has been previously computed du...
Definition: TF1.cxx:1602
TAxis * GetYaxis() const
Get y axis of the function.
Definition: TF1.cxx:2119
virtual Double_t Moment(Double_t n, Double_t a, Double_t b, const Double_t *params=0, Double_t epsilon=0.000001)
Return nth moment of function between a and b.
Definition: TF1.cxx:3426
virtual void SetRelTolerance(double eps)
Set the desired relative Error.
void SetParameters(const double *p)
set parameter values
Definition: WrappedTF1.h:90
TFormula * fFormula
Functor object to wrap any C++ callable object.
Definition: TF1.h:188
Double_t GetXmin() const
Definition: TAxis.h:139
static const double x2[5]
Fill Area Attributes class.
Definition: TAttFill.h:24
Double_t x[n]
Definition: legend1.C:17
static TString Format(const char *fmt,...)
Static method which formats a string using a printf style format descriptor and return a TString...
Definition: TString.cxx:2335
Int_t fNpfits
Definition: TF1.h:169
void Copy(TAttLine &attline) const
Copy this line attributes to a new TAttLine.
Definition: TAttLine.cxx:162
Int_t fNdim
Definition: TF1.h:166
The TNamed class is the base class for all named ROOT classes.
Definition: TNamed.h:33
unsigned int r3[N_CITIES]
Definition: simanTSP.cxx:323
double par0[8]
virtual void DrawF1(Double_t xmin, Double_t xmax, Option_t *option="")
Draw function between xmin and xmax.
Definition: TF1.cxx:1177
Abstract Minimizer class, defining the interface for the various minimizer (like Minuit2, Minuit, GSL, etc..) Plug-in&#39;s exist in ROOT to be able to instantiate the derived classes like ROOT::Math::GSLMinimizer or ROOT::Math::Minuit2Minimizer via the plug-in manager.
Definition: Minimizer.h:86
Double_t Log10(Double_t x)
Definition: TMath.h:529
virtual double MinValue() const =0
return minimum function value
static double p2(double t, double a, double b, double c)
int NEval() const
return number of function evaluations in calculating the integral
virtual Double_t GetBinCenter(Int_t bin) const
Return center of bin.
Definition: TAxis.cxx:464
TF1()
TF1 default constructor.
Definition: TF1.cxx:396
virtual bool Minimize()=0
method to perform the minimization
void SetParameters(const Double_t *params)
Definition: TF1.h:105
virtual void SetMarkerColor(Color_t mcolor=1)
Set the marker color.
Definition: TAttMarker.h:43
double Derivative1(double x)
Returns the first derivative of the function at point x, computed by Richardson&#39;s extrapolation metho...
virtual Size_t GetMarkerSize() const
Return the marker size.
Definition: TAttMarker.h:38
static IntegrationOneDim::Type DefaultIntegratorType()
virtual Int_t GetNdim() const
Definition: TF1.h:350
you should not use this method at all Int_t Int_t Double_t bm
Definition: TRolke.cxx:630
virtual const double * X() const =0
return pointer to X values at the minimum
Method or function calling interface.
Definition: TMethodCall.h:41
User class for performing function minimization.
void SetParName(Int_t ipar, const char *name)
Definition: TFormula.cxx:2485
TVirtualPad is an abstract base class for the Pad and Canvas classes.
Definition: TVirtualPad.h:59
Double_t Infinity()
Definition: TMath.h:635
Int_t GetNdim() const
Definition: TFormula.h:174
double Error() const
return the estimate of the absolute Error of the last Integral calculation
Definition: Integrator.h:420
std::vector< Double_t > fIntegral
Definition: TF1.h:178
double Integral(const double *xmin, const double *xmax)
evaluate the integral with the previously given function between xmin[] and xmax[] ...
int Status() const
return the status of the last integration - 0 in case of success
virtual Double_t Rndm()
Machine independent random number generator.
Definition: TRandom.cxx:512
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:2153
double IntegralLow(const IGenFunction &f, double b)
evaluate the Integral of a function f over the over the semi-infinite interval (-inf,b)
Definition: Integrator.h:300
virtual const char * GetParName(Int_t ipar) const
Definition: TF1.h:370
static TF1 * fgCurrent
Definition: TF1.h:194
Bool_t AreEqualRel(Double_t af, Double_t bf, Double_t relPrec)
Definition: TMath.h:196
virtual Int_t DistancetoPrimitive(Int_t px, Int_t py)
Compute distance from point px,py to a line.
Definition: TH1.cxx:2589
virtual void SetLineColor(Color_t lcolor)
Set the line color.
Definition: TAttLine.h:46
Double_t EvalPar(const Double_t *x, const Double_t *params=0) const
Definition: TFormula.cxx:2540
double Integral(Function &f, double a, double b)
evaluate the Integral of a function f over the defined interval (a,b)
Definition: Integrator.h:506
double Root() const
Returns root value.
Using a TBrowser one can browse all ROOT objects.
Definition: TBrowser.h:41
virtual void ExecuteEvent(Int_t event, Int_t px, Int_t py)
Execute action corresponding to one event.
Definition: TH1.cxx:3021
double gamma(double x)
virtual void SetChisquare(Double_t chi2)
Definition: TF1.h:419
float ymax
Definition: THbookFile.cxx:93
virtual void SetParLimits(Int_t ipar, Double_t parmin, Double_t parmax)
Set limits for parameter ipar.
Definition: TF1.cxx:3223
double IntegralUp(const IGenFunction &f, double a)
evaluate the Integral of a function f over the semi-infinite interval (a,+inf)
Definition: Integrator.h:282
static Bool_t fgRejectPoint
Definition: TF1.h:192
virtual void SetFunction(const ROOT::Math::IMultiGenFunction &func)=0
set the function to minimize
TH1 * fHistogram
Parent object hooking this function (if one)
Definition: TF1.h:183
unsigned int NFreeParameters() const
get total number of free parameters
Definition: FitResult.h:139
virtual Double_t GetMinimum(Double_t xmin=0, Double_t xmax=0, Double_t epsilon=1.E-10, Int_t maxiter=100, Bool_t logx=false) const
Returns the minimum value of the function on the (xmin, xmax) interval.
Definition: TF1.cxx:1414
TRandom2 r(17)
const char * GetTitle() const
Returns title of object.
Definition: TAxis.h:135
virtual Bool_t IsValid() const
Return kTRUE if the function is valid.
Definition: TF1.cxx:2626
Class to manage histogram axis.
Definition: TAxis.h:36
static const std::string & DefaultMinimizerType()
SVector< double, 2 > v
Definition: Dict.h:5
virtual void SetFillColor(Color_t fcolor)
Set the fill area color.
Definition: TAttFill.h:42
void SetLogScan(bool on)
Set a log grid scan (default is equidistant bins) will work only if xlow > 0.
double IntegralError(TF1 *func, Int_t ndim, const double *a, const double *b, const double *params, const double *covmat, double epsilon)
Definition: TF1Helper.cxx:38
The F O R M U L A class.
Definition: TFormula.h:89
virtual void SetParError(Int_t ipar, Double_t error)
Set error for parameter number ipar.
Definition: TF1.cxx:3198
virtual char * GetObjectInfo(Int_t px, Int_t py) const
Redefines TObject::GetObjectInfo.
Definition: TF1.cxx:1630
unsigned int r1[N_CITIES]
Definition: simanTSP.cxx:321
void SetFunction(const ROOT::Math::IGenFunction &f, double xlow, double xup)
Sets function to be minimized.
virtual Bool_t InheritsFrom(const char *classname) const
Returns kTRUE if object inherits from class "classname".
Definition: TObject.cxx:488
virtual void SetBinContent(Int_t bin, Double_t content)
Set bin content see convention for numbering bins in TH1::GetBin In case the bin number is greater th...
Definition: TH1.cxx:8323
X-axis in log scale.
Definition: TH1.h:175
unsigned int UInt_t
Definition: RtypesCore.h:42
TMarker * m
Definition: textangle.C:8
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition: TObject.cxx:925
char * Form(const char *fmt,...)
User class for performing function integration.
virtual void FixParameter(Int_t ipar, Double_t value)
Fix the value of a parameter The specified value will be used in a fit operation. ...
Definition: TF1.cxx:1286
Ssiz_t Length() const
Definition: TString.h:390
Double_t * fParMax
Definition: TF1Data.h:57
int Status() const
return the Error Status of the last Integral calculation
Int_t fType
Definition: TF1.h:168
User Class for performing numerical integration of a function in one dimension.
Definition: Integrator.h:102
Double_t E()
Definition: TMath.h:54
Double_t fMinimum
Definition: TF1.h:172
Int_t GetN() const
Definition: TGraph.h:133
static void RejectPoint(Bool_t reject=kTRUE)
Static function to set the global flag to reject points the fgRejectPoint global flag is tested by al...
Definition: TF1.cxx:3407
TLine * l
Definition: textangle.C:4
static void InitStandardFunctions()
Create the basic function objects.
Definition: TF1.cxx:2249
virtual void SetMarkerStyle(Style_t mstyle=1)
Set the marker style.
Definition: TAttMarker.h:45
TAxis * GetYaxis()
Definition: TH1.h:325
static double p1(double t, double a, double b)
float xmax
Definition: THbookFile.cxx:93
virtual void Update()
Called by functions such as SetRange, SetNpx, SetParameters to force the deletion of the associated h...
Definition: TF1.cxx:3377
virtual ~TF1()
TF1 default destructor.
Definition: TF1.cxx:708
don&#39;t draw stats box
Definition: TH1.h:172
virtual Int_t GetNpar() const
Definition: TFormula.h:244
virtual Double_t GetXmin() const
Definition: TF1.h:388
R__EXTERN TRandom * gRandom
Definition: TRandom.h:66
TString fFormula
Definition: TFormula.h:123
TString fName
Definition: TNamed.h:36
virtual TH1 * DoCreateHistogram(Double_t xmin, Double_t xmax, Bool_t recreate=kFALSE)
Create histogram with bin content equal to function value computed at the bin center This histogram w...
Definition: TF1.cxx:2767
Bool_t IsValid() const
Return true if the method call has been properly initialized and is usable.
virtual void SetMarkerSize(Size_t msize=1)
Set the marker size.
Definition: TAttMarker.h:46
static IntegrationMultiDim::Type DefaultIntegratorType()
TGraphErrors * gr
Definition: legend1.C:25
REAL epsilon
Definition: triangle.c:617
virtual Double_t GetMinimum(Double_t minval=-FLT_MAX) const
Return minimum value larger than minval of bins in the range, unless the value has been overridden by...
Definition: TH1.cxx:7749
void InitWithPrototype(TClass *cl, const char *method, const char *proto, Bool_t objectIsConst=kFALSE, ROOT::EFunctionMatchMode mode=ROOT::kConversionMatch)
Initialize the method invocation environment.
#define R__LOCKGUARD2(mutex)
static void CalcGaussLegendreSamplingPoints(Int_t num, Double_t *x, Double_t *w, Double_t eps=3.0e-11)
Type safe interface (static method) The number of sampling points are taken from the TGraph...
Definition: TF1.cxx:3550
Double_t * GetX() const
Definition: TGraph.h:140
PyObject * fType
Class for finding the root of a one dimensional function using the Brent algorithm.
virtual Color_t GetLineColor() const
Return the line color.
Definition: TAttLine.h:39
virtual void SetMaximum(Double_t maximum=-1111)
Set the maximum value along Y for this function In case the function is already drawn, set also the maximum in the helper histogram.
Definition: TF1.cxx:3117
virtual Int_t FindBin(Double_t x)
Find bin number corresponding to abscissa x.
Definition: TAxis.cxx:279
virtual void SetTitle(const char *title="")
Set function title if title has the form "fffffff;xxxx;yyyy", it is assumed that the function title i...
Definition: TF1.cxx:3267
static unsigned int total
long Long_t
Definition: RtypesCore.h:50
virtual Int_t ReadClassBuffer(const TClass *cl, void *pointer, const TClass *onfile_class=0)=0
static const std::string & DefaultMinimizerAlgo()
Double_t GetChisquare() const
Definition: TF1.h:336
virtual Double_t Eval(Double_t x, Double_t y=0, Double_t z=0, Double_t t=0) const
Evaluate this function.
Definition: TF1.cxx:1196
void SetMaxFunctionCalls(unsigned int maxfcn)
set maximum of function calls
Definition: Minimizer.h:456
class containg the result of the fit and all the related information (fitted parameter values...
Definition: FitResult.h:52
double Error() const
return integration error
Int_t fNDF
Definition: TF1.h:170
static const double x1[5]
#define ClassImp(name)
Definition: Rtypes.h:279
double f(double x)
void SetFunction(const IGenFunction &)
Set integration function (flag control if function must be copied inside).
double Double_t
Definition: RtypesCore.h:55
std::vector< Double_t > fSave
Definition: TF1.h:177
void SetTolerance(double tol)
set the tolerance
Definition: Minimizer.h:462
std::vector< Double_t > fParErrors
Definition: TF1.h:174
Double_t fXmin
Definition: TF1.h:163
void SetParName(Int_t iparam, const char *name)
Definition: TF1.h:115
Int_t GetParNumber(const char *name) const
Returns the parameter number given a name not very efficient but list of parameters is typically smal...
Definition: TF1.cxx:3570
Double_t AnalyticalIntegral(TF1 *f, Double_t a, Double_t b)
Double_t y[n]
Definition: legend1.C:17
double func(double *x, double *p)
Definition: stressTF1.cxx:213
std::vector< Double_t > fGamma
Array beta. is approximated by x = alpha +beta*r *gamma*r**2.
Definition: TF1.h:181
virtual Double_t GetX(Double_t y, Double_t xmin=0, Double_t xmax=0, Double_t epsilon=1.E-10, Int_t maxiter=100, Bool_t logx=false) const
Returns the X value corresponding to the function value fy for (xmin<x<xmax).
Definition: TF1.cxx:1579
virtual Color_t GetFillColor() const
Return the fill area color.
Definition: TAttFill.h:35
virtual Double_t GetXmax() const
Definition: TF1.h:389
virtual double FValMinimum() const
Return function value at current estimate of the minimum.
void Streamer(TBuffer &b, Int_t version, UInt_t start, UInt_t count, const TClass *onfile_class=0)
Stream a class object.
Definition: TF1Data_v5.cxx:59
Bool_t Contains(const char *pat, ECaseCompare cmp=kExact) const
Definition: TString.h:567
The TH1 histogram class.
Definition: TH1.h:80
you should not use this method at all Int_t Int_t Double_t Double_t Double_t e
Definition: TRolke.cxx:630
static std::string GetName(IntegrationOneDim::Type)
static function to get a string from the enumeration
Definition: Integrator.cxx:67
virtual void SavePrimitive(std::ostream &out, Option_t *option="")
Save primitive as a C++ statement(s) on output stream out.
Definition: TF1.cxx:2921
virtual Double_t Uniform(Double_t x1=1)
Returns a uniform deviate on the interval (0, x1).
Definition: TRandom.cxx:606
std::vector< Double_t > fAlpha
Integral of function binned on fNpx bins.
Definition: TF1.h:179
EAddToList
Definition: TF1.h:156
Double_t fXmin
Definition: TF1Data.h:47
virtual void SetLineStyle(Style_t lstyle)
Set the line style.
Definition: TAttLine.h:48
Template class to wrap any C++ callable object implementing operator() (const double * x) in a multi-...
Array of doubles (64 bits per element).
Definition: TArrayD.h:29
Namespace for new Math classes and functions.
Bool_t IsNull() const
Definition: TString.h:387
virtual void InitArgs(const Double_t *x, const Double_t *params)
Initialize parameters addresses.
Definition: TF1.cxx:2234
std::vector< Double_t > fBeta
Array alpha. for each bin in x the deconvolution r of fIntegral.
Definition: TF1.h:180
void SetParNames(const char *name0="p0", const char *name1="p1", const char *name2="p2", const char *name3="p3", const char *name4="p4", const char *name5="p5", const char *name6="p6", const char *name7="p7", const char *name8="p8", const char *name9="p9", const char *name10="p10")
Set parameter names.
Definition: TF1.cxx:3602
TAxis * GetZaxis()
Definition: TH1.h:326
virtual Double_t GetSave(const Double_t *x)
Get value corresponding to X in array of fSave values.
Definition: TF1.cxx:2052
bool IsEmpty() const
True if a fit result does not exist (even invalid) with parameter values.
Definition: FitResult.h:122
virtual double XMinimum() const
Return current estimate of the position of the minimum.
Mother of all ROOT objects.
Definition: TObject.h:37
you should not use this method at all Int_t Int_t z
Definition: TRolke.cxx:630
Double_t * fParMin
Definition: TF1Data.h:56
TMethodCall * fMethodCall
Pointer to histogram used for visualisation.
Definition: TF1.h:184
Double_t fChisquare
Definition: TF1Data.h:54
virtual Int_t GetNpar() const
Definition: TF1.h:349
virtual Double_t IntegralOneDim(Double_t a, Double_t b, Double_t epsrel, Double_t epsabs, Double_t &err)
Return Integral of function between a and b using the given parameter values and relative and absolut...
Definition: TF1.cxx:2368
virtual void GetParLimits(Int_t ipar, Double_t &parmin, Double_t &parmax) const
Return limits for parameter ipar.
Definition: TF1.cxx:1652
virtual bool SetVariable(unsigned int ivar, const std::string &name, double val, double step)=0
set a new free variable
Double_t * GetY() const
Definition: TGraph.h:141
virtual void Copy(TObject &named) const
Copy this to obj.
Definition: TNamed.cxx:85
User class for performing multidimensional integration.
static Bool_t RejectedPoint()
See TF1::RejectPoint above.
Definition: TF1.cxx:3416
Style_t GetFuncStyle() const
Definition: TStyle.h:221
double f2(const double *x)
Double_t fMaximum
Definition: TF1Data.h:59
virtual Double_t GetMinMaxNDim(Double_t *x, Bool_t findmax, Double_t epsilon=0, Int_t maxiter=0) const
Find the minimum of a function of whatever dimension.
Definition: TF1.cxx:1438
virtual void SetParErrors(const Double_t *errors)
Set errors for all active parameters when calling this function, the array errors must have at least ...
Definition: TF1.cxx:3209
void Execute(const char *, const char *, int *=0)
Execute method on this object with the given parameter string, e.g.
Definition: TMethodCall.h:68
virtual Double_t GetParameter(Int_t ipar) const
Definition: TF1.h:359
virtual void GetRange(Double_t *xmin, Double_t *xmax) const
Return range of a generic N-D function.
Definition: TF1.cxx:1989
void SetNpx(int npx)
Set the number of point used to bracket root using a grid.
virtual Bool_t AddToGlobalList(Bool_t on=kTRUE)
Add to global list of functions (gROOT->GetListOfFunctions() ) return previous status (true if the fu...
Definition: TF1.cxx:660
Short_t Max(Short_t a, Short_t b)
Definition: TMathBase.h:202
1-Dim function class
Definition: TF1.h:149
void MakeZombie()
Definition: TObject.h:47
Int_t IsNaN(Double_t x)
Definition: TMath.h:613
virtual void SetSavedPoint(Int_t point, Double_t value)
Restore value of function saved at point.
Definition: TF1.cxx:3251
A Graph is a graphics object made of two arrays X and Y with npoints each.
Definition: TGraph.h:53
virtual void SetFitResult(const ROOT::Fit::FitResult &result, const Int_t *indpar=0)
Set the result from the fit parameter values, errors, chi2, etc...
Definition: TF1.cxx:3078
TF1 * f1
Definition: legend1.C:11
Param Functor class for Multidimensional functions.
Definition: ParamFunctor.h:209
you should not use this method at all Int_t Int_t Double_t Double_t Double_t Int_t Double_t Double_t Double_t Double_t b
Definition: TRolke.cxx:630
virtual Double_t * GetParameters() const
Definition: TFormula.h:249
const Double_t * GetParameters() const
Definition: TF1.h:88
TF1Parameters * fParams
Definition: TF1.h:189
static std::atomic< Bool_t > fgAddToGlobList
Definition: TF1.h:193
virtual void Print(Option_t *option="") const
Print TNamed name and title.
Definition: TF1.cxx:2640
#define snprintf
Definition: civetweb.c:822
bit set when zooming on Y axis
Definition: TH1.h:176
Color_t GetFuncColor() const
Definition: TStyle.h:220
THist< 1, double, THistStatContent, THistStatUncertainty > TH1D
Definition: THist.hxx:301
#define gPad
Definition: TVirtualPad.h:289
static void AbsValue(Bool_t reject=kTRUE)
Static function: set the fgAbsValue flag.
Definition: TF1.cxx:749
virtual void SetNDF(Int_t ndf)
Set the number of degrees of freedom ndf should be the number of points used in a fit - the number of...
Definition: TF1.cxx:3142
R__EXTERN Int_t gDebug
Definition: Rtypes.h:128
virtual Double_t * GetParameters() const
Definition: TF1.h:365
virtual Double_t IntegralError(Double_t a, Double_t b, const Double_t *params=0, const Double_t *covmat=0, Double_t epsilon=1.E-2)
Return Error on Integral of a parametric function between a and b due to the parameter uncertainties...
Definition: TF1.cxx:2464
virtual TH1 * GetHistogram() const
Return a pointer to the histogram used to visualise the function.
Definition: TF1.cxx:1308
double result[121]
TF1 & operator=(const TF1 &rhs)
Operator =.
Definition: TF1.cxx:696
virtual void SetParameter(Int_t param, Double_t value)
Definition: TF1.h:431
virtual void SetTitle(const char *title)
Change (i.e.
Definition: TH1.cxx:6027
virtual bool Minimize(int maxIter, double absTol=1.E-8, double relTol=1.E-10)
Find minimum position iterating until convergence specified by the absolute and relative tolerance or...
bool SetFunction(const ROOT::Math::IGenFunction &f, double xlow, double xup)
Sets the function for the rest of the algorithms.
void SetNpx(int npx)
Set the number of point used to bracket root using a grid.
virtual Color_t GetMarkerColor() const
Return the marker color.
Definition: TAttMarker.h:36
Double_t * fSave
Definition: TF1Data.h:58
Option_t * GetDrawOption() const
Get option used by the graphics system to draw this object.
Definition: TBrowser.h:108
Functor1D class for one-dimensional functions.
Definition: Functor.h:494
virtual Style_t GetFillStyle() const
Return the fill area style.
Definition: TAttFill.h:36
Double_t Sqrt(Double_t x)
Definition: TMath.h:464
virtual TString GetExpFormula(Option_t *option="") const
Reconstruct the formula expression from the internal TFormula member variables.
std::vector< Double_t > fParMax
Definition: TF1.h:176
virtual Double_t CentralMoment(Double_t n, Double_t a, Double_t b, const Double_t *params=0, Double_t epsilon=0.000001)
Return nth central moment of function between a and b (i.e the n-th moment around the mean value) ...
Definition: TF1.cxx:3463
const Bool_t kTRUE
Definition: Rtypes.h:91
float * q
Definition: THbookFile.cxx:87
void Print(Option_t *option="") const
print the formula and its attributes
Definition: TFormula.cxx:2713
virtual Double_t EvalPar(const Double_t *x, const Double_t *params=0)
Evaluate function with given coordinates and parameters.
Definition: TF1.cxx:1225
virtual void SetTitle(const char *title="")
Set the title of the TNamed.
Definition: TNamed.cxx:155
Bool_t IsValid() const
Definition: TFormula.h:186
virtual void Browse(TBrowser *b)
Browse.
Definition: TF1.cxx:758
double RelError() const
return relative error
double norm(double *x, double *p)
Definition: unuranDistr.cxx:40
Double_t GetXmax() const
Definition: TAxis.h:140
virtual Int_t GetNumber() const
Definition: TF1.h:354
double Error() const
Returns the estimate of the absolute Error of the last derivative calculation.
std::vector< Double_t > fParMin
Definition: TF1.h:175
const Int_t n
Definition: legend1.C:16
Line Attributes class.
Definition: TAttLine.h:24
Double_t fXmax
Definition: TF1.h:164
Long64_t BinarySearch(Long64_t n, const T *array, T value)
Definition: TMath.h:931
static Double_t gErrorTF1
Definition: TF1.cxx:57
double Chi2() const
Chi2 fit value in case of likelihood must be computed ?
Definition: FitResult.h:165
User class for calculating the derivatives of a function.
unsigned int r2[N_CITIES]
Definition: simanTSP.cxx:322
char name[80]
Definition: TGX11.cxx:109
class for adaptive quadrature integration in multi-dimensions using rectangular regions.
virtual void Warning(const char *method, const char *msgfmt,...) const
Issue warning message.
Definition: TObject.cxx:911
TAxis * GetXaxis()
Definition: TH1.h:324
virtual Version_t ReadVersion(UInt_t *start=0, UInt_t *bcnt=0, const TClass *cl=0)=0
virtual const char * GetTitle() const
Returns title of object.
Definition: TNamed.h:52
Double_t fMinimum
Definition: TF1Data.h:60
void GetWeightVectors(double *x, double *w) const
Returns the arrays x and w containing the abscissa and weight of the Gauss-Legendre n-point quadratur...
TAxis * GetZaxis() const
Get z axis of the function. (In case this object is a TF2 or TF3)
Definition: TF1.cxx:2130
void Copy(TAttFill &attfill) const
Copy this fill attributes to a new TAttFill.
Definition: TAttFill.cxx:200
virtual void Paint(Option_t *option="")
Paint this function with its current attributes.
Definition: TF1.cxx:2689
const char * Data() const
Definition: TString.h:349
virtual TObject * DrawDerivative(Option_t *option="al")
Draw derivative of this function.
Definition: TF1.cxx:1136