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