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