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.reset(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 = std::unique_ptr<TF1Parameters>(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 = std::unique_ptr<TF1Parameters>(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 = std::unique_ptr<TFormula>(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 = std::unique_ptr<TMethodCall>(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 
946  // this was before in TFormula destructor
947  {
949  if (gROOT) gROOT->GetListOfFunctions()->Remove(this);
950  }
951 
952  if (fParent) fParent->RecursiveRemove(this);
953 
954 }
955 
956 
957 ////////////////////////////////////////////////////////////////////////////////
958 
959 TF1::TF1(const TF1 &f1) :
961  fXmin(0), fXmax(0), fNpar(0), fNdim(0), fType(EFType::kFormula)
962 {
963  ((TF1 &)f1).Copy(*this);
964 }
965 
966 
967 ////////////////////////////////////////////////////////////////////////////////
968 /// Static function: set the fgAbsValue flag.
969 /// By default TF1::Integral uses the original function value to compute the integral
970 /// However, TF1::Moment, CentralMoment require to compute the integral
971 /// using the absolute value of the function.
972 
974 {
975  fgAbsValue = flag;
976 }
977 
978 
979 ////////////////////////////////////////////////////////////////////////////////
980 /// Browse.
981 
983 {
984  Draw(b ? b->GetDrawOption() : "");
985  gPad->Update();
986 }
987 
988 
989 ////////////////////////////////////////////////////////////////////////////////
990 /// Copy this F1 to a new F1.
991 /// Note that the cached integral with its related arrays are not copied
992 /// (they are also set as transient data members)
993 
994 void TF1::Copy(TObject &obj) const
995 {
996  delete((TF1 &)obj).fHistogram;
997 
998  TNamed::Copy((TF1 &)obj);
999  TAttLine::Copy((TF1 &)obj);
1000  TAttFill::Copy((TF1 &)obj);
1001  TAttMarker::Copy((TF1 &)obj);
1002  ((TF1 &)obj).fXmin = fXmin;
1003  ((TF1 &)obj).fXmax = fXmax;
1004  ((TF1 &)obj).fNpx = fNpx;
1005  ((TF1 &)obj).fNpar = fNpar;
1006  ((TF1 &)obj).fNdim = fNdim;
1007  ((TF1 &)obj).fType = fType;
1008  ((TF1 &)obj).fChisquare = fChisquare;
1009  ((TF1 &)obj).fNpfits = fNpfits;
1010  ((TF1 &)obj).fNDF = fNDF;
1011  ((TF1 &)obj).fMinimum = fMinimum;
1012  ((TF1 &)obj).fMaximum = fMaximum;
1013 
1014  ((TF1 &)obj).fParErrors = fParErrors;
1015  ((TF1 &)obj).fParMin = fParMin;
1016  ((TF1 &)obj).fParMax = fParMax;
1017  ((TF1 &)obj).fParent = fParent;
1018  ((TF1 &)obj).fSave = fSave;
1019  ((TF1 &)obj).fHistogram = 0;
1020  ((TF1 &)obj).fMethodCall = 0;
1021  ((TF1 &)obj).fNormalized = fNormalized;
1022  ((TF1 &)obj).fNormIntegral = fNormIntegral;
1023  ((TF1 &)obj).fFormula = 0;
1024 
1025  if (fFormula) assert(fFormula->GetNpar() == fNpar);
1026 
1027  // use copy-constructor of TMethodCall
1028  TMethodCall *m = (fMethodCall) ? new TMethodCall(*fMethodCall) : nullptr;
1029  ((TF1 &)obj).fMethodCall.reset(m);
1030 
1031  TFormula *formulaToCopy = (fFormula) ? new TFormula(*fFormula) : nullptr;
1032  ((TF1 &)obj).fFormula.reset(formulaToCopy);
1033 
1034  TF1Parameters *paramsToCopy = (fParams) ? new TF1Parameters(*fParams) : nullptr;
1035  ((TF1 &)obj).fParams.reset(paramsToCopy);
1036 
1037  TF1FunctorPointer *functorToCopy = (fFunctor) ? fFunctor->Clone() : nullptr;
1038  ((TF1 &)obj).fFunctor.reset(functorToCopy);
1039 
1040  TF1AbsComposition *comp = nullptr;
1041  if (fComposition) {
1042  comp = (TF1AbsComposition *)fComposition->IsA()->New();
1043  fComposition->Copy(*comp);
1044  }
1045  ((TF1 &)obj).fComposition.reset(comp);
1046 }
1047 
1048 
1049 ////////////////////////////////////////////////////////////////////////////////
1050 /// Make a complete copy of the underlying object. If 'newname' is set,
1051 /// the copy's name will be set to that name.
1052 
1053 TObject* TF1::Clone(const char* newname) const
1054 {
1055 
1056  TF1* obj = (TF1*) TNamed::Clone(newname);
1057 
1058  if (fHistogram) {
1059  obj->fHistogram = (TH1*)fHistogram->Clone();
1060  obj->fHistogram->SetDirectory(0);
1061  }
1062 
1063  return obj;
1064 }
1065 
1066 
1067 ////////////////////////////////////////////////////////////////////////////////
1068 /// Returns the first derivative of the function at point x,
1069 /// computed by Richardson's extrapolation method (use 2 derivative estimates
1070 /// to compute a third, more accurate estimation)
1071 /// first, derivatives with steps h and h/2 are computed by central difference formulas
1072 /// \f[
1073 /// D(h) = \frac{f(x+h) - f(x-h)}{2h}
1074 /// \f]
1075 /// the final estimate
1076 /// \f[
1077 /// D = \frac{4D(h/2) - D(h)}{3}
1078 /// \f]
1079 /// "Numerical Methods for Scientists and Engineers", H.M.Antia, 2nd edition"
1080 ///
1081 /// if the argument params is null, the current function parameters are used,
1082 /// otherwise the parameters in params are used.
1083 ///
1084 /// the argument eps may be specified to control the step size (precision).
1085 /// the step size is taken as eps*(xmax-xmin).
1086 /// the default value (0.001) should be good enough for the vast majority
1087 /// of functions. Give a smaller value if your function has many changes
1088 /// of the second derivative in the function range.
1089 ///
1090 /// Getting the error via TF1::DerivativeError:
1091 /// (total error = roundoff error + interpolation error)
1092 /// the estimate of the roundoff error is taken as follows:
1093 /// \f[
1094 /// err = k\sqrt{f(x)^{2} + x^{2}deriv^{2}}\sqrt{\sum ai^{2}},
1095 /// \f]
1096 /// where k is the double precision, ai are coefficients used in
1097 /// central difference formulas
1098 /// interpolation error is decreased by making the step size h smaller.
1099 ///
1100 /// \author Anna Kreshuk
1101 
1103 {
1104  if (GetNdim() > 1) {
1105  Warning("Derivative", "Function dimension is larger than one");
1106  }
1107 
1109  double xmin, xmax;
1110  GetRange(xmin, xmax);
1111  // this is not optimal (should be used the average x instead of the range)
1112  double h = eps * std::abs(xmax - xmin);
1113  if (h <= 0) h = 0.001;
1114  double der = 0;
1115  if (params) {
1116  ROOT::Math::WrappedTF1 wtf(*(const_cast<TF1 *>(this)));
1117  wtf.SetParameters(params);
1118  der = rd.Derivative1(wtf, x, h);
1119  } else {
1120  // no need to set parameters used a non-parametric wrapper to avoid allocating
1121  // an array with parameter values
1123  der = rd.Derivative1(wf, x, h);
1124  }
1125 
1126  gErrorTF1 = rd.Error();
1127  return der;
1128 
1129 }
1130 
1131 
1132 ////////////////////////////////////////////////////////////////////////////////
1133 /// Returns the second derivative of the function at point x,
1134 /// computed by Richardson's extrapolation method (use 2 derivative estimates
1135 /// to compute a third, more accurate estimation)
1136 /// first, derivatives with steps h and h/2 are computed by central difference formulas
1137 /// \f[
1138 /// D(h) = \frac{f(x+h) - 2f(x) + f(x-h)}{h^{2}}
1139 /// \f]
1140 /// the final estimate
1141 /// \f[
1142 /// D = \frac{4D(h/2) - D(h)}{3}
1143 /// \f]
1144 /// "Numerical Methods for Scientists and Engineers", H.M.Antia, 2nd edition"
1145 ///
1146 /// if the argument params is null, the current function parameters are used,
1147 /// otherwise the parameters in params are used.
1148 ///
1149 /// the argument eps may be specified to control the step size (precision).
1150 /// the step size is taken as eps*(xmax-xmin).
1151 /// the default value (0.001) should be good enough for the vast majority
1152 /// of functions. Give a smaller value if your function has many changes
1153 /// of the second derivative in the function range.
1154 ///
1155 /// Getting the error via TF1::DerivativeError:
1156 /// (total error = roundoff error + interpolation error)
1157 /// the estimate of the roundoff error is taken as follows:
1158 /// \f[
1159 /// err = k\sqrt{f(x)^{2} + x^{2}deriv^{2}}\sqrt{\sum ai^{2}},
1160 /// \f]
1161 /// where k is the double precision, ai are coefficients used in
1162 /// central difference formulas
1163 /// interpolation error is decreased by making the step size h smaller.
1164 ///
1165 /// \author Anna Kreshuk
1166 
1168 {
1169  if (GetNdim() > 1) {
1170  Warning("Derivative2", "Function dimension is larger than one");
1171  }
1172 
1174  double xmin, xmax;
1175  GetRange(xmin, xmax);
1176  // this is not optimal (should be used the average x instead of the range)
1177  double h = eps * std::abs(xmax - xmin);
1178  if (h <= 0) h = 0.001;
1179  double der = 0;
1180  if (params) {
1181  ROOT::Math::WrappedTF1 wtf(*(const_cast<TF1 *>(this)));
1182  wtf.SetParameters(params);
1183  der = rd.Derivative2(wtf, x, h);
1184  } else {
1185  // no need to set parameters used a non-parametric wrapper to avoid allocating
1186  // an array with parameter values
1188  der = rd.Derivative2(wf, x, h);
1189  }
1190 
1191  gErrorTF1 = rd.Error();
1192 
1193  return der;
1194 }
1195 
1196 
1197 ////////////////////////////////////////////////////////////////////////////////
1198 /// Returns the third derivative of the function at point x,
1199 /// computed by Richardson's extrapolation method (use 2 derivative estimates
1200 /// to compute a third, more accurate estimation)
1201 /// first, derivatives with steps h and h/2 are computed by central difference formulas
1202 /// \f[
1203 /// D(h) = \frac{f(x+2h) - 2f(x+h) + 2f(x-h) - f(x-2h)}{2h^{3}}
1204 /// \f]
1205 /// the final estimate
1206 /// \f[
1207 /// D = \frac{4D(h/2) - D(h)}{3}
1208 /// \f]
1209 /// "Numerical Methods for Scientists and Engineers", H.M.Antia, 2nd edition"
1210 ///
1211 /// if the argument params is null, the current function parameters are used,
1212 /// otherwise the parameters in params are used.
1213 ///
1214 /// the argument eps may be specified to control the step size (precision).
1215 /// the step size is taken as eps*(xmax-xmin).
1216 /// the default value (0.001) should be good enough for the vast majority
1217 /// of functions. Give a smaller value if your function has many changes
1218 /// of the second derivative in the function range.
1219 ///
1220 /// Getting the error via TF1::DerivativeError:
1221 /// (total error = roundoff error + interpolation error)
1222 /// the estimate of the roundoff error is taken as follows:
1223 /// \f[
1224 /// err = k\sqrt{f(x)^{2} + x^{2}deriv^{2}}\sqrt{\sum ai^{2}},
1225 /// \f]
1226 /// where k is the double precision, ai are coefficients used in
1227 /// central difference formulas
1228 /// interpolation error is decreased by making the step size h smaller.
1229 ///
1230 /// \author Anna Kreshuk
1231 
1233 {
1234  if (GetNdim() > 1) {
1235  Warning("Derivative3", "Function dimension is larger than one");
1236  }
1237 
1239  double xmin, xmax;
1240  GetRange(xmin, xmax);
1241  // this is not optimal (should be used the average x instead of the range)
1242  double h = eps * std::abs(xmax - xmin);
1243  if (h <= 0) h = 0.001;
1244  double der = 0;
1245  if (params) {
1246  ROOT::Math::WrappedTF1 wtf(*(const_cast<TF1 *>(this)));
1247  wtf.SetParameters(params);
1248  der = rd.Derivative3(wtf, x, h);
1249  } else {
1250  // no need to set parameters used a non-parametric wrapper to avoid allocating
1251  // an array with parameter values
1253  der = rd.Derivative3(wf, x, h);
1254  }
1255 
1256  gErrorTF1 = rd.Error();
1257  return der;
1258 
1259 }
1260 
1261 
1262 ////////////////////////////////////////////////////////////////////////////////
1263 /// Static function returning the error of the last call to the of Derivative's
1264 /// functions
1265 
1267 {
1268  return gErrorTF1;
1269 }
1270 
1271 
1272 ////////////////////////////////////////////////////////////////////////////////
1273 /// Compute distance from point px,py to a function.
1274 ///
1275 /// Compute the closest distance of approach from point px,py to this
1276 /// function. The distance is computed in pixels units.
1277 ///
1278 /// Note that px is called with a negative value when the TF1 is in
1279 /// TGraph or TH1 list of functions. In this case there is no point
1280 /// looking at the histogram axis.
1281 
1283 {
1284  if (!fHistogram) return 9999;
1285  Int_t distance = 9999;
1286  if (px >= 0) {
1287  distance = fHistogram->DistancetoPrimitive(px, py);
1288  if (distance <= 1) return distance;
1289  } else {
1290  px = -px;
1291  }
1292 
1293  Double_t xx[1];
1294  Double_t x = gPad->AbsPixeltoX(px);
1295  xx[0] = gPad->PadtoX(x);
1296  if (xx[0] < fXmin || xx[0] > fXmax) return distance;
1297  Double_t fval = Eval(xx[0]);
1298  Double_t y = gPad->YtoPad(fval);
1299  Int_t pybin = gPad->YtoAbsPixel(y);
1300  return TMath::Abs(py - pybin);
1301 }
1302 
1303 
1304 ////////////////////////////////////////////////////////////////////////////////
1305 /// Draw this function with its current attributes.
1306 ///
1307 /// Possible option values are:
1308 ///
1309 /// option | description
1310 /// -------|----------------------------------------
1311 /// "SAME" | superimpose on top of existing picture
1312 /// "L" | connect all computed points with a straight line
1313 /// "C" | connect all computed points with a smooth curve
1314 /// "FC" | draw a fill area below a smooth curve
1315 ///
1316 /// Note that the default value is "L". Therefore to draw on top
1317 /// of an existing picture, specify option "LSAME"
1318 ///
1319 /// NB. You must use DrawCopy if you want to draw several times the same
1320 /// function in the current canvas.
1321 
1322 void TF1::Draw(Option_t *option)
1323 {
1324  TString opt = option;
1325  opt.ToLower();
1326  if (gPad && !opt.Contains("same")) gPad->Clear();
1327 
1328  AppendPad(option);
1329 
1330  gPad->IncrementPaletteColor(1, opt);
1331 }
1332 
1333 
1334 ////////////////////////////////////////////////////////////////////////////////
1335 /// Draw a copy of this function with its current attributes.
1336 ///
1337 /// This function MUST be used instead of Draw when you want to draw
1338 /// the same function with different parameters settings in the same canvas.
1339 ///
1340 /// Possible option values are:
1341 ///
1342 /// option | description
1343 /// -------|----------------------------------------
1344 /// "SAME" | superimpose on top of existing picture
1345 /// "L" | connect all computed points with a straight line
1346 /// "C" | connect all computed points with a smooth curve
1347 /// "FC" | draw a fill area below a smooth curve
1348 ///
1349 /// Note that the default value is "L". Therefore to draw on top
1350 /// of an existing picture, specify option "LSAME"
1351 
1352 TF1 *TF1::DrawCopy(Option_t *option) const
1353 {
1354  TF1 *newf1 = (TF1 *)this->IsA()->New();
1355  Copy(*newf1);
1356  newf1->AppendPad(option);
1357  newf1->SetBit(kCanDelete);
1358  return newf1;
1359 }
1360 
1361 
1362 ////////////////////////////////////////////////////////////////////////////////
1363 /// Draw derivative of this function
1364 ///
1365 /// An intermediate TGraph object is built and drawn with option.
1366 /// The function returns a pointer to the TGraph object. Do:
1367 ///
1368 /// TGraph *g = (TGraph*)myfunc.DrawDerivative(option);
1369 ///
1370 /// The resulting graph will be drawn into the current pad.
1371 /// If this function is used via the context menu, it recommended
1372 /// to create a new canvas/pad before invoking this function.
1373 
1375 {
1376  TVirtualPad *pad = gROOT->GetSelectedPad();
1377  TVirtualPad *padsav = gPad;
1378  if (pad) pad->cd();
1379 
1380  TGraph *gr = new TGraph(this, "d");
1381  gr->Draw(option);
1382  if (padsav) padsav->cd();
1383  return gr;
1384 }
1385 
1386 
1387 ////////////////////////////////////////////////////////////////////////////////
1388 /// Draw integral of this function
1389 ///
1390 /// An intermediate TGraph object is built and drawn with option.
1391 /// The function returns a pointer to the TGraph object. Do:
1392 ///
1393 /// TGraph *g = (TGraph*)myfunc.DrawIntegral(option);
1394 ///
1395 /// The resulting graph will be drawn into the current pad.
1396 /// If this function is used via the context menu, it recommended
1397 /// to create a new canvas/pad before invoking this function.
1398 
1400 {
1401  TVirtualPad *pad = gROOT->GetSelectedPad();
1402  TVirtualPad *padsav = gPad;
1403  if (pad) pad->cd();
1404 
1405  TGraph *gr = new TGraph(this, "i");
1406  gr->Draw(option);
1407  if (padsav) padsav->cd();
1408  return gr;
1409 }
1410 
1411 
1412 ////////////////////////////////////////////////////////////////////////////////
1413 /// Draw function between xmin and xmax.
1414 
1416 {
1417 // //if(Compile(formula)) return ;
1418  SetRange(xmin, xmax);
1419 
1420  Draw(option);
1421 }
1422 
1423 
1424 ////////////////////////////////////////////////////////////////////////////////
1425 /// Evaluate this function.
1426 ///
1427 /// Computes the value of this function (general case for a 3-d function)
1428 /// at point x,y,z.
1429 /// For a 1-d function give y=0 and z=0
1430 /// The current value of variables x,y,z is passed through x, y and z.
1431 /// The parameters used will be the ones in the array params if params is given
1432 /// otherwise parameters will be taken from the stored data members fParams
1433 
1435 {
1436  if (fType == EFType::kFormula) return fFormula->Eval(x, y, z, t);
1437 
1438  Double_t xx[4] = {x, y, z, t};
1439  Double_t *pp = (Double_t *)fParams->GetParameters();
1440  // if (fType == EFType::kInterpreted)((TF1 *)this)->InitArgs(xx, pp);
1441  return ((TF1 *)this)->EvalPar(xx, pp);
1442 }
1443 
1444 
1445 ////////////////////////////////////////////////////////////////////////////////
1446 /// Evaluate function with given coordinates and parameters.
1447 ///
1448 /// Compute the value of this function at point defined by array x
1449 /// and current values of parameters in array params.
1450 /// If argument params is omitted or equal 0, the internal values
1451 /// of parameters (array fParams) will be used instead.
1452 /// For a 1-D function only x[0] must be given.
1453 /// In case of a multi-dimensional function, the arrays x must be
1454 /// filled with the corresponding number of dimensions.
1455 ///
1456 /// WARNING. In case of an interpreted function (fType=2), it is the
1457 /// user's responsibility to initialize the parameters via InitArgs
1458 /// before calling this function.
1459 /// InitArgs should be called at least once to specify the addresses
1460 /// of the arguments x and params.
1461 /// InitArgs should be called every time these addresses change.
1462 
1463 Double_t TF1::EvalPar(const Double_t *x, const Double_t *params)
1464 {
1465  //fgCurrent = this;
1466 
1467  if (fType == EFType::kFormula) {
1468  assert(fFormula);
1469 
1470  if (fNormalized && fNormIntegral != 0)
1471  return fFormula->EvalPar(x, params) / fNormIntegral;
1472  else
1473  return fFormula->EvalPar(x, params);
1474  }
1475  Double_t result = 0;
1476  if (fType == EFType::kPtrScalarFreeFcn || fType == EFType::kTemplScalar) {
1477  if (fFunctor) {
1478  assert(fParams);
1479  if (params) result = ((TF1FunctorPointerImpl<Double_t> *)fFunctor.get())->fImpl((Double_t *)x, (Double_t *)params);
1480  else result = ((TF1FunctorPointerImpl<Double_t> *)fFunctor.get())->fImpl((Double_t *)x, (Double_t *)fParams->GetParameters());
1481 
1482  } else result = GetSave(x);
1483 
1484  if (fNormalized && fNormIntegral != 0)
1485  result = result / fNormIntegral;
1486 
1487  return result;
1488  }
1489  if (fType == EFType::kInterpreted) {
1490  if (fMethodCall) fMethodCall->Execute(result);
1491  else result = GetSave(x);
1492 
1493  if (fNormalized && fNormIntegral != 0)
1494  result = result / fNormIntegral;
1495 
1496  return result;
1497  }
1498 
1499 #ifdef R__HAS_VECCORE
1500  if (fType == EFType::kTemplVec) {
1501  if (fFunctor) {
1502  if (params) result = EvalParVec(x, params);
1503  else result = EvalParVec(x, (Double_t *) fParams->GetParameters());
1504  }
1505  else {
1506  result = GetSave(x);
1507  }
1508 
1509  if (fNormalized && fNormIntegral != 0)
1510  result = result / fNormIntegral;
1511 
1512  return result;
1513  }
1514 #endif
1515 
1516  if (fType == EFType::kCompositionFcn) {
1517  if (!fComposition)
1518  Error("EvalPar", "Composition function not found");
1519 
1520  result = (*fComposition)(x, params);
1521  }
1522 
1523  return result;
1524 }
1525 
1526 ////////////////////////////////////////////////////////////////////////////////
1527 /// Execute action corresponding to one event.
1528 ///
1529 /// This member function is called when a F1 is clicked with the locator
1530 
1531 void TF1::ExecuteEvent(Int_t event, Int_t px, Int_t py)
1532 {
1533  if (!gPad) return;
1534 
1535  if (fHistogram) fHistogram->ExecuteEvent(event, px, py);
1536 
1537  if (!gPad->GetView()) {
1538  if (event == kMouseMotion) gPad->SetCursor(kHand);
1539  }
1540 }
1541 
1542 
1543 ////////////////////////////////////////////////////////////////////////////////
1544 /// Fix the value of a parameter
1545 /// The specified value will be used in a fit operation
1546 
1548 {
1549  if (ipar < 0 || ipar > GetNpar() - 1) return;
1550  SetParameter(ipar, value);
1551  if (value != 0) SetParLimits(ipar, value, value);
1552  else SetParLimits(ipar, 1, 1);
1553 }
1554 
1555 
1556 ////////////////////////////////////////////////////////////////////////////////
1557 /// Static function returning the current function being processed
1558 
1560 {
1561  ::Warning("TF1::GetCurrent", "This function is obsolete and is working only for the current painted functions");
1562  return fgCurrent;
1563 }
1564 
1565 
1566 ////////////////////////////////////////////////////////////////////////////////
1567 /// Return a pointer to the histogram used to visualise the function
1568 /// Note that this histogram is managed by the function and
1569 /// in same case it is automatically deleted when some TF1 functions are called
1570 /// such as TF1::SetParameters, TF1::SetNpx, TF1::SetRange
1571 /// It is then reccomended either to clone the return object or calling again teh GetHistogram
1572 /// function whenever is needed
1573 
1575 {
1576  if (fHistogram) return fHistogram;
1577 
1578  // histogram has not been yet created - create it
1579  // should not we make this function not const ??
1580  const_cast<TF1 *>(this)->fHistogram = const_cast<TF1 *>(this)->CreateHistogram();
1581  if (!fHistogram) Error("GetHistogram", "Error creating histogram for function %s of type %s", GetName(), IsA()->GetName());
1582  return fHistogram;
1583 }
1584 
1585 
1586 ////////////////////////////////////////////////////////////////////////////////
1587 /// Returns the maximum value of the function
1588 ///
1589 /// Method:
1590 /// First, the grid search is used to bracket the maximum
1591 /// with the step size = (xmax-xmin)/fNpx.
1592 /// This way, the step size can be controlled via the SetNpx() function.
1593 /// If the function is unimodal or if its extrema are far apart, setting
1594 /// the fNpx to a small value speeds the algorithm up many times.
1595 /// Then, Brent's method is applied on the bracketed interval
1596 /// epsilon (default = 1.E-10) controls the relative accuracy (if |x| > 1 )
1597 /// and absolute (if |x| < 1) and maxiter (default = 100) controls the maximum number
1598 /// of iteration of the Brent algorithm
1599 /// If the flag logx is set the grid search is done in log step size
1600 /// This is done automatically if the log scale is set in the current Pad
1601 ///
1602 /// NOTE: see also TF1::GetMaximumX and TF1::GetX
1603 
1605 {
1606  if (xmin >= xmax) {
1607  xmin = fXmin;
1608  xmax = fXmax;
1609  }
1610 
1611  if (!logx && gPad != 0) logx = gPad->GetLogx();
1612 
1614  GInverseFunc g(this);
1616  bm.SetFunction(wf1, xmin, xmax);
1617  bm.SetNpx(fNpx);
1618  bm.SetLogScan(logx);
1619  bm.Minimize(maxiter, epsilon, epsilon);
1620  Double_t x;
1621  x = - bm.FValMinimum();
1622 
1623  return x;
1624 }
1625 
1626 
1627 ////////////////////////////////////////////////////////////////////////////////
1628 /// Returns the X value corresponding to the maximum value of the function
1629 ///
1630 /// Method:
1631 /// First, the grid search is used to bracket the maximum
1632 /// with the step size = (xmax-xmin)/fNpx.
1633 /// This way, the step size can be controlled via the SetNpx() function.
1634 /// If the function is unimodal or if its extrema are far apart, setting
1635 /// the fNpx to a small value speeds the algorithm up many times.
1636 /// Then, Brent's method is applied on the bracketed interval
1637 /// epsilon (default = 1.E-10) controls the relative accuracy (if |x| > 1 )
1638 /// and absolute (if |x| < 1) and maxiter (default = 100) controls the maximum number
1639 /// of iteration of the Brent algorithm
1640 /// If the flag logx is set the grid search is done in log step size
1641 /// This is done automatically if the log scale is set in the current Pad
1642 ///
1643 /// NOTE: see also TF1::GetX
1644 
1646 {
1647  if (xmin >= xmax) {
1648  xmin = fXmin;
1649  xmax = fXmax;
1650  }
1651 
1652  if (!logx && gPad != 0) logx = gPad->GetLogx();
1653 
1655  GInverseFunc g(this);
1657  bm.SetFunction(wf1, xmin, xmax);
1658  bm.SetNpx(fNpx);
1659  bm.SetLogScan(logx);
1660  bm.Minimize(maxiter, epsilon, epsilon);
1661  Double_t x;
1662  x = bm.XMinimum();
1663 
1664  return x;
1665 }
1666 
1667 
1668 ////////////////////////////////////////////////////////////////////////////////
1669 /// Returns the minimum value of the function on the (xmin, xmax) interval
1670 ///
1671 /// Method:
1672 /// First, the grid search is used to bracket the maximum
1673 /// with the step size = (xmax-xmin)/fNpx. This way, the step size
1674 /// can be controlled via the SetNpx() function. If the function is
1675 /// unimodal or if its extrema are far apart, setting the fNpx to
1676 /// a small value speeds the algorithm up many times.
1677 /// Then, Brent's method is applied on the bracketed interval
1678 /// epsilon (default = 1.E-10) controls the relative accuracy (if |x| > 1 )
1679 /// and absolute (if |x| < 1) and maxiter (default = 100) controls the maximum number
1680 /// of iteration of the Brent algorithm
1681 /// If the flag logx is set the grid search is done in log step size
1682 /// This is done automatically if the log scale is set in the current Pad
1683 ///
1684 /// NOTE: see also TF1::GetMaximumX and TF1::GetX
1685 
1687 {
1688  if (xmin >= xmax) {
1689  xmin = fXmin;
1690  xmax = fXmax;
1691  }
1692 
1693  if (!logx && gPad != 0) logx = gPad->GetLogx();
1694 
1697  bm.SetFunction(wf1, xmin, xmax);
1698  bm.SetNpx(fNpx);
1699  bm.SetLogScan(logx);
1700  bm.Minimize(maxiter, epsilon, epsilon);
1701  Double_t x;
1702  x = bm.FValMinimum();
1703 
1704  return x;
1705 }
1706 
1707 ////////////////////////////////////////////////////////////////////////////////
1708 /// Find the minimum of a function of whatever dimension.
1709 /// While GetMinimum works only for 1D function , GetMinimumNDim works for all dimensions
1710 /// since it uses the minimizer interface
1711 /// vector x at beginning will contained the initial point, on exit will contain the result
1712 
1713 Double_t TF1::GetMinMaxNDim(Double_t *x , bool findmax, Double_t epsilon, Int_t maxiter) const
1714 {
1715  R__ASSERT(x != 0);
1716 
1717  int ndim = GetNdim();
1718  if (ndim == 0) {
1719  Error("GetMinimumNDim", "Function of dimension 0 - return Eval(x)");
1720  return (const_cast<TF1 &>(*this))(x);
1721  }
1722 
1723  // create minimizer class
1724  const char *minimName = ROOT::Math::MinimizerOptions::DefaultMinimizerType().c_str();
1725  const char *minimAlgo = ROOT::Math::MinimizerOptions::DefaultMinimizerAlgo().c_str();
1726  ROOT::Math::Minimizer *min = ROOT::Math::Factory::CreateMinimizer(minimName, minimAlgo);
1727 
1728  if (min == 0) {
1729  Error("GetMinimumNDim", "Error creating minimizer %s", minimName);
1730  return 0;
1731  }
1732 
1733  // minimizer will be set using default values
1734  if (epsilon > 0) min->SetTolerance(epsilon);
1735  if (maxiter > 0) min->SetMaxFunctionCalls(maxiter);
1736 
1737  // create wrapper class from TF1 (cannot use Functor, t.b.i.)
1738  ROOT::Math::WrappedMultiFunction<TF1 &> objFunc(const_cast<TF1 &>(*this), ndim);
1739  // create -f(x) when searching for the maximum
1740  GInverseFuncNdim invFunc(const_cast<TF1 *>(this));
1741  ROOT::Math::WrappedMultiFunction<GInverseFuncNdim &> objFuncInv(invFunc, ndim);
1742  if (!findmax)
1743  min->SetFunction(objFunc);
1744  else
1745  min->SetFunction(objFuncInv);
1746 
1747  std::vector<double> rmin(ndim);
1748  std::vector<double> rmax(ndim);
1749  GetRange(&rmin[0], &rmax[0]);
1750  for (int i = 0; i < ndim; ++i) {
1751  const char *xname = 0;
1752  double stepSize = 0.1;
1753  // use range for step size or give some value depending on x if range is not defined
1754  if (rmax[i] > rmin[i])
1755  stepSize = (rmax[i] - rmin[i]) / 100;
1756  else if (std::abs(x[i]) > 1.)
1757  stepSize = 0.1 * x[i];
1758 
1759  // set variable names
1760  if (ndim <= 3) {
1761  if (i == 0) {
1762  xname = "x";
1763  } else if (i == 1) {
1764  xname = "y";
1765  } else {
1766  xname = "z";
1767  }
1768  } else {
1769  xname = TString::Format("x_%d", i);
1770  // arbitrary step sie (should be computed from range)
1771  }
1772 
1773  if (rmin[i] < rmax[i]) {
1774  //Info("GetMinMax","setting limits on %s - [ %f , %f ]",xname,rmin[i],rmax[i]);
1775  min->SetLimitedVariable(i, xname, x[i], stepSize, rmin[i], rmax[i]);
1776  } else {
1777  min->SetVariable(i, xname, x[i], stepSize);
1778  }
1779  }
1780 
1781  bool ret = min->Minimize();
1782  if (!ret) {
1783  Error("GetMinimumNDim", "Error minimizing function %s", GetName());
1784  }
1785  if (min->X()) std::copy(min->X(), min->X() + ndim, x);
1786  double fmin = min->MinValue();
1787  delete min;
1788  // need to revert sign in case looking for maximum
1789  return (findmax) ? -fmin : fmin;
1790 
1791 }
1792 
1793 
1794 ////////////////////////////////////////////////////////////////////////////////
1795 /// Returns the X value corresponding to the minimum value of the function
1796 /// on the (xmin, xmax) interval
1797 ///
1798 /// Method:
1799 /// First, the grid search is used to bracket the maximum
1800 /// with the step size = (xmax-xmin)/fNpx. This way, the step size
1801 /// can be controlled via the SetNpx() function. If the function is
1802 /// unimodal or if its extrema are far apart, setting the fNpx to
1803 /// a small value speeds the algorithm up many times.
1804 /// Then, Brent's method is applied on the bracketed interval
1805 /// epsilon (default = 1.E-10) controls the relative accuracy (if |x| > 1 )
1806 /// and absolute (if |x| < 1) and maxiter (default = 100) controls the maximum number
1807 /// of iteration of the Brent algorithm
1808 /// If the flag logx is set the grid search is done in log step size
1809 /// This is done automatically if the log scale is set in the current Pad
1810 ///
1811 /// NOTE: see also TF1::GetX
1812 
1814 {
1815  if (xmin >= xmax) {
1816  xmin = fXmin;
1817  xmax = fXmax;
1818  }
1819 
1822  bm.SetFunction(wf1, xmin, xmax);
1823  bm.SetNpx(fNpx);
1824  bm.SetLogScan(logx);
1825  bm.Minimize(maxiter, epsilon, epsilon);
1826  Double_t x;
1827  x = bm.XMinimum();
1828 
1829  return x;
1830 }
1831 
1832 
1833 ////////////////////////////////////////////////////////////////////////////////
1834 /// Returns the X value corresponding to the function value fy for (xmin<x<xmax).
1835 /// in other words it can find the roots of the function when fy=0 and successive calls
1836 /// by changing the next call to [xmin+eps,xmax] where xmin is the previous root.
1837 ///
1838 /// Method:
1839 /// First, the grid search is used to bracket the maximum
1840 /// with the step size = (xmax-xmin)/fNpx. This way, the step size
1841 /// can be controlled via the SetNpx() function. If the function is
1842 /// unimodal or if its extrema are far apart, setting the fNpx to
1843 /// a small value speeds the algorithm up many times.
1844 /// Then, Brent's method is applied on the bracketed interval
1845 /// epsilon (default = 1.E-10) controls the relative accuracy (if |x| > 1 )
1846 /// and absolute (if |x| < 1) and maxiter (default = 100) controls the maximum number
1847 /// of iteration of the Brent algorithm
1848 /// If the flag logx is set the grid search is done in log step size
1849 /// This is done automatically if the log scale is set in the current Pad
1850 ///
1851 /// NOTE: see also TF1::GetMaximumX, TF1::GetMinimumX
1852 
1854 {
1855  if (xmin >= xmax) {
1856  xmin = fXmin;
1857  xmax = fXmax;
1858  }
1859 
1860  if (!logx && gPad != 0) logx = gPad->GetLogx();
1861 
1862  GFunc g(this, fy);
1865  brf.SetFunction(wf1, xmin, xmax);
1866  brf.SetNpx(fNpx);
1867  brf.SetLogScan(logx);
1868  bool ret = brf.Solve(maxiter, epsilon, epsilon);
1869  if (!ret) Error("GetX","[%f,%f] is not a valid interval",xmin,xmax);
1870  return (ret) ? brf.Root() : TMath::QuietNaN();
1871 }
1872 
1873 ////////////////////////////////////////////////////////////////////////////////
1874 /// Return the number of degrees of freedom in the fit
1875 /// the fNDF parameter has been previously computed during a fit.
1876 /// The number of degrees of freedom corresponds to the number of points
1877 /// used in the fit minus the number of free parameters.
1878 
1880 {
1881  Int_t npar = GetNpar();
1882  if (fNDF == 0 && (fNpfits > npar)) return fNpfits - npar;
1883  return fNDF;
1884 }
1885 
1886 
1887 ////////////////////////////////////////////////////////////////////////////////
1888 /// Return the number of free parameters
1889 
1891 {
1892  Int_t ntot = GetNpar();
1893  Int_t nfree = ntot;
1894  Double_t al, bl;
1895  for (Int_t i = 0; i < ntot; i++) {
1896  ((TF1 *)this)->GetParLimits(i, al, bl);
1897  if (al * bl != 0 && al >= bl) nfree--;
1898  }
1899  return nfree;
1900 }
1901 
1902 
1903 ////////////////////////////////////////////////////////////////////////////////
1904 /// Redefines TObject::GetObjectInfo.
1905 /// Displays the function info (x, function value)
1906 /// corresponding to cursor position px,py
1907 
1908 char *TF1::GetObjectInfo(Int_t px, Int_t /* py */) const
1909 {
1910  static char info[64];
1911  Double_t x = gPad->PadtoX(gPad->AbsPixeltoX(px));
1912  snprintf(info, 64, "(x=%g, f=%g)", x, ((TF1 *)this)->Eval(x));
1913  return info;
1914 }
1915 
1916 
1917 ////////////////////////////////////////////////////////////////////////////////
1918 /// Return value of parameter number ipar
1919 
1921 {
1922  if (ipar < 0 || ipar > GetNpar() - 1) return 0;
1923  return fParErrors[ipar];
1924 }
1925 
1926 
1927 ////////////////////////////////////////////////////////////////////////////////
1928 /// Return limits for parameter ipar.
1929 
1930 void TF1::GetParLimits(Int_t ipar, Double_t &parmin, Double_t &parmax) const
1931 {
1932  parmin = 0;
1933  parmax = 0;
1934  int n = fParMin.size();
1935  assert(n == int(fParMax.size()) && n <= fNpar);
1936  if (ipar < 0 || ipar > n - 1) return;
1937  parmin = fParMin[ipar];
1938  parmax = fParMax[ipar];
1939 }
1940 
1941 
1942 ////////////////////////////////////////////////////////////////////////////////
1943 /// Return the fit probability
1944 
1946 {
1947  if (fNDF <= 0) return 0;
1948  return TMath::Prob(fChisquare, fNDF);
1949 }
1950 
1951 
1952 ////////////////////////////////////////////////////////////////////////////////
1953 /// Compute Quantiles for density distribution of this function
1954 ///
1955 /// Quantile x_q of a probability distribution Function F is defined as
1956 /// \f[
1957 /// F(x_{q}) = \int_{xmin}^{x_{q}} f dx = q with 0 <= q <= 1.
1958 /// \f]
1959 /// For instance the median \f$ x_{\frac{1}{2}} \f$ of a distribution is defined as that value
1960 /// of the random variable for which the distribution function equals 0.5:
1961 /// \f[
1962 /// F(x_{\frac{1}{2}}) = \prod(x < x_{\frac{1}{2}}) = \frac{1}{2}
1963 /// \f]
1964 ///
1965 /// \param[in] nprobSum maximum size of array q and size of array probSum
1966 /// \param[out] q array filled with nq quantiles
1967 /// \param[in] probSum array of positions where quantiles will be computed.
1968 /// It is assumed to contain at least nprobSum values.
1969 /// \return value nq (<=nprobSum) with the number of quantiles computed
1970 ///
1971 /// Getting quantiles from two histograms and storing results in a TGraph,
1972 /// a so-called QQ-plot
1973 ///
1974 /// TGraph *gr = new TGraph(nprob);
1975 /// f1->GetQuantiles(nprob,gr->GetX());
1976 /// f2->GetQuantiles(nprob,gr->GetY());
1977 /// gr->Draw("alp");
1978 ///
1979 /// \author Eddy Offermann
1980 
1981 
1982 Int_t TF1::GetQuantiles(Int_t nprobSum, Double_t *q, const Double_t *probSum)
1983 {
1984  // LM: change to use fNpx
1985  // should we change code to use a root finder ?
1986  // It should be more precise and more efficient
1987  const Int_t npx = TMath::Max(fNpx, 2 * nprobSum);
1988  const Double_t xMin = GetXmin();
1989  const Double_t xMax = GetXmax();
1990  const Double_t dx = (xMax - xMin) / npx;
1991 
1992  TArrayD integral(npx + 1);
1993  TArrayD alpha(npx);
1994  TArrayD beta(npx);
1995  TArrayD gamma(npx);
1996 
1997  integral[0] = 0;
1998  Int_t intNegative = 0;
1999  Int_t i;
2000  for (i = 0; i < npx; i++) {
2001  Double_t integ = Integral(Double_t(xMin + i * dx), Double_t(xMin + i * dx + dx), 0.0);
2002  if (integ < 0) {
2003  intNegative++;
2004  integ = -integ;
2005  }
2006  integral[i + 1] = integral[i] + integ;
2007  }
2008 
2009  if (intNegative > 0)
2010  Warning("GetQuantiles", "function:%s has %d negative values: abs assumed",
2011  GetName(), intNegative);
2012  if (integral[npx] == 0) {
2013  Error("GetQuantiles", "Integral of function is zero");
2014  return 0;
2015  }
2016 
2017  const Double_t total = integral[npx];
2018  for (i = 1; i <= npx; i++) integral[i] /= total;
2019  //the integral r for each bin is approximated by a parabola
2020  // x = alpha + beta*r +gamma*r**2
2021  // compute the coefficients alpha, beta, gamma for each bin
2022  for (i = 0; i < npx; i++) {
2023  const Double_t x0 = xMin + dx * i;
2024  const Double_t r2 = integral[i + 1] - integral[i];
2025  const Double_t r1 = Integral(x0, x0 + 0.5 * dx, 0.0) / total;
2026  gamma[i] = (2 * r2 - 4 * r1) / (dx * dx);
2027  beta[i] = r2 / dx - gamma[i] * dx;
2028  alpha[i] = x0;
2029  gamma[i] *= 2;
2030  }
2031 
2032  // Be careful because of finite precision in the integral; Use the fact that the integral
2033  // is monotone increasing
2034  for (i = 0; i < nprobSum; i++) {
2035  const Double_t r = probSum[i];
2036  Int_t bin = TMath::Max(TMath::BinarySearch(npx + 1, integral.GetArray(), r), (Long64_t)0);
2037  // in case the prob is 1
2038  if (bin == npx) {
2039  q[i] = xMax;
2040  continue;
2041  }
2042  // LM use a tolerance 1.E-12 (integral precision)
2043  while (bin < npx - 1 && TMath::AreEqualRel(integral[bin + 1], r, 1E-12)) {
2044  if (TMath::AreEqualRel(integral[bin + 2], r, 1E-12)) bin++;
2045  else break;
2046  }
2047 
2048  const Double_t rr = r - integral[bin];
2049  if (rr != 0.0) {
2050  Double_t xx = 0.0;
2051  const Double_t fac = -2.*gamma[bin] * rr / beta[bin] / beta[bin];
2052  if (fac != 0 && fac <= 1)
2053  xx = (-beta[bin] + TMath::Sqrt(beta[bin] * beta[bin] + 2 * gamma[bin] * rr)) / gamma[bin];
2054  else if (beta[bin] != 0.)
2055  xx = rr / beta[bin];
2056  q[i] = alpha[bin] + xx;
2057  } else {
2058  q[i] = alpha[bin];
2059  if (integral[bin + 1] == r) q[i] += dx;
2060  }
2061  }
2062 
2063  return nprobSum;
2064 }
2065 ////////////////////////////////////////////////////////////////////////////////
2066 ///
2067 /// Compute the cumulative function at fNpx points between fXmin and fXmax.
2068 /// Option can be used to force a log scale (option = "log"), linear (option = "lin") or automatic if empty.
2070 
2071  fIntegral.resize(fNpx + 1);
2072  fAlpha.resize(fNpx + 1);
2073  fBeta.resize(fNpx);
2074  fGamma.resize(fNpx);
2075  fIntegral[0] = 0;
2076  fAlpha[fNpx] = 0;
2077  Double_t integ;
2078  Int_t intNegative = 0;
2079  Int_t i;
2080  Bool_t logbin = kFALSE;
2081  Double_t dx;
2082  Double_t xmin = fXmin;
2083  Double_t xmax = fXmax;
2084  TString opt(option);
2085  opt.ToUpper();
2086  // perform a log binning if specified by user (option="Log") or if some conditions are met
2087  // and the user explicitly does not specify a Linear binning option
2088  if (opt.Contains("LOG") || ((xmin > 0 && xmax / xmin > fNpx) && !opt.Contains("LIN"))) {
2089  logbin = kTRUE;
2090  fAlpha[fNpx] = 1;
2091  xmin = TMath::Log10(fXmin);
2092  xmax = TMath::Log10(fXmax);
2093  if (gDebug)
2094  Info("GetRandom", "Use log scale for tabulating the integral in [%f,%f] with %d points", fXmin, fXmax, fNpx);
2095  }
2096  dx = (xmax - xmin) / fNpx;
2097 
2098  std::vector<Double_t> xx(fNpx + 1);
2099  for (i = 0; i < fNpx; i++) {
2100  xx[i] = xmin + i * dx;
2101  }
2102  xx[fNpx] = xmax;
2103  for (i = 0; i < fNpx; i++) {
2104  if (logbin) {
2105  integ = Integral(TMath::Power(10, xx[i]), TMath::Power(10, xx[i + 1]), 0.0);
2106  } else {
2107  integ = Integral(xx[i], xx[i + 1], 0.0);
2108  }
2109  if (integ < 0) {
2110  intNegative++;
2111  integ = -integ;
2112  }
2113  fIntegral[i + 1] = fIntegral[i] + integ;
2114  }
2115  if (intNegative > 0) {
2116  Warning("GetRandom", "function:%s has %d negative values: abs assumed", GetName(), intNegative);
2117  }
2118  if (fIntegral[fNpx] == 0) {
2119  Error("GetRandom", "Integral of function is zero");
2120  return kFALSE;
2121  }
2123  for (i = 1; i <= fNpx; i++) { // normalize integral to 1
2124  fIntegral[i] /= total;
2125  }
2126  // the integral r for each bin is approximated by a parabola
2127  // x = alpha + beta*r +gamma*r**2
2128  // compute the coefficients alpha, beta, gamma for each bin
2129  Double_t x0, r1, r2, r3;
2130  for (i = 0; i < fNpx; i++) {
2131  x0 = xx[i];
2132  r2 = fIntegral[i + 1] - fIntegral[i];
2133  if (logbin)
2134  r1 = Integral(TMath::Power(10, x0), TMath::Power(10, x0 + 0.5 * dx), 0.0) / total;
2135  else
2136  r1 = Integral(x0, x0 + 0.5 * dx, 0.0) / total;
2137  r3 = 2 * r2 - 4 * r1;
2138  if (TMath::Abs(r3) > 1e-8)
2139  fGamma[i] = r3 / (dx * dx);
2140  else
2141  fGamma[i] = 0;
2142  fBeta[i] = r2 / dx - fGamma[i] * dx;
2143  fAlpha[i] = x0;
2144  fGamma[i] *= 2;
2145  }
2146  return kTRUE;
2147 }
2148 
2149 ////////////////////////////////////////////////////////////////////////////////
2150 /// Return a random number following this function shape.
2151 ///
2152 /// @param rng Random number generator. By default (or when passing a nullptr) the global gRandom is used
2153 /// @param option Option string which controls the binning used to compute the integral. Default mode is automatic depending of
2154 /// xmax, xmin and Npx (function points).
2155 /// Possible values are:
2156 /// - "LOG" to force usage of log scale for tabulating the integral
2157 /// - "LIN" to force usage of linear scale when tabulating the integral
2158 ///
2159 /// The distribution contained in the function fname (TF1) is integrated
2160 /// over the channel contents.
2161 /// It is normalized to 1.
2162 /// For each bin the integral is approximated by a parabola.
2163 /// The parabola coefficients are stored as non persistent data members
2164 /// Getting one random number implies:
2165 /// - Generating a random number between 0 and 1 (say r1)
2166 /// - Look in which bin in the normalized integral r1 corresponds to
2167 /// - Evaluate the parabolic curve in the selected bin to find the corresponding X value.
2168 ///
2169 /// The user can provide as optional parameter a Random number generator.
2170 /// By default gRandom is used
2171 ///
2172 /// If the ratio fXmax/fXmin > fNpx the integral is tabulated in log scale in x
2173 /// A log scale for the intergral is also always used if a user specifies the "LOG" option
2174 /// Instead if a user requestes a "LIN" option the integral binning is never done in log scale
2175 /// whatever the fXmax/fXmin ratio is
2176 ///
2177 /// Note that the parabolic approximation is very good as soon as the number of bins is greater than 50.
2178 
2179 
2181 {
2182  // Check if integral array must be build
2183  if (fIntegral.size() == 0) {
2184  Bool_t ret = ComputeCdfTable(option);
2185  if (!ret) return TMath::QuietNaN();
2186  }
2187 
2188 
2189  // return random number
2190  Double_t r = (rng) ? rng->Rndm() : gRandom->Rndm();
2191  Int_t bin = TMath::BinarySearch(fNpx, fIntegral.data(), r);
2192  Double_t rr = r - fIntegral[bin];
2193 
2194  Double_t yy;
2195  if (fGamma[bin] != 0)
2196  yy = (-fBeta[bin] + TMath::Sqrt(fBeta[bin] * fBeta[bin] + 2 * fGamma[bin] * rr)) / fGamma[bin];
2197  else
2198  yy = rr / fBeta[bin];
2199  Double_t x = fAlpha[bin] + yy;
2200  if (fAlpha[fNpx] > 0) return TMath::Power(10, x);
2201  return x;
2202 }
2203 
2204 
2205 ////////////////////////////////////////////////////////////////////////////////
2206 /// Return a random number following this function shape in [xmin,xmax]
2207 ///
2208 /// The distribution contained in the function fname (TF1) is integrated
2209 /// over the channel contents.
2210 /// It is normalized to 1.
2211 /// For each bin the integral is approximated by a parabola.
2212 /// The parabola coefficients are stored as non persistent data members
2213 /// Getting one random number implies:
2214 /// - Generating a random number between 0 and 1 (say r1)
2215 /// - Look in which bin in the normalized integral r1 corresponds to
2216 /// - Evaluate the parabolic curve in the selected bin to find
2217 /// the corresponding X value.
2218 ///
2219 /// The parabolic approximation is very good as soon as the number
2220 /// of bins is greater than 50.
2221 ///
2222 /// @param xmin minimum value for generated random numbers
2223 /// @param xmax maximum value for generated random numbers
2224 /// @param rng (optional) random number generator pointer
2225 /// @param option (optional) : `LOG` or `LIN` to force the usage of a log or linear scale for computing the cumulative integral table
2226 ///
2227 /// IMPORTANT NOTE
2228 ///
2229 /// The integral of the function is computed at fNpx points. If the function
2230 /// has sharp peaks, you should increase the number of points (SetNpx)
2231 /// such that the peak is correctly tabulated at several points.
2232 
2234 {
2235  // Check if integral array must be build
2236  if (fIntegral.size() == 0) {
2237  Bool_t ret = ComputeCdfTable(option);
2238  if (!ret) return TMath::QuietNaN();
2239  }
2240 
2241  // return random number
2242  Double_t dx = (fXmax - fXmin) / fNpx;
2243  Int_t nbinmin = (Int_t)((xmin - fXmin) / dx);
2244  Int_t nbinmax = (Int_t)((xmax - fXmin) / dx) + 2;
2245  if (nbinmax > fNpx) nbinmax = fNpx;
2246 
2247  Double_t pmin = fIntegral[nbinmin];
2248  Double_t pmax = fIntegral[nbinmax];
2249 
2250  Double_t r, x, xx, rr;
2251  do {
2252  r = (rng) ? rng->Uniform(pmin, pmax) : gRandom->Uniform(pmin, pmax);
2253 
2254  Int_t bin = TMath::BinarySearch(fNpx, fIntegral.data(), r);
2255  rr = r - fIntegral[bin];
2256 
2257  if (fGamma[bin] != 0)
2258  xx = (-fBeta[bin] + TMath::Sqrt(fBeta[bin] * fBeta[bin] + 2 * fGamma[bin] * rr)) / fGamma[bin];
2259  else
2260  xx = rr / fBeta[bin];
2261  x = fAlpha[bin] + xx;
2262  } while (x < xmin || x > xmax);
2263  return x;
2264 }
2265 
2266 ////////////////////////////////////////////////////////////////////////////////
2267 /// Return range of a generic N-D function.
2268 
2269 void TF1::GetRange(Double_t *rmin, Double_t *rmax) const
2270 {
2271  int ndim = GetNdim();
2272 
2273  double xmin = 0, ymin = 0, zmin = 0, xmax = 0, ymax = 0, zmax = 0;
2274  GetRange(xmin, ymin, zmin, xmax, ymax, zmax);
2275  for (int i = 0; i < ndim; ++i) {
2276  if (i == 0) {
2277  rmin[0] = xmin;
2278  rmax[0] = xmax;
2279  } else if (i == 1) {
2280  rmin[1] = ymin;
2281  rmax[1] = ymax;
2282  } else if (i == 2) {
2283  rmin[2] = zmin;
2284  rmax[2] = zmax;
2285  } else {
2286  rmin[i] = 0;
2287  rmax[i] = 0;
2288  }
2289  }
2290 }
2291 
2292 
2293 ////////////////////////////////////////////////////////////////////////////////
2294 /// Return range of a 1-D function.
2295 
2297 {
2298  xmin = fXmin;
2299  xmax = fXmax;
2300 }
2301 
2302 
2303 ////////////////////////////////////////////////////////////////////////////////
2304 /// Return range of a 2-D function.
2305 
2307 {
2308  xmin = fXmin;
2309  xmax = fXmax;
2310  ymin = 0;
2311  ymax = 0;
2312 }
2313 
2314 
2315 ////////////////////////////////////////////////////////////////////////////////
2316 /// Return range of function.
2317 
2319 {
2320  xmin = fXmin;
2321  xmax = fXmax;
2322  ymin = 0;
2323  ymax = 0;
2324  zmin = 0;
2325  zmax = 0;
2326 }
2327 
2328 
2329 ////////////////////////////////////////////////////////////////////////////////
2330 /// Get value corresponding to X in array of fSave values
2331 
2333 {
2334  if (fSave.size() == 0) return 0;
2335  //if (fSave == 0) return 0;
2336  int fNsave = fSave.size();
2337  Double_t x = Double_t(xx[0]);
2338  Double_t y, dx, xmin, xmax, xlow, xup, ylow, yup;
2339  if (fParent && fParent->InheritsFrom(TH1::Class())) {
2340  //if parent is a histogram the function had been saved at the center of the bins
2341  //we make a linear interpolation between the saved values
2342  xmin = fSave[fNsave - 3];
2343  xmax = fSave[fNsave - 2];
2344  if (fSave[fNsave - 1] == xmax) {
2345  TH1 *h = (TH1 *)fParent;
2346  TAxis *xaxis = h->GetXaxis();
2347  Int_t bin1 = xaxis->FindBin(xmin);
2348  Int_t binup = xaxis->FindBin(xmax);
2349  Int_t bin = xaxis->FindBin(x);
2350  if (bin < binup) {
2351  xlow = xaxis->GetBinCenter(bin);
2352  xup = xaxis->GetBinCenter(bin + 1);
2353  ylow = fSave[bin - bin1];
2354  yup = fSave[bin - bin1 + 1];
2355  } else {
2356  xlow = xaxis->GetBinCenter(bin - 1);
2357  xup = xaxis->GetBinCenter(bin);
2358  ylow = fSave[bin - bin1 - 1];
2359  yup = fSave[bin - bin1];
2360  }
2361  dx = xup - xlow;
2362  y = ((xup * ylow - xlow * yup) + x * (yup - ylow)) / dx;
2363  return y;
2364  }
2365  }
2366  Int_t np = fNsave - 3;
2367  xmin = Double_t(fSave[np + 1]);
2368  xmax = Double_t(fSave[np + 2]);
2369  dx = (xmax - xmin) / np;
2370  if (x < xmin || x > xmax) return 0;
2371  // return a Nan in case of x=nan, otherwise will crash later
2372  if (TMath::IsNaN(x)) return x;
2373  if (dx <= 0) return 0;
2374 
2375  Int_t bin = Int_t((x - xmin) / dx);
2376  xlow = xmin + bin * dx;
2377  xup = xlow + dx;
2378  ylow = fSave[bin];
2379  yup = fSave[bin + 1];
2380  y = ((xup * ylow - xlow * yup) + x * (yup - ylow)) / dx;
2381  return y;
2382 }
2383 
2384 
2385 ////////////////////////////////////////////////////////////////////////////////
2386 /// Get x axis of the function.
2387 
2389 {
2390  TH1 *h = GetHistogram();
2391  if (!h) return 0;
2392  return h->GetXaxis();
2393 }
2394 
2395 
2396 ////////////////////////////////////////////////////////////////////////////////
2397 /// Get y axis of the function.
2398 
2400 {
2401  TH1 *h = GetHistogram();
2402  if (!h) return 0;
2403  return h->GetYaxis();
2404 }
2405 
2406 
2407 ////////////////////////////////////////////////////////////////////////////////
2408 /// Get z axis of the function. (In case this object is a TF2 or TF3)
2409 
2411 {
2412  TH1 *h = GetHistogram();
2413  if (!h) return 0;
2414  return h->GetZaxis();
2415 }
2416 
2417 
2418 
2419 ////////////////////////////////////////////////////////////////////////////////
2420 /// Compute the gradient (derivative) wrt a parameter ipar
2421 ///
2422 /// \param ipar index of parameter for which the derivative is computed
2423 /// \param x point, where the derivative is computed
2424 /// \param eps - if the errors of parameters have been computed, the step used in
2425 /// numerical differentiation is eps*parameter_error.
2426 ///
2427 /// if the errors have not been computed, step=eps is used
2428 /// default value of eps = 0.01
2429 /// Method is the same as in Derivative() function
2430 ///
2431 /// If a parameter is fixed, the gradient on this parameter = 0
2432 
2434 {
2435  return GradientParTempl<Double_t>(ipar, x, eps);
2436 }
2437 
2438 ////////////////////////////////////////////////////////////////////////////////
2439 /// Compute the gradient wrt parameters
2440 /// If the TF1 object is based on a formula expression (TFormula)
2441 /// and TFormula::GenerateGradientPar() has been successfully called
2442 /// automatic differentiation using CLAD is used instead of the default
2443 /// numerical differentiation
2444 ///
2445 /// \param x point, were the gradient is computed
2446 /// \param grad used to return the computed gradient, assumed to be of at least fNpar size
2447 /// \param eps if the errors of parameters have been computed, the step used in
2448 /// numerical differentiation is eps*parameter_error.
2449 ///
2450 /// if the errors have not been computed, step=eps is used
2451 /// default value of eps = 0.01
2452 /// Method is the same as in Derivative() function
2453 ///
2454 /// If a parameter is fixed, the gradient on this parameter = 0
2455 
2456 void TF1::GradientPar(const Double_t *x, Double_t *grad, Double_t eps)
2457 {
2458  if (fFormula && fFormula->HasGeneratedGradient())
2459  fFormula->GradientPar(x,grad);
2460  else
2461  GradientParTempl<Double_t>(x, grad, eps);
2462 }
2463 
2464 ////////////////////////////////////////////////////////////////////////////////
2465 /// Initialize parameters addresses.
2466 
2467 void TF1::InitArgs(const Double_t *x, const Double_t *params)
2468 {
2469  if (fMethodCall) {
2470  Long_t args[2];
2471  args[0] = (Long_t)x;
2472  if (params) args[1] = (Long_t)params;
2473  else args[1] = (Long_t)GetParameters();
2474  fMethodCall->SetParamPtrs(args);
2475  }
2476 }
2477 
2478 
2479 ////////////////////////////////////////////////////////////////////////////////
2480 /// Create the basic function objects
2481 
2483 {
2484  TF1 *f1;
2486  if (!gROOT->GetListOfFunctions()->FindObject("gaus")) {
2487  f1 = new TF1("gaus", "gaus", -1, 1);
2488  f1->SetParameters(1, 0, 1);
2489  f1 = new TF1("gausn", "gausn", -1, 1);
2490  f1->SetParameters(1, 0, 1);
2491  f1 = new TF1("landau", "landau", -1, 1);
2492  f1->SetParameters(1, 0, 1);
2493  f1 = new TF1("landaun", "landaun", -1, 1);
2494  f1->SetParameters(1, 0, 1);
2495  f1 = new TF1("expo", "expo", -1, 1);
2496  f1->SetParameters(1, 1);
2497  for (Int_t i = 0; i < 10; i++) {
2498  f1 = new TF1(Form("pol%d", i), Form("pol%d", i), -1, 1);
2499  f1->SetParameters(1, 1, 1, 1, 1, 1, 1, 1, 1, 1);
2500  // create also chebyshev polynomial
2501  // (note polynomial object will not be deleted)
2502  // note that these functions cannot be stored
2504  Double_t min = -1;
2505  Double_t max = 1;
2506  f1 = new TF1(TString::Format("chebyshev%d", i), pol, min, max, i + 1, 1);
2507  f1->SetParameters(1, 1, 1, 1, 1, 1, 1, 1, 1, 1);
2508  }
2509 
2510  }
2511 }
2512 ////////////////////////////////////////////////////////////////////////////////
2513 /// IntegralOneDim or analytical integral
2514 
2516 {
2517  Double_t error = 0;
2518  if (GetNumber() > 0) {
2519  Double_t result = 0.;
2520  if (gDebug) {
2521  Info("computing analytical integral for function %s with number %d", GetName(), GetNumber());
2522  }
2523  result = AnalyticalIntegral(this, a, b);
2524  // if it is a formula that havent been implemented in analytical integral a NaN is return
2525  if (!TMath::IsNaN(result)) return result;
2526  if (gDebug)
2527  Warning("analytical integral not available for %s - with number %d compute numerical integral", GetName(), GetNumber());
2528  }
2529  return IntegralOneDim(a, b, epsrel, epsrel, error);
2530 }
2531 
2532 ////////////////////////////////////////////////////////////////////////////////
2533 /// Return Integral of function between a and b using the given parameter values and
2534 /// relative and absolute tolerance.
2535 ///
2536 /// The default integrator defined in ROOT::Math::IntegratorOneDimOptions::DefaultIntegrator() is used
2537 /// If ROOT contains the MathMore library the default integrator is set to be
2538 /// the adaptive ROOT::Math::GSLIntegrator (based on QUADPACK) or otherwise the
2539 /// ROOT::Math::GaussIntegrator is used
2540 /// See the reference documentation of these classes for more information about the
2541 /// integration algorithms
2542 /// To change integration algorithm just do :
2543 /// ROOT::Math::IntegratorOneDimOptions::SetDefaultIntegrator(IntegratorName);
2544 /// Valid integrator names are:
2545 /// - Gauss : for ROOT::Math::GaussIntegrator
2546 /// - GaussLegendre : for ROOT::Math::GaussLegendreIntegrator
2547 /// - Adaptive : for ROOT::Math::GSLIntegrator adaptive method (QAG)
2548 /// - AdaptiveSingular : for ROOT::Math::GSLIntegrator adaptive singular method (QAGS)
2549 /// - NonAdaptive : for ROOT::Math::GSLIntegrator non adaptive (QNG)
2550 ///
2551 /// In order to use the GSL integrators one needs to have the MathMore library installed
2552 ///
2553 /// Note 1:
2554 ///
2555 /// Values of the function f(x) at the interval end-points A and B are not
2556 /// required. The subprogram may therefore be used when these values are
2557 /// undefined.
2558 ///
2559 /// Note 2:
2560 ///
2561 /// Instead of TF1::Integral, you may want to use the combination of
2562 /// TF1::CalcGaussLegendreSamplingPoints and TF1::IntegralFast.
2563 /// See an example with the following script:
2564 ///
2565 /// ~~~ {.cpp}
2566 /// void gint() {
2567 /// TF1 *g = new TF1("g","gaus",-5,5);
2568 /// g->SetParameters(1,0,1);
2569 /// //default gaus integration method uses 6 points
2570 /// //not suitable to integrate on a large domain
2571 /// double r1 = g->Integral(0,5);
2572 /// double r2 = g->Integral(0,1000);
2573 ///
2574 /// //try with user directives computing more points
2575 /// Int_t np = 1000;
2576 /// double *x=new double[np];
2577 /// double *w=new double[np];
2578 /// g->CalcGaussLegendreSamplingPoints(np,x,w,1e-15);
2579 /// double r3 = g->IntegralFast(np,x,w,0,5);
2580 /// double r4 = g->IntegralFast(np,x,w,0,1000);
2581 /// double r5 = g->IntegralFast(np,x,w,0,10000);
2582 /// double r6 = g->IntegralFast(np,x,w,0,100000);
2583 /// printf("g->Integral(0,5) = %g\n",r1);
2584 /// printf("g->Integral(0,1000) = %g\n",r2);
2585 /// printf("g->IntegralFast(n,x,w,0,5) = %g\n",r3);
2586 /// printf("g->IntegralFast(n,x,w,0,1000) = %g\n",r4);
2587 /// printf("g->IntegralFast(n,x,w,0,10000) = %g\n",r5);
2588 /// printf("g->IntegralFast(n,x,w,0,100000)= %g\n",r6);
2589 /// delete [] x;
2590 /// delete [] w;
2591 /// }
2592 /// ~~~
2593 ///
2594 /// This example produces the following results:
2595 ///
2596 /// ~~~ {.cpp}
2597 /// g->Integral(0,5) = 1.25331
2598 /// g->Integral(0,1000) = 1.25319
2599 /// g->IntegralFast(n,x,w,0,5) = 1.25331
2600 /// g->IntegralFast(n,x,w,0,1000) = 1.25331
2601 /// g->IntegralFast(n,x,w,0,10000) = 1.25331
2602 /// g->IntegralFast(n,x,w,0,100000)= 1.253
2603 /// ~~~
2604 
2606 {
2607  //Double_t *parameters = GetParameters();
2608  TF1_EvalWrapper wf1(this, 0, fgAbsValue);
2609  Double_t result = 0;
2610  Int_t status = 0;
2614  ROOT::Math::GaussIntegrator iod(epsabs, epsrel);
2615  iod.SetFunction(wf1);
2616  if (a != - TMath::Infinity() && b != TMath::Infinity())
2617  result = iod.Integral(a, b);
2618  else if (a == - TMath::Infinity() && b != TMath::Infinity())
2619  result = iod.IntegralLow(b);
2620  else if (a != - TMath::Infinity() && b == TMath::Infinity())
2621  result = iod.IntegralUp(a);
2622  else if (a == - TMath::Infinity() && b == TMath::Infinity())
2623  result = iod.Integral();
2624  error = iod.Error();
2625  status = iod.Status();
2626  } else {
2628  if (a != - TMath::Infinity() && b != TMath::Infinity())
2629  result = iod.Integral(a, b);
2630  else if (a == - TMath::Infinity() && b != TMath::Infinity())
2631  result = iod.IntegralLow(b);
2632  else if (a != - TMath::Infinity() && b == TMath::Infinity())
2633  result = iod.IntegralUp(a);
2634  else if (a == - TMath::Infinity() && b == TMath::Infinity())
2635  result = iod.Integral();
2636  error = iod.Error();
2637  status = iod.Status();
2638  }
2639  if (status != 0) {
2641  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);
2642  TString msg("\t\tFunction Parameters = {");
2643  for (int ipar = 0; ipar < GetNpar(); ++ipar) {
2644  msg += TString::Format(" %s = %f ", GetParName(ipar), GetParameter(ipar));
2645  if (ipar < GetNpar() - 1) msg += TString(",");
2646  else msg += TString("}");
2647  }
2648  Info("IntegralOneDim", "%s", msg.Data());
2649  }
2650  return result;
2651 }
2652 
2653 ////////////////////////////////////////////////////////////////////////////////
2654 /// Return Error on Integral of a parametric function between a and b
2655 /// due to the parameter uncertainties and their covariance matrix from the fit.
2656 /// In addition to the integral limits, this method takes as input a pointer to the fitted parameter values
2657 /// and a pointer the covariance matrix from the fit. These pointers should be retrieved from the
2658 /// previously performed fit using the TFitResult class.
2659 /// Note that to get the TFitResult, te fit should be done using the fit option `S`.
2660 /// Example:
2661 /// ~~~~{.cpp}
2662 /// TFitResultPtr r = histo->Fit(func, "S");
2663 /// func->IntegralError(x1,x2,r->GetParams(), r->GetCovarianceMatrix()->GetMatrixArray() );
2664 /// ~~~~
2665 ///
2666 /// IMPORTANT NOTE1:
2667 ///
2668 /// A null pointer to the parameter values vector and to the covariance matrix can be passed.
2669 /// In this case, when the parameter values pointer is null, the parameter values stored in this
2670 /// TF1 function object are used in the integral error computation.
2671 /// When the poassed pointer to the covariance matrix is null, a covariance matrix from the last fit is retrieved
2672 /// from a global fitter instance when it exists. Note that the global fitter instance
2673 /// esists only when ROOT is not running with multi-threading enabled (ROOT::IsImplicitMTEnabled() == True).
2674 /// When the ovariance matrix from the last fit cannot be retrieved, an error message is printed and a a zero value is
2675 /// returned.
2676 ///
2677 ///
2678 /// IMPORTANT NOTE2:
2679 ///
2680 /// When no covariance matrix is passed and in the meantime a fit is done
2681 /// using another function, the routine will signal an error and it will return zero only
2682 /// when the number of fit parameter is different than the values stored in TF1 (TF1::GetNpar() ).
2683 /// In the case that npar is the same, an incorrect result is returned.
2684 ///
2685 /// IMPORTANT NOTE3:
2686 ///
2687 /// The user must pass a pointer to the elements of the full covariance matrix
2688 /// dimensioned with the right size (npar*npar), where npar is the total number of parameters (TF1::GetNpar()),
2689 /// including also the fixed parameters. The covariance matrix must be retrieved from the TFitResult class as
2690 /// shown above and not from TVirtualFitter::GetCovarianceMatrix() function.
2691 
2693 {
2694  Double_t x1[1];
2695  Double_t x2[1];
2696  x1[0] = a, x2[0] = b;
2697  return ROOT::TF1Helper::IntegralError(this, 1, x1, x2, params, covmat, epsilon);
2698 }
2699 
2700 ////////////////////////////////////////////////////////////////////////////////
2701 /// Return Error on Integral of a parametric function with dimension larger than one
2702 /// between a[] and b[] due to the parameters uncertainties.
2703 /// For a TF1 with dimension larger than 1 (for example a TF2 or TF3)
2704 /// TF1::IntegralMultiple is used for the integral calculation
2705 ///
2706 /// In addition to the integral limits, this method takes as input a pointer to the fitted parameter values
2707 /// and a pointer the covariance matrix from the fit. These pointers should be retrieved from the
2708 /// previously performed fit using the TFitResult class.
2709 /// Note that to get the TFitResult, te fit should be done using the fit option `S`.
2710 /// Example:
2711 /// ~~~~{.cpp}
2712 /// TFitResultPtr r = histo2d->Fit(func2, "S");
2713 /// func2->IntegralError(a,b,r->GetParams(), r->GetCovarianceMatrix()->GetMatrixArray() );
2714 /// ~~~~
2715 ///
2716 /// IMPORTANT NOTE1:
2717 ///
2718 /// A null pointer to the parameter values vector and to the covariance matrix can be passed.
2719 /// In this case, when the parameter values pointer is null, the parameter values stored in this
2720 /// TF1 function object are used in the integral error computation.
2721 /// When the poassed pointer to the covariance matrix is null, a covariance matrix from the last fit is retrieved
2722 /// from a global fitter instance when it exists. Note that the global fitter instance
2723 /// esists only when ROOT is not running with multi-threading enabled (ROOT::IsImplicitMTEnabled() == True).
2724 /// When the ovariance matrix from the last fit cannot be retrieved, an error message is printed and a a zero value is
2725 /// returned.
2726 ///
2727 ///
2728 /// IMPORTANT NOTE2:
2729 ///
2730 /// When no covariance matrix is passed and in the meantime a fit is done
2731 /// using another function, the routine will signal an error and it will return zero only
2732 /// when the number of fit parameter is different than the values stored in TF1 (TF1::GetNpar() ).
2733 /// In the case that npar is the same, an incorrect result is returned.
2734 ///
2735 /// IMPORTANT NOTE3:
2736 ///
2737 /// The user must pass a pointer to the elements of the full covariance matrix
2738 /// dimensioned with the right size (npar*npar), where npar is the total number of parameters (TF1::GetNpar()),
2739 /// including also the fixed parameters. The covariance matrix must be retrieved from the TFitResult class as
2740 /// shown above and not from TVirtualFitter::GetCovarianceMatrix() function.
2741 
2742 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)
2743 {
2744  return ROOT::TF1Helper::IntegralError(this, n, a, b, params, covmat, epsilon);
2745 }
2746 
2747 #ifdef INTHEFUTURE
2748 ////////////////////////////////////////////////////////////////////////////////
2749 /// Gauss-Legendre integral, see CalcGaussLegendreSamplingPoints
2750 
2752 {
2753  if (!g) return 0;
2754  return IntegralFast(g->GetN(), g->GetX(), g->GetY(), a, b, params);
2755 }
2756 #endif
2757 
2758 
2759 ////////////////////////////////////////////////////////////////////////////////
2760 /// Gauss-Legendre integral, see CalcGaussLegendreSamplingPoints
2761 
2763 {
2764  // Now x and w are not used!
2765 
2766  ROOT::Math::WrappedTF1 wf1(*this);
2767  if (params)
2768  wf1.SetParameters(params);
2770  gli.SetFunction(wf1);
2771  return gli.Integral(a, b);
2772 
2773 }
2774 
2775 
2776 ////////////////////////////////////////////////////////////////////////////////
2777 /// See more general prototype below.
2778 /// This interface kept for back compatibility
2779 /// It is recommended to use the other interface where one can specify also epsabs and the maximum number of
2780 /// points
2781 
2783 {
2784  Int_t nfnevl, ifail;
2786  Double_t result = IntegralMultiple(n, a, b, maxpts, epsrel, epsrel, relerr, nfnevl, ifail);
2787  if (ifail > 0) {
2788  Warning("IntegralMultiple", "failed code=%d, ", ifail);
2789  }
2790  return result;
2791 }
2792 
2793 
2794 ////////////////////////////////////////////////////////////////////////////////
2795 /// This function computes, to an attempted specified accuracy, the value of
2796 /// the integral
2797 ///
2798 /// \param[in] n Number of dimensions [2,15]
2799 /// \param[in] a,b One-dimensional arrays of length >= N . On entry A[i], and B[i],
2800 /// contain the lower and upper limits of integration, respectively.
2801 /// \param[in] maxpts Maximum number of function evaluations to be allowed.
2802 /// maxpts >= 2^n +2*n*(n+1) +1
2803 /// if maxpts<minpts, maxpts is set to 10*minpts
2804 /// \param[in] epsrel Specified relative accuracy.
2805 /// \param[in] epsabs Specified absolute accuracy.
2806 /// The integration algorithm will attempt to reach either the relative or the absolute accuracy.
2807 /// In case the maximum function called is reached the algorithm will stop earlier without having reached
2808 /// the desired accuracy
2809 ///
2810 /// \param[out] relerr Contains, on exit, an estimation of the relative accuracy of the result.
2811 /// \param[out] nfnevl number of function evaluations performed.
2812 /// \param[out] ifail
2813 /// \parblock
2814 /// 0 Normal exit. At least minpts and at most maxpts calls to the function were performed.
2815 ///
2816 /// 1 maxpts is too small for the specified accuracy eps. The result and relerr contain the values obtainable for the
2817 /// specified value of maxpts.
2818 ///
2819 /// 3 n<2 or n>15
2820 /// \endparblock
2821 ///
2822 /// Method:
2823 ///
2824 /// The default method used is the Genz-Mallik adaptive multidimensional algorithm
2825 /// using the class ROOT::Math::AdaptiveIntegratorMultiDim (see the reference documentation of the class)
2826 ///
2827 /// Other methods can be used by setting ROOT::Math::IntegratorMultiDimOptions::SetDefaultIntegrator()
2828 /// to different integrators.
2829 /// Other possible integrators are MC integrators based on the ROOT::Math::GSLMCIntegrator class
2830 /// Possible methods are : Vegas, Miser or Plain
2831 /// IN case of MC integration the accuracy is determined by the number of function calls, one should be
2832 /// careful not to use a too large value of maxpts
2833 ///
2834 
2835 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)
2836 {
2838 
2839  double result = 0;
2843  ROOT::Math::AdaptiveIntegratorMultiDim aimd(wf1, epsabs, epsrel, maxpts);
2844  //aimd.SetMinPts(minpts); // use default minpts ( n^2 + 2 * n * (n+1) +1 )
2845  result = aimd.Integral(a, b);
2846  relerr = aimd.RelError();
2847  nfnevl = aimd.NEval();
2848  ifail = aimd.Status();
2849  } else {
2850  // use default abs tolerance = relative tolerance
2852  result = imd.Integral(a, b);
2853  relerr = (result != 0) ? imd.Error() / std::abs(result) : imd.Error();
2854  nfnevl = 0;
2855  ifail = imd.Status();
2856  }
2857 
2858 
2859  return result;
2860 }
2861 
2862 
2863 ////////////////////////////////////////////////////////////////////////////////
2864 /// Return kTRUE if the function is valid
2865 
2867 {
2868  if (fFormula) return fFormula->IsValid();
2869  if (fMethodCall) return fMethodCall->IsValid();
2870  // function built on compiled functors are always valid by definition
2871  // (checked at compiled time)
2872  // invalid is a TF1 where the functor is null pointer and has not been saved
2873  if (!fFunctor && fSave.empty()) return kFALSE;
2874  return kTRUE;
2875 }
2876 
2877 
2878 //______________________________________________________________________________
2879 
2880 
2881 void TF1::Print(Option_t *option) const
2882 {
2883  if (fType == EFType::kFormula) {
2884  printf("Formula based function: %s \n", GetName());
2885  assert(fFormula);
2886  fFormula->Print(option);
2887  } else if (fType > 0) {
2888  if (fType == EFType::kInterpreted)
2889  printf("Interpreted based function: %s(double *x, double *p). Ndim = %d, Npar = %d \n", GetName(), GetNdim(),
2890  GetNpar());
2891  else if (fType == EFType::kCompositionFcn) {
2892  printf("Composition based function: %s. Ndim = %d, Npar = %d \n", GetName(), GetNdim(), GetNpar());
2893  if (!fComposition)
2894  printf("fComposition not found!\n"); // this would be bad
2895  } else {
2896  if (fFunctor)
2897  printf("Compiled based function: %s based on a functor object. Ndim = %d, Npar = %d\n", GetName(),
2898  GetNdim(), GetNpar());
2899  else {
2900  printf("Function based on a list of points from a compiled based function: %s. Ndim = %d, Npar = %d, Npx "
2901  "= %zu\n",
2902  GetName(), GetNdim(), GetNpar(), fSave.size());
2903  if (fSave.empty())
2904  Warning("Print", "Function %s is based on a list of points but list is empty", GetName());
2905  }
2906  }
2907  TString opt(option);
2908  opt.ToUpper();
2909  if (opt.Contains("V")) {
2910  // print list of parameters
2911  if (fNpar > 0) {
2912  printf("List of Parameters: \n");
2913  for (int i = 0; i < fNpar; ++i)
2914  printf(" %20s = %10f \n", GetParName(i), GetParameter(i));
2915  }
2916  if (!fSave.empty()) {
2917  // print list of saved points
2918  printf("List of Saved points (N=%d): \n", int(fSave.size()));
2919  for (auto &x : fSave)
2920  printf("( %10f ) ", x);
2921  printf("\n");
2922  }
2923  }
2924  }
2925  if (fHistogram) {
2926  printf("Contained histogram\n");
2927  fHistogram->Print(option);
2928  }
2929 }
2930 
2931 ////////////////////////////////////////////////////////////////////////////////
2932 /// Paint this function with its current attributes.
2933 /// The function is going to be converted in an histogram and the corresponding
2934 /// histogram is painted.
2935 /// The painted histogram can be retrieved calling afterwards the method TF1::GetHistogram()
2936 
2937 void TF1::Paint(Option_t *choptin)
2938 {
2939  fgCurrent = this;
2940 
2941  char option[32];
2942  strlcpy(option,choptin,32);
2943 
2944  TString opt = option;
2945  opt.ToLower();
2946 
2947  Bool_t optSAME = kFALSE;
2948  if (opt.Contains("same")) {
2949  opt.ReplaceAll("same","");
2950  optSAME = kTRUE;
2951  }
2952  opt.ReplaceAll(' ', "");
2953 
2954  Double_t xmin = fXmin, xmax = fXmax, pmin = fXmin, pmax = fXmax;
2955  if (gPad) {
2956  pmin = gPad->PadtoX(gPad->GetUxmin());
2957  pmax = gPad->PadtoX(gPad->GetUxmax());
2958  }
2959  if (optSAME) {
2960  if (xmax < pmin) return; // Completely outside.
2961  if (xmin > pmax) return;
2962  if (xmin < pmin) xmin = pmin;
2963  if (xmax > pmax) xmax = pmax;
2964  }
2965 
2966  // create an histogram using the function content (re-use it if already existing)
2968 
2969  char *l1 = strstr(option,"PFC"); // Automatic Fill Color
2970  char *l2 = strstr(option,"PLC"); // Automatic Line Color
2971  char *l3 = strstr(option,"PMC"); // Automatic Marker Color
2972  if (l1 || l2 || l3) {
2973  Int_t i = gPad->NextPaletteColor();
2974  if (l1) {memcpy(l1," ",3); fHistogram->SetFillColor(i);}
2975  if (l2) {memcpy(l2," ",3); fHistogram->SetLineColor(i);}
2976  if (l3) {memcpy(l3," ",3); fHistogram->SetMarkerColor(i);}
2977  }
2978 
2979  // set the optimal minimum and maximum
2980  Double_t minimum = fHistogram->GetMinimumStored();
2981  Double_t maximum = fHistogram->GetMaximumStored();
2982  if (minimum <= 0 && gPad && gPad->GetLogy()) minimum = -1111; // This can happen when switching from lin to log scale.
2983  if (gPad && gPad->GetUymin() < fHistogram->GetMinimum() &&
2984  !fHistogram->TestBit(TH1::kIsZoomed)) minimum = -1111; // This can happen after unzooming a fit.
2985  if (minimum == -1111) { // This can happen after unzooming.
2987  minimum = fHistogram->GetYaxis()->GetXmin();
2988  } else {
2989  minimum = fMinimum;
2990  // Optimize the computation of the scale in Y in case the min/max of the
2991  // function oscillate around a constant value
2992  if (minimum == -1111) {
2993  Double_t hmin;
2994  if (optSAME && gPad) hmin = gPad->GetUymin();
2995  else hmin = fHistogram->GetMinimum();
2996  if (hmin > 0) {
2997  Double_t hmax;
2998  Double_t hminpos = hmin;
2999  if (optSAME && gPad) hmax = gPad->GetUymax();
3000  else hmax = fHistogram->GetMaximum();
3001  hmin -= 0.05 * (hmax - hmin);
3002  if (hmin < 0) hmin = 0;
3003  if (hmin <= 0 && gPad && gPad->GetLogy()) hmin = hminpos;
3004  minimum = hmin;
3005  }
3006  }
3007  }
3008  fHistogram->SetMinimum(minimum);
3009  }
3010  if (maximum == -1111) {
3012  maximum = fHistogram->GetYaxis()->GetXmax();
3013  } else {
3014  maximum = fMaximum;
3015  }
3016  fHistogram->SetMaximum(maximum);
3017  }
3018 
3019 
3020  // Draw the histogram.
3021  if (!gPad) return;
3022  if (opt.Length() == 0) {
3023  if (optSAME) fHistogram->Paint("lfsame");
3024  else fHistogram->Paint("lf");
3025  } else {
3026  fHistogram->Paint(option);
3027  }
3028 }
3029 
3030 ////////////////////////////////////////////////////////////////////////////////
3031 /// Create histogram with bin content equal to function value
3032 /// computed at the bin center
3033 /// This histogram will be used to paint the function
3034 /// A re-creation is forced and a new histogram is done if recreate=true
3035 
3037 {
3038  Int_t i;
3039  Double_t xv[1];
3040 
3041  TH1 *histogram = 0;
3042 
3043 
3044  // Create a temporary histogram and fill each channel with the function value
3045  // Preserve axis titles
3046  TString xtitle = "";
3047  TString ytitle = "";
3048  char *semicol = (char *)strstr(GetTitle(), ";");
3049  if (semicol) {
3050  Int_t nxt = strlen(semicol);
3051  char *ctemp = new char[nxt];
3052  strlcpy(ctemp, semicol + 1, nxt);
3053  semicol = (char *)strstr(ctemp, ";");
3054  if (semicol) {
3055  *semicol = 0;
3056  ytitle = semicol + 1;
3057  }
3058  xtitle = ctemp;
3059  delete [] ctemp;
3060  }
3061  if (fHistogram) {
3062  // delete previous histograms if were done if done in different mode
3063  xtitle = fHistogram->GetXaxis()->GetTitle();
3064  ytitle = fHistogram->GetYaxis()->GetTitle();
3065  if (!gPad->GetLogx() && fHistogram->TestBit(TH1::kLogX)) {
3066  delete fHistogram;
3067  fHistogram = 0;
3068  recreate = kTRUE;
3069  }
3070  if (gPad->GetLogx() && !fHistogram->TestBit(TH1::kLogX)) {
3071  delete fHistogram;
3072  fHistogram = 0;
3073  recreate = kTRUE;
3074  }
3075  }
3076 
3077  if (fHistogram && !recreate) {
3078  histogram = fHistogram;
3080  } else {
3081  // If logx, we must bin in logx and not in x
3082  // otherwise in case of several decades, one gets wrong results.
3083  if (xmin > 0 && gPad && gPad->GetLogx()) {
3084  Double_t *xbins = new Double_t[fNpx + 1];
3085  Double_t xlogmin = TMath::Log10(xmin);
3086  Double_t xlogmax = TMath::Log10(xmax);
3087  Double_t dlogx = (xlogmax - xlogmin) / ((Double_t)fNpx);
3088  for (i = 0; i <= fNpx; i++) {
3089  xbins[i] = gPad->PadtoX(xlogmin + i * dlogx);
3090  }
3091  histogram = new TH1D("Func", GetTitle(), fNpx, xbins);
3092  histogram->SetBit(TH1::kLogX);
3093  delete [] xbins;
3094  } else {
3095  histogram = new TH1D("Func", GetTitle(), fNpx, xmin, xmax);
3096  }
3097  if (fMinimum != -1111) histogram->SetMinimum(fMinimum);
3098  if (fMaximum != -1111) histogram->SetMaximum(fMaximum);
3099  histogram->SetDirectory(0);
3100  }
3101  R__ASSERT(histogram);
3102 
3103  // Restore axis titles.
3104  histogram->GetXaxis()->SetTitle(xtitle.Data());
3105  histogram->GetYaxis()->SetTitle(ytitle.Data());
3106  Double_t *parameters = GetParameters();
3107 
3108  InitArgs(xv, parameters);
3109  for (i = 1; i <= fNpx; i++) {
3110  xv[0] = histogram->GetBinCenter(i);
3111  histogram->SetBinContent(i, EvalPar(xv, parameters));
3112  }
3113 
3114  // Copy Function attributes to histogram attributes.
3115  histogram->SetBit(TH1::kNoStats);
3116  histogram->SetLineColor(GetLineColor());
3117  histogram->SetLineStyle(GetLineStyle());
3118  histogram->SetLineWidth(GetLineWidth());
3119  histogram->SetFillColor(GetFillColor());
3120  histogram->SetFillStyle(GetFillStyle());
3121  histogram->SetMarkerColor(GetMarkerColor());
3122  histogram->SetMarkerStyle(GetMarkerStyle());
3123  histogram->SetMarkerSize(GetMarkerSize());
3124 
3125  // update saved histogram in case it was deleted or if it is the first time the method is called
3126  // for example when called from TF1::GetHistogram()
3127  if (!fHistogram) fHistogram = histogram;
3128  return histogram;
3129 
3130 }
3131 
3132 
3133 ////////////////////////////////////////////////////////////////////////////////
3134 /// Release parameter number ipar If used in a fit, the parameter
3135 /// can vary freely. The parameter limits are reset to 0,0.
3136 
3138 {
3139  if (ipar < 0 || ipar > GetNpar() - 1) return;
3140  SetParLimits(ipar, 0, 0);
3141 }
3142 
3143 
3144 ////////////////////////////////////////////////////////////////////////////////
3145 /// Save values of function in array fSave
3146 
3148 {
3149  Double_t *parameters = GetParameters();
3150  //if (fSave != 0) {delete [] fSave; fSave = 0;}
3151  if (fParent && fParent->InheritsFrom(TH1::Class())) {
3152  //if parent is a histogram save the function at the center of the bins
3153  if ((xmin > 0 && xmax > 0) && TMath::Abs(TMath::Log10(xmax / xmin) > TMath::Log10(fNpx))) {
3154  TH1 *h = (TH1 *)fParent;
3155  Int_t bin1 = h->GetXaxis()->FindBin(xmin);
3156  Int_t bin2 = h->GetXaxis()->FindBin(xmax);
3157  int fNsave = bin2 - bin1 + 4;
3158  //fSave = new Double_t[fNsave];
3159  fSave.resize(fNsave);
3160  Double_t xv[1];
3161 
3162  InitArgs(xv, parameters);
3163  for (Int_t i = bin1; i <= bin2; i++) {
3164  xv[0] = h->GetXaxis()->GetBinCenter(i);
3165  fSave[i - bin1] = EvalPar(xv, parameters);
3166  }
3167  fSave[fNsave - 3] = xmin;
3168  fSave[fNsave - 2] = xmax;
3169  fSave[fNsave - 1] = xmax;
3170  return;
3171  }
3172  }
3173  int fNsave = fNpx + 3;
3174  if (fNsave <= 3) {
3175  return;
3176  }
3177  //fSave = new Double_t[fNsave];
3178  fSave.resize(fNsave);
3179  Double_t dx = (xmax - xmin) / fNpx;
3180  if (dx <= 0) {
3181  dx = (fXmax - fXmin) / fNpx;
3182  fNsave--;
3183  xmin = fXmin + 0.5 * dx;
3184  xmax = fXmax - 0.5 * dx;
3185  }
3186  Double_t xv[1];
3187  InitArgs(xv, parameters);
3188  for (Int_t i = 0; i <= fNpx; i++) {
3189  xv[0] = xmin + dx * i;
3190  fSave[i] = EvalPar(xv, parameters);
3191  }
3192  fSave[fNpx + 1] = xmin;
3193  fSave[fNpx + 2] = xmax;
3194 }
3195 
3196 
3197 ////////////////////////////////////////////////////////////////////////////////
3198 /// Save primitive as a C++ statement(s) on output stream out
3199 
3200 void TF1::SavePrimitive(std::ostream &out, Option_t *option /*= ""*/)
3201 {
3202  Int_t i;
3203  char quote = '"';
3204 
3205  // Save the function as C code independant from ROOT.
3206  if (strstr(option, "cc")) {
3207  out << "double " << GetName() << "(double xv) {" << std::endl;
3208  Double_t dx = (fXmax - fXmin) / (fNpx - 1);
3209  out << " double x[" << fNpx << "] = {" << std::endl;
3210  out << " ";
3211  Int_t n = 0;
3212  for (i = 0; i < fNpx; i++) {
3213  out << fXmin + dx *i ;
3214  if (i < fNpx - 1) out << ", ";
3215  if (n++ == 10) {
3216  out << std::endl;
3217  out << " ";
3218  n = 0;
3219  }
3220  }
3221  out << std::endl;
3222  out << " };" << std::endl;
3223  out << " double y[" << fNpx << "] = {" << std::endl;
3224  out << " ";
3225  n = 0;
3226  for (i = 0; i < fNpx; i++) {
3227  out << Eval(fXmin + dx * i);
3228  if (i < fNpx - 1) out << ", ";
3229  if (n++ == 10) {
3230  out << std::endl;
3231  out << " ";
3232  n = 0;
3233  }
3234  }
3235  out << std::endl;
3236  out << " };" << std::endl;
3237  out << " if (xv<x[0]) return y[0];" << std::endl;
3238  out << " if (xv>x[" << fNpx - 1 << "]) return y[" << fNpx - 1 << "];" << std::endl;
3239  out << " int i, j=0;" << std::endl;
3240  out << " for (i=1; i<" << fNpx << "; i++) { if (xv < x[i]) break; j++; }" << std::endl;
3241  out << " return y[j] + (y[j + 1] - y[j]) / (x[j + 1] - x[j]) * (xv - x[j]);" << std::endl;
3242  out << "}" << std::endl;
3243  return;
3244  }
3245 
3246  out << " " << std::endl;
3247 
3248  // Either f1Number is computed locally or set from outside
3249  static Int_t f1Number = 0;
3250  TString f1Name(GetName());
3251  const char *l = strstr(option, "#");
3252  if (l != 0) {
3253  sscanf(&l[1], "%d", &f1Number);
3254  } else {
3255  ++f1Number;
3256  }
3257  f1Name += f1Number;
3258 
3259  const char *addToGlobList = fParent ? ", TF1::EAddToList::kNo" : ", TF1::EAddToList::kDefault";
3260 
3261  if (!fType) {
3262  out << " TF1 *" << f1Name.Data() << " = new TF1(" << quote << GetName() << quote << "," << quote << GetTitle() << quote << "," << fXmin << "," << fXmax << addToGlobList << ");" << std::endl;
3263  if (fNpx != 100) {
3264  out << " " << f1Name.Data() << "->SetNpx(" << fNpx << ");" << std::endl;
3265  }
3266  } else {
3267  out << " TF1 *" << f1Name.Data() << " = new TF1(" << quote << "*" << GetName() << quote << "," << fXmin << "," << fXmax << "," << GetNpar() << ");" << std::endl;
3268  out << " //The original function : " << GetTitle() << " had originally been created by:" << std::endl;
3269  out << " //TF1 *" << GetName() << " = new TF1(" << quote << GetName() << quote << "," << GetTitle() << "," << fXmin << "," << fXmax << "," << GetNpar();
3270  out << ", 1" << addToGlobList << ");" << std::endl;
3271  out << " " << f1Name.Data() << "->SetRange(" << fXmin << "," << fXmax << ");" << std::endl;
3272  out << " " << f1Name.Data() << "->SetName(" << quote << GetName() << quote << ");" << std::endl;
3273  out << " " << f1Name.Data() << "->SetTitle(" << quote << GetTitle() << quote << ");" << std::endl;
3274  if (fNpx != 100) {
3275  out << " " << f1Name.Data() << "->SetNpx(" << fNpx << ");" << std::endl;
3276  }
3277  Double_t dx = (fXmax - fXmin) / fNpx;
3278  Double_t xv[1];
3279  Double_t *parameters = GetParameters();
3280  InitArgs(xv, parameters);
3281  for (i = 0; i <= fNpx; i++) {
3282  xv[0] = fXmin + dx * i;
3283  Double_t save = EvalPar(xv, parameters);
3284  out << " " << f1Name.Data() << "->SetSavedPoint(" << i << "," << save << ");" << std::endl;
3285  }
3286  out << " " << f1Name.Data() << "->SetSavedPoint(" << fNpx + 1 << "," << fXmin << ");" << std::endl;
3287  out << " " << f1Name.Data() << "->SetSavedPoint(" << fNpx + 2 << "," << fXmax << ");" << std::endl;
3288  }
3289 
3290  if (TestBit(kNotDraw)) {
3291  out << " " << f1Name.Data() << "->SetBit(TF1::kNotDraw);" << std::endl;
3292  }
3293  if (GetFillColor() != 0) {
3294  if (GetFillColor() > 228) {
3296  out << " " << f1Name.Data() << "->SetFillColor(ci);" << std::endl;
3297  } else
3298  out << " " << f1Name.Data() << "->SetFillColor(" << GetFillColor() << ");" << std::endl;
3299  }
3300  if (GetFillStyle() != 1001) {
3301  out << " " << f1Name.Data() << "->SetFillStyle(" << GetFillStyle() << ");" << std::endl;
3302  }
3303  if (GetMarkerColor() != 1) {
3304  if (GetMarkerColor() > 228) {
3306  out << " " << f1Name.Data() << "->SetMarkerColor(ci);" << std::endl;
3307  } else
3308  out << " " << f1Name.Data() << "->SetMarkerColor(" << GetMarkerColor() << ");" << std::endl;
3309  }
3310  if (GetMarkerStyle() != 1) {
3311  out << " " << f1Name.Data() << "->SetMarkerStyle(" << GetMarkerStyle() << ");" << std::endl;
3312  }
3313  if (GetMarkerSize() != 1) {
3314  out << " " << f1Name.Data() << "->SetMarkerSize(" << GetMarkerSize() << ");" << std::endl;
3315  }
3316  if (GetLineColor() != 1) {
3317  if (GetLineColor() > 228) {
3319  out << " " << f1Name.Data() << "->SetLineColor(ci);" << std::endl;
3320  } else
3321  out << " " << f1Name.Data() << "->SetLineColor(" << GetLineColor() << ");" << std::endl;
3322  }
3323  if (GetLineWidth() != 4) {
3324  out << " " << f1Name.Data() << "->SetLineWidth(" << GetLineWidth() << ");" << std::endl;
3325  }
3326  if (GetLineStyle() != 1) {
3327  out << " " << f1Name.Data() << "->SetLineStyle(" << GetLineStyle() << ");" << std::endl;
3328  }
3329  if (GetChisquare() != 0) {
3330  out << " " << f1Name.Data() << "->SetChisquare(" << GetChisquare() << ");" << std::endl;
3331  out << " " << f1Name.Data() << "->SetNDF(" << GetNDF() << ");" << std::endl;
3332  }
3333 
3334  if (GetXaxis()) GetXaxis()->SaveAttributes(out, f1Name.Data(), "->GetXaxis()");
3335  if (GetYaxis()) GetYaxis()->SaveAttributes(out, f1Name.Data(), "->GetYaxis()");
3336 
3337  Double_t parmin, parmax;
3338  for (i = 0; i < GetNpar(); i++) {
3339  out << " " << f1Name.Data() << "->SetParameter(" << i << "," << GetParameter(i) << ");" << std::endl;
3340  out << " " << f1Name.Data() << "->SetParError(" << i << "," << GetParError(i) << ");" << std::endl;
3341  GetParLimits(i, parmin, parmax);
3342  out << " " << f1Name.Data() << "->SetParLimits(" << i << "," << parmin << "," << parmax << ");" << std::endl;
3343  }
3344  if (!strstr(option, "nodraw")) {
3345  out << " " << f1Name.Data() << "->Draw("
3346  << quote << option << quote << ");" << std::endl;
3347  }
3348 }
3349 
3350 
3351 ////////////////////////////////////////////////////////////////////////////////
3352 /// Static function setting the current function.
3353 /// the current function may be accessed in static C-like functions
3354 /// when fitting or painting a function.
3355 
3357 {
3358  fgCurrent = f1;
3359 }
3360 
3361 ////////////////////////////////////////////////////////////////////////////////
3362 /// Set the result from the fit
3363 /// parameter values, errors, chi2, etc...
3364 /// Optionally a pointer to a vector (with size fNpar) of the parameter indices in the FitResult can be passed
3365 /// This is useful in the case of a combined fit with different functions, and the FitResult contains the global result
3366 /// By default it is assume that indpar = {0,1,2,....,fNpar-1}.
3367 
3368 void TF1::SetFitResult(const ROOT::Fit::FitResult &result, const Int_t *indpar)
3369 {
3370  Int_t npar = GetNpar();
3371  if (result.IsEmpty()) {
3372  Warning("SetFitResult", "Empty Fit result - nothing is set in TF1");
3373  return;
3374  }
3375  if (indpar == 0 && npar != (int) result.NPar()) {
3376  Error("SetFitResult", "Invalid Fit result passed - number of parameter is %d , different than TF1::GetNpar() = %d", npar, result.NPar());
3377  return;
3378  }
3379  if (result.Chi2() > 0)
3380  SetChisquare(result.Chi2());
3381  else
3382  SetChisquare(result.MinFcnValue());
3383 
3384  SetNDF(result.Ndf());
3385  SetNumberFitPoints(result.Ndf() + result.NFreeParameters());
3386 
3387 
3388  for (Int_t i = 0; i < npar; ++i) {
3389  Int_t ipar = (indpar != 0) ? indpar[i] : i;
3390  if (ipar < 0) continue;
3391  GetParameters()[i] = result.Parameter(ipar);
3392  // in case errors are not present do not set them
3393  if (ipar < (int) result.Errors().size())
3394  fParErrors[i] = result.Error(ipar);
3395  }
3396  //invalidate cached integral since parameters have changed
3397  Update();
3398 
3399 }
3400 
3401 
3402 ////////////////////////////////////////////////////////////////////////////////
3403 /// Set the maximum value along Y for this function
3404 /// In case the function is already drawn, set also the maximum in the
3405 /// helper histogram
3406 
3408 {
3409  fMaximum = maximum;
3410  if (fHistogram) fHistogram->SetMaximum(maximum);
3411  if (gPad) gPad->Modified();
3412 }
3413 
3414 
3415 ////////////////////////////////////////////////////////////////////////////////
3416 /// Set the minimum value along Y for this function
3417 /// In case the function is already drawn, set also the minimum in the
3418 /// helper histogram
3419 
3421 {
3422  fMinimum = minimum;
3423  if (fHistogram) fHistogram->SetMinimum(minimum);
3424  if (gPad) gPad->Modified();
3425 }
3426 
3427 
3428 ////////////////////////////////////////////////////////////////////////////////
3429 /// Set the number of degrees of freedom
3430 /// ndf should be the number of points used in a fit - the number of free parameters
3431 
3433 {
3434  fNDF = ndf;
3435 }
3436 
3437 
3438 ////////////////////////////////////////////////////////////////////////////////
3439 /// Set the number of points used to draw the function
3440 ///
3441 /// The default number of points along x is 100 for 1-d functions and 30 for 2-d/3-d functions
3442 /// You can increase this value to get a better resolution when drawing
3443 /// pictures with sharp peaks or to get a better result when using TF1::GetRandom
3444 /// the minimum number of points is 4, the maximum is 10000000 for 1-d and 10000 for 2-d/3-d functions
3445 
3447 {
3448  const Int_t minPx = 4;
3449  Int_t maxPx = 10000000;
3450  if (GetNdim() > 1) maxPx = 10000;
3451  if (npx >= minPx && npx <= maxPx) {
3452  fNpx = npx;
3453  } else {
3454  if (npx < minPx) fNpx = minPx;
3455  if (npx > maxPx) fNpx = maxPx;
3456  Warning("SetNpx", "Number of points must be >=%d && <= %d, fNpx set to %d", minPx, maxPx, fNpx);
3457  }
3458  Update();
3459 }
3460 ////////////////////////////////////////////////////////////////////////////////
3461 /// Set name of parameter number ipar
3462 
3463 void TF1::SetParName(Int_t ipar, const char *name)
3464 {
3465  if (fFormula) {
3466  if (ipar < 0 || ipar >= GetNpar()) return;
3467  fFormula->SetParName(ipar, name);
3468  } else
3469  fParams->SetParName(ipar, name);
3470 }
3471 
3472 ////////////////////////////////////////////////////////////////////////////////
3473 /// Set up to 10 parameter names
3474 
3475 void TF1::SetParNames(const char *name0, const char *name1, const char *name2, const char *name3, const char *name4,
3476  const char *name5, const char *name6, const char *name7, const char *name8, const char *name9, const char *name10)
3477 {
3478  if (fFormula)
3479  fFormula->SetParNames(name0, name1, name2, name3, name4, name5, name6, name7, name8, name9, name10);
3480  else
3481  fParams->SetParNames(name0, name1, name2, name3, name4, name5, name6, name7, name8, name9, name10);
3482 }
3483 ////////////////////////////////////////////////////////////////////////////////
3484 /// Set error for parameter number ipar
3485 
3487 {
3488  if (ipar < 0 || ipar > GetNpar() - 1) return;
3489  fParErrors[ipar] = error;
3490 }
3491 
3492 
3493 ////////////////////////////////////////////////////////////////////////////////
3494 /// Set errors for all active parameters
3495 /// when calling this function, the array errors must have at least fNpar values
3496 
3497 void TF1::SetParErrors(const Double_t *errors)
3498 {
3499  if (!errors) return;
3500  for (Int_t i = 0; i < GetNpar(); i++) fParErrors[i] = errors[i];
3501 }
3502 
3503 
3504 ////////////////////////////////////////////////////////////////////////////////
3505 /// Set limits for parameter ipar.
3506 ///
3507 /// The specified limits will be used in a fit operation
3508 /// when the option "B" is specified (Bounds).
3509 /// To fix a parameter, use TF1::FixParameter
3510 
3511 void TF1::SetParLimits(Int_t ipar, Double_t parmin, Double_t parmax)
3512 {
3513  Int_t npar = GetNpar();
3514  if (ipar < 0 || ipar > npar - 1) return;
3515  if (int(fParMin.size()) != npar) {
3516  fParMin.resize(npar);
3517  }
3518  if (int(fParMax.size()) != npar) {
3519  fParMax.resize(npar);
3520  }
3521  fParMin[ipar] = parmin;
3522  fParMax[ipar] = parmax;
3523 }
3524 
3525 
3526 ////////////////////////////////////////////////////////////////////////////////
3527 /// Initialize the upper and lower bounds to draw the function.
3528 ///
3529 /// The function range is also used in an histogram fit operation
3530 /// when the option "R" is specified.
3531 
3533 {
3534  fXmin = xmin;
3535  fXmax = xmax;
3536  if (fType == EFType::kCompositionFcn && fComposition) {
3537  fComposition->SetRange(xmin, xmax); // automatically updates sub-functions
3538  }
3539  Update();
3540 }
3541 
3542 
3543 ////////////////////////////////////////////////////////////////////////////////
3544 /// Restore value of function saved at point
3545 
3547 {
3548  if (fSave.size() == 0) {
3549  fSave.resize(fNpx + 3);
3550  }
3551  if (point < 0 || point >= int(fSave.size())) return;
3552  fSave[point] = value;
3553 }
3554 
3555 
3556 ////////////////////////////////////////////////////////////////////////////////
3557 /// Set function title
3558 /// if title has the form "fffffff;xxxx;yyyy", it is assumed that
3559 /// the function title is "fffffff" and "xxxx" and "yyyy" are the
3560 /// titles for the X and Y axis respectively.
3561 
3562 void TF1::SetTitle(const char *title)
3563 {
3564  if (!title) return;
3565  fTitle = title;
3566  if (!fHistogram) return;
3567  fHistogram->SetTitle(title);
3568  if (gPad) gPad->Modified();
3569 }
3570 
3571 
3572 ////////////////////////////////////////////////////////////////////////////////
3573 /// Stream a class object.
3574 
3575 void TF1::Streamer(TBuffer &b)
3576 {
3577  if (b.IsReading()) {
3578  UInt_t R__s, R__c;
3579  Version_t v = b.ReadVersion(&R__s, &R__c);
3580  // process new version with new TFormula class which is contained in TF1
3581  //printf("reading TF1....- version %d..\n",v);
3582 
3583  if (v > 7) {
3584  // new classes with new TFormula
3585  // need to register the objects
3586  b.ReadClassBuffer(TF1::Class(), this, v, R__s, R__c);
3587  if (!TestBit(kNotGlobal)) {
3589  gROOT->GetListOfFunctions()->Add(this);
3590  }
3591  return;
3592  } else {
3593  ROOT::v5::TF1Data fold;
3594  //printf("Reading TF1 as v5::TF1Data- version %d \n",v);
3595  fold.Streamer(b, v, R__s, R__c, TF1::Class());
3596  // convert old TF1 to new one
3597  ((TF1v5Convert *)this)->Convert(fold);
3598  }
3599  }
3600 
3601  // Writing
3602  else {
3603  Int_t saved = 0;
3604  // save not-formula functions as array of points
3605  if (fType > 0 && fSave.empty() && fType != EFType::kCompositionFcn) {
3606  saved = 1;
3607  Save(fXmin, fXmax, 0, 0, 0, 0);
3608  }
3609  b.WriteClassBuffer(TF1::Class(), this);
3610 
3611  // clear vector contents
3612  if (saved) {
3613  fSave.clear();
3614  }
3615  }
3616 }
3617 
3618 
3619 ////////////////////////////////////////////////////////////////////////////////
3620 /// Called by functions such as SetRange, SetNpx, SetParameters
3621 /// to force the deletion of the associated histogram or Integral
3622 
3624 {
3625  delete fHistogram;
3626  fHistogram = 0;
3627  if (!fIntegral.empty()) {
3628  fIntegral.clear();
3629  fAlpha.clear();
3630  fBeta.clear();
3631  fGamma.clear();
3632  }
3633  if (fNormalized) {
3634  // need to compute the integral of the not-normalized function
3635  fNormalized = false;
3636  fNormIntegral = Integral(fXmin, fXmax, 0.0);
3637  fNormalized = true;
3638  } else
3639  fNormIntegral = 0;
3640 
3641  // std::vector<double>x(fNdim);
3642  // if ((fType == 1) && !fFunctor->Empty()) (*fFunctor)x.data(), (Double_t*)fParams);
3643  if (fType == EFType::kCompositionFcn && fComposition) {
3644  // double-check that the parameters are correct
3645  fComposition->SetParameters(GetParameters());
3646 
3647  fComposition->Update(); // should not be necessary, but just to be safe
3648  }
3649 }
3650 
3651 ////////////////////////////////////////////////////////////////////////////////
3652 /// Static function to set the global flag to reject points
3653 /// the fgRejectPoint global flag is tested by all fit functions
3654 /// if TRUE the point is not included in the fit.
3655 /// This flag can be set by a user in a fitting function.
3656 /// The fgRejectPoint flag is reset by the TH1 and TGraph fitting functions.
3657 
3659 {
3660  fgRejectPoint = reject;
3661 }
3662 
3663 
3664 ////////////////////////////////////////////////////////////////////////////////
3665 /// See TF1::RejectPoint above
3666 
3668 {
3669  return fgRejectPoint;
3670 }
3671 
3672 ////////////////////////////////////////////////////////////////////////////////
3673 /// Return nth moment of function between a and b
3674 ///
3675 /// See TF1::Integral() for parameter definitions
3676 
3678 {
3679  // wrapped function in interface for integral calculation
3680  // using abs value of integral
3681 
3682  TF1_EvalWrapper func(this, params, kTRUE, n);
3683 
3685 
3686  giod.SetFunction(func);
3687  giod.SetRelTolerance(epsilon);
3688 
3689  Double_t norm = giod.Integral(a, b);
3690  if (norm == 0) {
3691  Error("Moment", "Integral zero over range");
3692  return 0;
3693  }
3694 
3695  // calculate now integral of x^n f(x)
3696  // wrapped the member function EvalNum in interface required by integrator using the functor class
3697  ROOT::Math::Functor1D xnfunc(&func, &TF1_EvalWrapper::EvalNMom);
3698  giod.SetFunction(xnfunc);
3699 
3700  Double_t res = giod.Integral(a, b) / norm;
3701 
3702  return res;
3703 }
3704 
3705 
3706 ////////////////////////////////////////////////////////////////////////////////
3707 /// Return nth central moment of function between a and b
3708 /// (i.e the n-th moment around the mean value)
3709 ///
3710 /// See TF1::Integral() for parameter definitions
3711 ///
3712 /// \author Gene Van Buren <gene@bnl.gov>
3713 
3715 {
3716  TF1_EvalWrapper func(this, params, kTRUE, n);
3717 
3719 
3720  giod.SetFunction(func);
3721  giod.SetRelTolerance(epsilon);
3722 
3723  Double_t norm = giod.Integral(a, b);
3724  if (norm == 0) {
3725  Error("Moment", "Integral zero over range");
3726  return 0;
3727  }
3728 
3729  // calculate now integral of xf(x)
3730  // wrapped the member function EvalFirstMom in interface required by integrator using the functor class
3731  ROOT::Math::Functor1D xfunc(&func, &TF1_EvalWrapper::EvalFirstMom);
3732  giod.SetFunction(xfunc);
3733 
3734  // estimate of mean value
3735  Double_t xbar = giod.Integral(a, b) / norm;
3736 
3737  // use different mean value in function wrapper
3738  func.fX0 = xbar;
3739  ROOT::Math::Functor1D xnfunc(&func, &TF1_EvalWrapper::EvalNMom);
3740  giod.SetFunction(xnfunc);
3741 
3742  Double_t res = giod.Integral(a, b) / norm;
3743  return res;
3744 }
3745 
3746 
3747 //______________________________________________________________________________
3748 // some useful static utility functions to compute sampling points for IntegralFast
3749 ////////////////////////////////////////////////////////////////////////////////
3750 /// Type safe interface (static method)
3751 /// The number of sampling points are taken from the TGraph
3752 
3753 #ifdef INTHEFUTURE
3755 {
3756  if (!g) return;
3757  CalcGaussLegendreSamplingPoints(g->GetN(), g->GetX(), g->GetY(), eps);
3758 }
3759 
3760 
3761 ////////////////////////////////////////////////////////////////////////////////
3762 /// Type safe interface (static method)
3763 /// A TGraph is created with new with num points and the pointer to the
3764 /// graph is returned by the function. It is the responsibility of the
3765 /// user to delete the object.
3766 /// if num is invalid (<=0) NULL is returned
3767 
3769 {
3770  if (num <= 0)
3771  return 0;
3772 
3773  TGraph *g = new TGraph(num);
3774  CalcGaussLegendreSamplingPoints(g->GetN(), g->GetX(), g->GetY(), eps);
3775  return g;
3776 }
3777 #endif
3778 
3779 
3780 ////////////////////////////////////////////////////////////////////////////////
3781 /// Type: unsafe but fast interface filling the arrays x and w (static method)
3782 ///
3783 /// Given the number of sampling points this routine fills the arrays x and w
3784 /// of length num, containing the abscissa and weight of the Gauss-Legendre
3785 /// n-point quadrature formula.
3786 ///
3787 /// Gauss-Legendre:
3788 /** \f[
3789  W(x)=1 -1<x<1 \\
3790  (j+1)P_{j+1} = (2j+1)xP_j-jP_{j-1}
3791  \f]
3792 **/
3793 /// num is the number of sampling points (>0)
3794 /// x and w are arrays of size num
3795 /// eps is the relative precision
3796 ///
3797 /// If num<=0 or eps<=0 no action is done.
3798 ///
3799 /// Reference: Numerical Recipes in C, Second Edition
3800 
3802 {
3803  // This function is just kept like this for backward compatibility!
3804 
3806  gli.GetWeightVectors(x, w);
3807 
3808 
3809 }
3810 
3811 
3812 /** \class TF1Parameters
3813 TF1 Parameters class
3814 */
3815 
3816 ////////////////////////////////////////////////////////////////////////////////
3817 /// Returns the parameter number given a name
3818 /// not very efficient but list of parameters is typically small
3819 /// could use a map if needed
3820 
3822 {
3823  for (unsigned int i = 0; i < fParNames.size(); ++i) {
3824  if (fParNames[i] == std::string(name)) return i;
3825  }
3826  return -1;
3827 }
3828 
3829 ////////////////////////////////////////////////////////////////////////////////
3830 /// Set parameter values
3831 
3833  Double_t p5, Double_t p6, Double_t p7, Double_t p8,
3834  Double_t p9, Double_t p10)
3835 {
3836  unsigned int npar = fParameters.size();
3837  if (npar > 0) fParameters[0] = p0;
3838  if (npar > 1) fParameters[1] = p1;
3839  if (npar > 2) fParameters[2] = p2;
3840  if (npar > 3) fParameters[3] = p3;
3841  if (npar > 4) fParameters[4] = p4;
3842  if (npar > 5) fParameters[5] = p5;
3843  if (npar > 6) fParameters[6] = p6;
3844  if (npar > 7) fParameters[7] = p7;
3845  if (npar > 8) fParameters[8] = p8;
3846  if (npar > 9) fParameters[9] = p9;
3847  if (npar > 10) fParameters[10] = p10;
3848 }
3849 
3850 ////////////////////////////////////////////////////////////////////////////////
3851 /// Set parameter names
3852 
3853 void TF1Parameters::SetParNames(const char *name0, const char *name1, const char *name2, const char *name3,
3854  const char *name4, const char *name5, const char *name6, const char *name7,
3855  const char *name8, const char *name9, const char *name10)
3856 {
3857  unsigned int npar = fParNames.size();
3858  if (npar > 0) fParNames[0] = name0;
3859  if (npar > 1) fParNames[1] = name1;
3860  if (npar > 2) fParNames[2] = name2;
3861  if (npar > 3) fParNames[3] = name3;
3862  if (npar > 4) fParNames[4] = name4;
3863  if (npar > 5) fParNames[5] = name5;
3864  if (npar > 6) fParNames[6] = name6;
3865  if (npar > 7) fParNames[7] = name7;
3866  if (npar > 8) fParNames[8] = name8;
3867  if (npar > 9) fParNames[9] = name9;
3868  if (npar > 10) fParNames[10] = name10;
3869 }
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:416
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:1813
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 Note that this histogram is managed ...
Definition: TF1.cxx:1574
TF1::DrawF1
virtual void DrawF1(Double_t xmin, Double_t xmax, Option_t *option="")
Draw function between xmin and xmax.
Definition: TF1.cxx:1415
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:1559
TF1::fgAbsValue
static std::atomic< Bool_t > fgAbsValue
Definition: TF1.h:304
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:3658
TF1::ExecuteEvent
virtual void ExecuteEvent(Int_t event, Int_t px, Int_t py)
Execute action corresponding to one event.
Definition: TF1.cxx:1531
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:1908
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
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:1604
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:1853
TFormula
The Formula class.
Definition: TFormula.h:87
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:399
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:296
TF1::fgCurrent
static TF1 * fgCurrent
Definition: TF1.h:307
TF1::SetNpx
virtual void SetNpx(Int_t npx=100)
Set the number of points used to draw the function.
Definition: TF1.cxx:3446
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:2515
TF1::GetParameters
virtual Double_t * GetParameters() const
Definition: TF1.h:520
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:485
TF1::CreateHistogram
virtual TH1 * CreateHistogram()
Definition: TF1.h:449
TF1::GetNpar
virtual Int_t GetNpar() const
Definition: TF1.h:481
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:3475
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:3407
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:1945
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:618
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:1232
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:3677
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:3356
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:672
TF1::GetXmax
virtual Double_t GetXmax() const
Definition: TF1.h:556
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:1282
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
TF1::TF1FunctorPointer
Definition: TF1.h:227
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:9062
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:3200
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:1713
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:3497
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:326
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::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:3801
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:2331
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:3420
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:325
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:6975
TF1::DerivativeError
static Double_t DerivativeError()
Static function returning the error of the last call to the of Derivative's functions.
Definition: TF1.cxx:1266
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:2937
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:2069
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
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:2605
TF1::GetParLimits
virtual void GetParLimits(Int_t ipar, Double_t &parmin, Double_t &parmax) const
Return limits for parameter ipar.
Definition: TF1.cxx:1930
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:3432
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
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::fMethodCall
std::unique_ptr< TMethodCall > fMethodCall
Pointer to histogram used for visualisation.
Definition: TF1.h:264
TF1::GetRange
virtual void GetRange(Double_t *xmin, Double_t *xmax) const
Return range of a generic N-D function.
Definition: TF1.cxx:2269
TF1::GetNumber
virtual Int_t GetNumber() const
Definition: TF1.h:498
TF1::Clone
TObject * Clone(const char *newname=0) const
Make a complete copy of the underlying object.
Definition: TF1.cxx:1053
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:2180
TF1::SetParameter
virtual void SetParameter(Int_t param, Double_t value)
Definition: TF1.h:634
TF1::SetParameters
virtual void SetParameters(const Double_t *params)
Definition: TF1.h:644
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:6678
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:2433
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:2762
TH1::Clone
TObject * Clone(const char *newname=0) const
Make a complete copy of the underlying object.
Definition: TH1.cxx:2740
TString::ToUpper
void ToUpper()
Change string to upper case.
Definition: TString.cxx:1158
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:3368
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:2866
TF1::GetParNumber
virtual Int_t GetParNumber(const char *name) const
Definition: TF1.h:533
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
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:3821
TF1::SetParError
virtual void SetParError(Int_t ipar, Double_t error)
Set error for parameter number ipar.
Definition: TF1.cxx:3486
TF1::GetYaxis
TAxis * GetYaxis() const
Get y axis of the function.
Definition: TF1.cxx:2399
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
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:141
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:2482
TH1::GetYaxis
TAxis * GetYaxis()
Definition: TH1.h:321
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:1374
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:3623
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:288
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:2388
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:2467
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:1167
kFALSE
const Bool_t kFALSE
Definition: RtypesCore.h:92
TF1::GetParName
virtual const char * GetParName(Int_t ipar) const
Definition: TF1.h:529
TString::Append
TString & Append(const char *cs)
Definition: TString.h:564
TH1::GetBinCenter
virtual Double_t GetBinCenter(Int_t bin) const
Return bin center for 1D histogram.
Definition: TH1.cxx:8981
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
TH1::DistancetoPrimitive
virtual Int_t DistancetoPrimitive(Int_t px, Int_t py)
Compute distance from point px,py to a line.
Definition: TH1.cxx:2811
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:3714
TString::First
Ssiz_t First(char c) const
Find first occurrence of a character c.
Definition: TString.cxx:519
TH1::ExecuteEvent
virtual void ExecuteEvent(Int_t event, Int_t px, Int_t py)
Execute action corresponding to one event.
Definition: TH1.cxx:3246
TH1::SetMaximum
virtual void SetMaximum(Double_t maximum=-1111)
Definition: TH1.h:398
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:3036
TF1::Browse
virtual void Browse(TBrowser *b)
Browse.
Definition: TF1.cxx:982
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:612
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:994
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:305
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:8475
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:8777
double
double
Definition: Converters.cxx:921
TRandom::Rndm
virtual Double_t Rndm()
Machine independent random number generator.
Definition: TRandom.cxx:552
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
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:2410
TF1::fFunctor
std::unique_ptr< TF1FunctorPointer > fFunctor
Definition: TF1.h:267
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:500
TH1::GetMinimumStored
virtual Double_t GetMinimumStored() const
Definition: TH1.h:292
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:167
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:624
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:3532
kHand
@ kHand
Definition: GuiTypes.h:374
TF1::GetSave
virtual Double_t GetSave(const Double_t *x)
Get value corresponding to X in array of fSave values.
Definition: TF1.cxx:2332
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:1463
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:3853
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
TF1::fParams
std::unique_ptr< TF1Parameters > fParams
Definition: TF1.h:269
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:421
ROOT::Math::IBaseFunctionOneDim::Clone
virtual IBaseFunctionOneDim * Clone() const =0
Clone a function.
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:3546
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
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:1920
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:3562
TF1::TF1FunctorPointerImpl
Definition: TF1.h:293
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:1352
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:3667
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:1434
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
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:1645
TF1::Draw
virtual void Draw(Option_t *option="")
Draw this function with its current attributes.
Definition: TF1.cxx:1322
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:1686
ROOT::v5::TF1Data::fNpfits
Int_t fNpfits
Definition: TF1Data.h:43
TObject
Mother of all ROOT objects.
Definition: TObject.h:37
TF1::fFormula
std::unique_ptr< TFormula > fFormula
Functor object to wrap any C++ callable object.
Definition: TF1.h:268
TF1::fgAddToGlobList
static std::atomic< Bool_t > fgAddToGlobList
Definition: TF1.h:306
TF1::AbsValue
static void AbsValue(Bool_t reject=kTRUE)
Static function: set the fgAbsValue flag.
Definition: TF1.cxx:973
TH1::kIsZoomed
@ kIsZoomed
bit set when zooming on Y axis
Definition: TH1.h:168
TH1
TH1 is the base class of all histogram 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:1102
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:3463
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:1879
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:98
ROOT::Math::IntegratorMultiDimOptions::DefaultAbsTolerance
static double DefaultAbsTolerance()
Definition: IntegratorOptions.cxx:369
TH1::kNoStats
@ kNoStats
don't draw stats box
Definition: TH1.h:164
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:1890
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:3511
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:2835
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:278
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:1982
Class
void Class()
Definition: Class.C:29
TString::ToLower
void ToLower()
Change string to lower-case.
Definition: TString.cxx:1145
TF1::DrawIntegral
virtual TObject * DrawIntegral(Option_t *option="al")
Draw integral of this function.
Definition: TF1.cxx:1399
TH1::GetXaxis
TAxis * GetXaxis()
Get the behaviour adopted by the object about the statoverflows. See EStatOverflows for more informat...
Definition: TH1.h:320
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:512
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:8390
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:3147
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:444
ROOT::Math::BrentMinimizer1D::FValMinimum
virtual double FValMinimum() const
Return function value at current estimate of the minimum.
Definition: BrentMinimizer1D.cxx:78
ROOT
tbb::task_arena is an alias of tbb::interface7::task_arena, which doesn't allow to forward declare tb...
Definition: EExecutionPolicy.hxx:4
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:1547
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:2692
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:6155
TMath.h
fw3dlego::xbins
const double xbins[xbins_n]
Definition: collection_proxies.C:48
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
gROOT
#define gROOT
Definition: TROOT.h:406
int
TF1::Print
virtual void Print(Option_t *option="") const
Print TNamed name and title.
Definition: TF1.cxx:2881
TF1::fParMax
std::vector< Double_t > fParMax
Definition: TF1.h:256
TF1::GetXmin
virtual Double_t GetXmin() const
Definition: TF1.h:552
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:3137
TMethodCall.h
g
#define g(i)
Definition: RSha256.hxx:105