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