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