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