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