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_q of a probability distribution Function F is defined as
1966/// \f[
1967/// F(x_{q}) = \int_{xmin}^{x_{q}} f dx = q with 0 <= q <= 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] nprobSum maximum size of array q and size of array probSum
1976/// \param[out] q array filled with nq quantiles
1977/// \param[in] probSum array of positions where quantiles will be computed.
1978/// It is assumed to contain at least nprobSum values.
1979/// \return value nq (<=nprobSum) with the number of quantiles computed
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());
1986/// f2->GetQuantiles(nprob,gr->GetY());
1987/// gr->Draw("alp");
1988///
1989/// \author Eddy Offermann
1990
1991
1992Int_t TF1::GetQuantiles(Int_t nprobSum, Double_t *q, const Double_t *probSum)
1993{
1994 // LM: change to use fNpx
1995 // should we change code to use a root finder ?
1996 // It should be more precise and more efficient
1997 const Int_t npx = TMath::Max(fNpx, 2 * nprobSum);
1998 const Double_t xMin = GetXmin();
1999 const Double_t xMax = GetXmax();
2000 const Double_t dx = (xMax - xMin) / npx;
2001
2002 TArrayD integral(npx + 1);
2003 TArrayD alpha(npx);
2004 TArrayD beta(npx);
2005 TArrayD gamma(npx);
2006
2007 integral[0] = 0;
2008 Int_t intNegative = 0;
2009 Int_t i;
2010 for (i = 0; i < npx; i++) {
2011 Double_t integ = Integral(Double_t(xMin + i * dx), Double_t(xMin + i * dx + dx), 0.0);
2012 if (integ < 0) {
2013 intNegative++;
2014 integ = -integ;
2015 }
2016 integral[i + 1] = integral[i] + integ;
2017 }
2018
2019 if (intNegative > 0)
2020 Warning("GetQuantiles", "function:%s has %d negative values: abs assumed",
2021 GetName(), intNegative);
2022 if (integral[npx] == 0) {
2023 Error("GetQuantiles", "Integral of function is zero");
2024 return 0;
2025 }
2026
2027 const Double_t total = integral[npx];
2028 for (i = 1; i <= npx; i++) integral[i] /= total;
2029 //the integral r for each bin is approximated by a parabola
2030 // x = alpha + beta*r +gamma*r**2
2031 // compute the coefficients alpha, beta, gamma for each bin
2032 for (i = 0; i < npx; i++) {
2033 const Double_t x0 = xMin + dx * i;
2034 const Double_t r2 = integral[i + 1] - integral[i];
2035 const Double_t r1 = Integral(x0, x0 + 0.5 * dx, 0.0) / total;
2036 gamma[i] = (2 * r2 - 4 * r1) / (dx * dx);
2037 beta[i] = r2 / dx - gamma[i] * dx;
2038 alpha[i] = x0;
2039 gamma[i] *= 2;
2040 }
2041
2042 // Be careful because of finite precision in the integral; Use the fact that the integral
2043 // is monotone increasing
2044 for (i = 0; i < nprobSum; i++) {
2045 const Double_t r = probSum[i];
2046 Int_t bin = TMath::Max(TMath::BinarySearch(npx + 1, integral.GetArray(), r), (Long64_t)0);
2047 // in case the prob is 1
2048 if (bin == npx) {
2049 q[i] = xMax;
2050 continue;
2051 }
2052 // LM use a tolerance 1.E-12 (integral precision)
2053 while (bin < npx - 1 && TMath::AreEqualRel(integral[bin + 1], r, 1E-12)) {
2054 if (TMath::AreEqualRel(integral[bin + 2], r, 1E-12)) bin++;
2055 else break;
2056 }
2057
2058 const Double_t rr = r - integral[bin];
2059 if (rr != 0.0) {
2060 Double_t xx = 0.0;
2061 const Double_t fac = -2.*gamma[bin] * rr / beta[bin] / beta[bin];
2062 if (fac != 0 && fac <= 1)
2063 xx = (-beta[bin] + TMath::Sqrt(beta[bin] * beta[bin] + 2 * gamma[bin] * rr)) / gamma[bin];
2064 else if (beta[bin] != 0.)
2065 xx = rr / beta[bin];
2066 q[i] = alpha[bin] + xx;
2067 } else {
2068 q[i] = alpha[bin];
2069 if (integral[bin + 1] == r) q[i] += dx;
2070 }
2071 }
2072
2073 return nprobSum;
2074}
2075////////////////////////////////////////////////////////////////////////////////
2076///
2077/// Compute the cumulative function at fNpx points between fXmin and fXmax.
2078/// Option can be used to force a log scale (option = "log"), linear (option = "lin") or automatic if empty.
2080
2081 fIntegral.resize(fNpx + 1);
2082 fAlpha.resize(fNpx + 1);
2083 fBeta.resize(fNpx);
2084 fGamma.resize(fNpx);
2085 fIntegral[0] = 0;
2086 fAlpha[fNpx] = 0;
2087 Double_t integ;
2088 Int_t intNegative = 0;
2089 Int_t i;
2090 Bool_t logbin = kFALSE;
2091 Double_t dx;
2094 TString opt(option);
2095 opt.ToUpper();
2096 // perform a log binning if specified by user (option="Log") or if some conditions are met
2097 // and the user explicitly does not specify a Linear binning option
2098 if (opt.Contains("LOG") || ((xmin > 0 && xmax / xmin > fNpx) && !opt.Contains("LIN"))) {
2099 logbin = kTRUE;
2100 fAlpha[fNpx] = 1;
2103 if (gDebug)
2104 Info("GetRandom", "Use log scale for tabulating the integral in [%f,%f] with %d points", fXmin, fXmax, fNpx);
2105 }
2106 dx = (xmax - xmin) / fNpx;
2107
2108 std::vector<Double_t> xx(fNpx + 1);
2109 for (i = 0; i < fNpx; i++) {
2110 xx[i] = xmin + i * dx;
2111 }
2112 xx[fNpx] = xmax;
2113 for (i = 0; i < fNpx; i++) {
2114 if (logbin) {
2115 integ = Integral(TMath::Power(10, xx[i]), TMath::Power(10, xx[i + 1]), 0.0);
2116 } else {
2117 integ = Integral(xx[i], xx[i + 1], 0.0);
2118 }
2119 if (integ < 0) {
2120 intNegative++;
2121 integ = -integ;
2122 }
2123 fIntegral[i + 1] = fIntegral[i] + integ;
2124 }
2125 if (intNegative > 0) {
2126 Warning("GetRandom", "function:%s has %d negative values: abs assumed", GetName(), intNegative);
2127 }
2128 if (fIntegral[fNpx] == 0) {
2129 Error("GetRandom", "Integral of function is zero");
2130 return kFALSE;
2131 }
2133 for (i = 1; i <= fNpx; i++) { // normalize integral to 1
2134 fIntegral[i] /= total;
2135 }
2136 // the integral r for each bin is approximated by a parabola
2137 // x = alpha + beta*r +gamma*r**2
2138 // compute the coefficients alpha, beta, gamma for each bin
2139 Double_t x0, r1, r2, r3;
2140 for (i = 0; i < fNpx; i++) {
2141 x0 = xx[i];
2142 r2 = fIntegral[i + 1] - fIntegral[i];
2143 if (logbin)
2144 r1 = Integral(TMath::Power(10, x0), TMath::Power(10, x0 + 0.5 * dx), 0.0) / total;
2145 else
2146 r1 = Integral(x0, x0 + 0.5 * dx, 0.0) / total;
2147 r3 = 2 * r2 - 4 * r1;
2148 if (TMath::Abs(r3) > 1e-8)
2149 fGamma[i] = r3 / (dx * dx);
2150 else
2151 fGamma[i] = 0;
2152 fBeta[i] = r2 / dx - fGamma[i] * dx;
2153 fAlpha[i] = x0;
2154 fGamma[i] *= 2;
2155 }
2156 return kTRUE;
2157}
2158
2159////////////////////////////////////////////////////////////////////////////////
2160/// Return a random number following this function shape.
2161///
2162/// @param rng Random number generator. By default (or when passing a nullptr) the global gRandom is used
2163/// @param option Option string which controls the binning used to compute the integral. Default mode is automatic depending of
2164/// xmax, xmin and Npx (function points).
2165/// Possible values are:
2166/// - "LOG" to force usage of log scale for tabulating the integral
2167/// - "LIN" to force usage of linear scale when tabulating the integral
2168///
2169/// The distribution contained in the function fname (TF1) is integrated
2170/// over the channel contents.
2171/// It is normalized to 1.
2172/// For each bin the integral is approximated by a parabola.
2173/// The parabola coefficients are stored as non persistent data members
2174/// Getting one random number implies:
2175/// - Generating a random number between 0 and 1 (say r1)
2176/// - Look in which bin in the normalized integral r1 corresponds to
2177/// - Evaluate the parabolic curve in the selected bin to find the corresponding X value.
2178///
2179/// The user can provide as optional parameter a Random number generator.
2180/// By default gRandom is used
2181///
2182/// If the ratio fXmax/fXmin > fNpx the integral is tabulated in log scale in x
2183/// A log scale for the intergral is also always used if a user specifies the "LOG" option
2184/// Instead if a user requestes a "LIN" option the integral binning is never done in log scale
2185/// whatever the fXmax/fXmin ratio is
2186///
2187/// Note that the parabolic approximation is very good as soon as the number of bins is greater than 50.
2188
2189
2191{
2192 // Check if integral array must be built
2193 if (fIntegral.empty()) {
2195 if (!ret) return TMath::QuietNaN();
2196 }
2197
2198
2199 // return random number
2200 Double_t r = (rng) ? rng->Rndm() : gRandom->Rndm();
2201 Int_t bin = TMath::BinarySearch(fNpx, fIntegral.data(), r);
2202 Double_t rr = r - fIntegral[bin];
2203
2204 Double_t yy;
2205 if (fGamma[bin] != 0)
2206 yy = (-fBeta[bin] + TMath::Sqrt(fBeta[bin] * fBeta[bin] + 2 * fGamma[bin] * rr)) / fGamma[bin];
2207 else
2208 yy = rr / fBeta[bin];
2209 Double_t x = fAlpha[bin] + yy;
2210 if (fAlpha[fNpx] > 0) return TMath::Power(10, x);
2211 return x;
2212}
2213
2214
2215////////////////////////////////////////////////////////////////////////////////
2216/// Return a random number following this function shape in [xmin,xmax]
2217///
2218/// The distribution contained in the function fname (TF1) is integrated
2219/// over the channel contents.
2220/// It is normalized to 1.
2221/// For each bin the integral is approximated by a parabola.
2222/// The parabola coefficients are stored as non persistent data members
2223/// Getting one random number implies:
2224/// - Generating a random number between 0 and 1 (say r1)
2225/// - Look in which bin in the normalized integral r1 corresponds to
2226/// - Evaluate the parabolic curve in the selected bin to find
2227/// the corresponding X value.
2228///
2229/// The parabolic approximation is very good as soon as the number
2230/// of bins is greater than 50.
2231///
2232/// @param xmin minimum value for generated random numbers
2233/// @param xmax maximum value for generated random numbers
2234/// @param rng (optional) random number generator pointer
2235/// @param option (optional) : `LOG` or `LIN` to force the usage of a log or linear scale for computing the cumulative integral table
2236///
2237/// IMPORTANT NOTE
2238///
2239/// The integral of the function is computed at fNpx points. If the function
2240/// has sharp peaks, you should increase the number of points (SetNpx)
2241/// such that the peak is correctly tabulated at several points.
2242
2244{
2245 // Check if integral array must be built
2246 if (fIntegral.empty()) {
2248 if (!ret) return TMath::QuietNaN();
2249 }
2250
2251 // return random number
2252 Double_t dx = (fXmax - fXmin) / fNpx;
2253 Int_t nbinmin = (Int_t)((xmin - fXmin) / dx);
2254 Int_t nbinmax = (Int_t)((xmax - fXmin) / dx) + 2;
2255 if (nbinmax > fNpx) nbinmax = fNpx;
2256
2257 Double_t pmin = fIntegral[nbinmin];
2258 Double_t pmax = fIntegral[nbinmax];
2259
2260 Double_t r, x, xx, rr;
2261 do {
2262 r = (rng) ? rng->Uniform(pmin, pmax) : gRandom->Uniform(pmin, pmax);
2263
2264 Int_t bin = TMath::BinarySearch(fNpx, fIntegral.data(), r);
2265 rr = r - fIntegral[bin];
2266
2267 if (fGamma[bin] != 0)
2268 xx = (-fBeta[bin] + TMath::Sqrt(fBeta[bin] * fBeta[bin] + 2 * fGamma[bin] * rr)) / fGamma[bin];
2269 else
2270 xx = rr / fBeta[bin];
2271 x = fAlpha[bin] + xx;
2272 } while (x < xmin || x > xmax);
2273 return x;
2274}
2275
2276////////////////////////////////////////////////////////////////////////////////
2277/// Return range of a generic N-D function.
2278
2279void TF1::GetRange(Double_t *rmin, Double_t *rmax) const
2280{
2281 int ndim = GetNdim();
2282
2283 double xmin = 0, ymin = 0, zmin = 0, xmax = 0, ymax = 0, zmax = 0;
2284 GetRange(xmin, ymin, zmin, xmax, ymax, zmax);
2285 for (int i = 0; i < ndim; ++i) {
2286 if (i == 0) {
2287 rmin[0] = xmin;
2288 rmax[0] = xmax;
2289 } else if (i == 1) {
2290 rmin[1] = ymin;
2291 rmax[1] = ymax;
2292 } else if (i == 2) {
2293 rmin[2] = zmin;
2294 rmax[2] = zmax;
2295 } else {
2296 rmin[i] = 0;
2297 rmax[i] = 0;
2298 }
2299 }
2300}
2301
2302
2303////////////////////////////////////////////////////////////////////////////////
2304/// Return range of a 1-D function.
2305
2307{
2308 xmin = fXmin;
2309 xmax = fXmax;
2310}
2311
2312
2313////////////////////////////////////////////////////////////////////////////////
2314/// Return range of a 2-D function.
2315
2317{
2318 xmin = fXmin;
2319 xmax = fXmax;
2320 ymin = 0;
2321 ymax = 0;
2322}
2323
2324
2325////////////////////////////////////////////////////////////////////////////////
2326/// Return range of function.
2327
2329{
2330 xmin = fXmin;
2331 xmax = fXmax;
2332 ymin = 0;
2333 ymax = 0;
2334 zmin = 0;
2335 zmax = 0;
2336}
2337
2338
2339////////////////////////////////////////////////////////////////////////////////
2340/// Get value corresponding to X in array of fSave values
2341
2343{
2344 if (fSave.empty()) return 0;
2345 //if (fSave == 0) return 0;
2346 int nsave = fSave.size();
2347 Double_t x = Double_t(xx[0]);
2348 Double_t y, dx, xmin, xmax, xlow, xup, ylow, yup;
2350 //if parent is a histogram the function had been saved at the center of the bins
2351 //we make a linear interpolation between the saved values
2352 xmin = fSave[nsave - 3];
2353 xmax = fSave[nsave - 2];
2354 if (fSave[nsave - 1] == xmax) {
2355 TH1 *h = (TH1 *)fParent;
2356 TAxis *xaxis = h->GetXaxis();
2357 Int_t bin1 = xaxis->FindBin(xmin);
2358 Int_t binup = xaxis->FindBin(xmax);
2359 Int_t bin = xaxis->FindBin(x);
2360 if (bin < binup) {
2361 xlow = xaxis->GetBinCenter(bin);
2362 xup = xaxis->GetBinCenter(bin + 1);
2363 ylow = fSave[bin - bin1];
2364 yup = fSave[bin - bin1 + 1];
2365 } else {
2366 xlow = xaxis->GetBinCenter(bin - 1);
2367 xup = xaxis->GetBinCenter(bin);
2368 ylow = fSave[bin - bin1 - 1];
2369 yup = fSave[bin - bin1];
2370 }
2371 dx = xup - xlow;
2372 y = ((xup * ylow - xlow * yup) + x * (yup - ylow)) / dx;
2373 return y;
2374 }
2375 }
2376 Int_t np = nsave - 3;
2377 xmin = fSave[np + 1];
2378 xmax = fSave[np + 2];
2379 dx = (xmax - xmin) / np;
2380 if (x < xmin || x > xmax) return 0;
2381 // return a Nan in case of x=nan, otherwise will crash later
2382 if (TMath::IsNaN(x)) return x;
2383 if (dx <= 0) return 0;
2384
2385 Int_t bin = TMath::Min(np - 1, Int_t((x - xmin) / dx));
2386 xlow = xmin + bin * dx;
2387 xup = xlow + dx;
2388 ylow = fSave[bin];
2389 yup = fSave[bin + 1];
2390 y = ((xup * ylow - xlow * yup) + x * (yup - ylow)) / dx;
2391 return y;
2392}
2393
2394
2395////////////////////////////////////////////////////////////////////////////////
2396/// Get x axis of the function.
2397
2399{
2400 TH1 *h = GetHistogram();
2401 if (!h) return nullptr;
2402 return h->GetXaxis();
2403}
2404
2405
2406////////////////////////////////////////////////////////////////////////////////
2407/// Get y axis of the function.
2408
2410{
2411 TH1 *h = GetHistogram();
2412 if (!h) return nullptr;
2413 return h->GetYaxis();
2414}
2415
2416
2417////////////////////////////////////////////////////////////////////////////////
2418/// Get z axis of the function. (In case this object is a TF2 or TF3)
2419
2421{
2422 TH1 *h = GetHistogram();
2423 if (!h) return nullptr;
2424 return h->GetZaxis();
2425}
2426
2427
2428
2429////////////////////////////////////////////////////////////////////////////////
2430/// Compute the gradient (derivative) wrt a parameter ipar
2431///
2432/// \param ipar index of parameter for which the derivative is computed
2433/// \param x point, where the derivative is computed
2434/// \param eps - if the errors of parameters have been computed, the step used in
2435/// numerical differentiation is eps*parameter_error.
2436///
2437/// if the errors have not been computed, step=eps is used
2438/// default value of eps = 0.01
2439/// Method is the same as in Derivative() function
2440///
2441/// If a parameter is fixed, the gradient on this parameter = 0
2442
2444{
2445 return GradientParTempl<Double_t>(ipar, x, eps);
2446}
2447
2448////////////////////////////////////////////////////////////////////////////////
2449/// Compute the gradient wrt parameters
2450/// If the TF1 object is based on a formula expression (TFormula)
2451/// and TFormula::GenerateGradientPar() has been successfully called
2452/// automatic differentiation using CLAD is used instead of the default
2453/// numerical differentiation
2454///
2455/// \param x point, were the gradient is computed
2456/// \param grad used to return the computed gradient, assumed to be of at least fNpar size
2457/// \param eps if the errors of parameters have been computed, the step used in
2458/// numerical differentiation is eps*parameter_error.
2459///
2460/// if the errors have not been computed, step=eps is used
2461/// default value of eps = 0.01
2462/// Method is the same as in Derivative() function
2463///
2464/// If a parameter is fixed, the gradient on this parameter = 0
2465
2467{
2468 if (fFormula && fFormula->HasGeneratedGradient()) {
2469 // need to zero the gradient buffer
2470 std::fill(grad, grad + fNpar, 0.);
2471 fFormula->GradientPar(x,grad);
2472 }
2473 else
2474 GradientParTempl<Double_t>(x, grad, eps);
2475}
2476
2477////////////////////////////////////////////////////////////////////////////////
2478/// Initialize parameters addresses.
2479
2480void TF1::InitArgs(const Double_t *x, const Double_t *params)
2481{
2482 if (fMethodCall) {
2483 Longptr_t args[2];
2484 args[0] = (Longptr_t)x;
2485 if (params) args[1] = (Longptr_t)params;
2486 else args[1] = (Longptr_t)GetParameters();
2487 fMethodCall->SetParamPtrs(args);
2488 }
2489}
2490
2491
2492////////////////////////////////////////////////////////////////////////////////
2493/// Create the basic function objects
2494
2496{
2497 TF1 *f1;
2499 if (!gROOT->GetListOfFunctions()->FindObject("gaus")) {
2500 f1 = new TF1("gaus", "gaus", -1, 1);
2501 f1->SetParameters(1, 0, 1);
2502 f1 = new TF1("gausn", "gausn", -1, 1);
2503 f1->SetParameters(1, 0, 1);
2504 f1 = new TF1("landau", "landau", -1, 1);
2505 f1->SetParameters(1, 0, 1);
2506 f1 = new TF1("landaun", "landaun", -1, 1);
2507 f1->SetParameters(1, 0, 1);
2508 f1 = new TF1("expo", "expo", -1, 1);
2509 f1->SetParameters(1, 1);
2510 for (Int_t i = 0; i < 10; i++) {
2511 auto f1name = TString::Format("pol%d", i);
2512 f1 = new TF1(f1name.Data(), f1name.Data(), -1, 1);
2513 f1->SetParameters(1, 1, 1, 1, 1, 1, 1, 1, 1, 1);
2514 // create also chebyshev polynomial
2515 // (note polynomial object will not be deleted)
2516 // note that these functions cannot be stored
2518 Double_t min = -1;
2519 Double_t max = 1;
2520 f1 = new TF1(TString::Format("chebyshev%d", i), pol, min, max, i + 1, 1);
2521 f1->SetParameters(1, 1, 1, 1, 1, 1, 1, 1, 1, 1);
2522 }
2523
2524 }
2525}
2526////////////////////////////////////////////////////////////////////////////////
2527/// IntegralOneDim or analytical integral
2528
2530{
2531 Double_t error = 0;
2532 if (GetNumber() > 0) {
2533 Double_t result = 0.;
2534 if (gDebug) {
2535 Info("computing analytical integral for function %s with number %d", GetName(), GetNumber());
2536 }
2537 result = AnalyticalIntegral(this, a, b);
2538 // if it is a formula that havent been implemented in analytical integral a NaN is return
2539 if (!TMath::IsNaN(result)) return result;
2540 if (gDebug)
2541 Warning("analytical integral not available for %s - with number %d compute numerical integral", GetName(), GetNumber());
2542 }
2543 return IntegralOneDim(a, b, epsrel, epsrel, error);
2544}
2545
2546////////////////////////////////////////////////////////////////////////////////
2547/// Return Integral of function between a and b using the given parameter values and
2548/// relative and absolute tolerance.
2549///
2550/// The default integrator defined in ROOT::Math::IntegratorOneDimOptions::DefaultIntegrator() is used
2551/// If ROOT contains the MathMore library the default integrator is set to be
2552/// the adaptive ROOT::Math::GSLIntegrator (based on QUADPACK) or otherwise the
2553/// ROOT::Math::GaussIntegrator is used
2554/// See the reference documentation of these classes for more information about the
2555/// integration algorithms
2556/// To change integration algorithm just do :
2557/// ROOT::Math::IntegratorOneDimOptions::SetDefaultIntegrator(IntegratorName);
2558/// Valid integrator names are:
2559/// - Gauss : for ROOT::Math::GaussIntegrator
2560/// - GaussLegendre : for ROOT::Math::GaussLegendreIntegrator
2561/// - Adaptive : for ROOT::Math::GSLIntegrator adaptive method (QAG)
2562/// - AdaptiveSingular : for ROOT::Math::GSLIntegrator adaptive singular method (QAGS)
2563/// - NonAdaptive : for ROOT::Math::GSLIntegrator non adaptive (QNG)
2564///
2565/// In order to use the GSL integrators one needs to have the MathMore library installed
2566///
2567/// Note 1:
2568///
2569/// Values of the function f(x) at the interval end-points A and B are not
2570/// required. The subprogram may therefore be used when these values are
2571/// undefined.
2572///
2573/// Note 2:
2574///
2575/// Instead of TF1::Integral, you may want to use the combination of
2576/// TF1::CalcGaussLegendreSamplingPoints and TF1::IntegralFast.
2577/// See an example with the following script:
2578///
2579/// ~~~ {.cpp}
2580/// void gint() {
2581/// TF1 *g = new TF1("g","gaus",-5,5);
2582/// g->SetParameters(1,0,1);
2583/// //default gaus integration method uses 6 points
2584/// //not suitable to integrate on a large domain
2585/// double r1 = g->Integral(0,5);
2586/// double r2 = g->Integral(0,1000);
2587///
2588/// //try with user directives computing more points
2589/// Int_t np = 1000;
2590/// double *x=new double[np];
2591/// double *w=new double[np];
2592/// g->CalcGaussLegendreSamplingPoints(np,x,w,1e-15);
2593/// double r3 = g->IntegralFast(np,x,w,0,5);
2594/// double r4 = g->IntegralFast(np,x,w,0,1000);
2595/// double r5 = g->IntegralFast(np,x,w,0,10000);
2596/// double r6 = g->IntegralFast(np,x,w,0,100000);
2597/// printf("g->Integral(0,5) = %g\n",r1);
2598/// printf("g->Integral(0,1000) = %g\n",r2);
2599/// printf("g->IntegralFast(n,x,w,0,5) = %g\n",r3);
2600/// printf("g->IntegralFast(n,x,w,0,1000) = %g\n",r4);
2601/// printf("g->IntegralFast(n,x,w,0,10000) = %g\n",r5);
2602/// printf("g->IntegralFast(n,x,w,0,100000)= %g\n",r6);
2603/// delete [] x;
2604/// delete [] w;
2605/// }
2606/// ~~~
2607///
2608/// This example produces the following results:
2609///
2610/// ~~~ {.cpp}
2611/// g->Integral(0,5) = 1.25331
2612/// g->Integral(0,1000) = 1.25319
2613/// g->IntegralFast(n,x,w,0,5) = 1.25331
2614/// g->IntegralFast(n,x,w,0,1000) = 1.25331
2615/// g->IntegralFast(n,x,w,0,10000) = 1.25331
2616/// g->IntegralFast(n,x,w,0,100000)= 1.253
2617/// ~~~
2618
2620{
2621 //Double_t *parameters = GetParameters();
2622 TF1_EvalWrapper wf1(this, nullptr, fgAbsValue);
2623 Double_t result = 0;
2624 Int_t status = 0;
2628 ROOT::Math::GaussIntegrator iod(epsabs, epsrel);
2629 iod.SetFunction(wf1);
2630 if (a != - TMath::Infinity() && b != TMath::Infinity())
2631 result = iod.Integral(a, b);
2632 else if (a == - TMath::Infinity() && b != TMath::Infinity())
2633 result = iod.IntegralLow(b);
2634 else if (a != - TMath::Infinity() && b == TMath::Infinity())
2635 result = iod.IntegralUp(a);
2636 else if (a == - TMath::Infinity() && b == TMath::Infinity())
2637 result = iod.Integral();
2638 error = iod.Error();
2639 status = iod.Status();
2640 } else {
2642 if (a != - TMath::Infinity() && b != TMath::Infinity())
2643 result = iod.Integral(a, b);
2644 else if (a == - TMath::Infinity() && b != TMath::Infinity())
2645 result = iod.IntegralLow(b);
2646 else if (a != - TMath::Infinity() && b == TMath::Infinity())
2647 result = iod.IntegralUp(a);
2648 else if (a == - TMath::Infinity() && b == TMath::Infinity())
2649 result = iod.Integral();
2650 error = iod.Error();
2651 status = iod.Status();
2652 }
2653 if (status != 0) {
2655 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);
2656 TString msg("\t\tFunction Parameters = {");
2657 for (int ipar = 0; ipar < GetNpar(); ++ipar) {
2658 msg += TString::Format(" %s = %f ", GetParName(ipar), GetParameter(ipar));
2659 if (ipar < GetNpar() - 1) msg += TString(",");
2660 else msg += TString("}");
2661 }
2662 Info("IntegralOneDim", "%s", msg.Data());
2663 }
2664 return result;
2665}
2666
2667////////////////////////////////////////////////////////////////////////////////
2668/// Return Error on Integral of a parametric function between a and b
2669/// due to the parameter uncertainties and their covariance matrix from the fit.
2670/// In addition to the integral limits, this method takes as input a pointer to the fitted parameter values
2671/// and a pointer the covariance matrix from the fit. These pointers should be retrieved from the
2672/// previously performed fit using the TFitResult class.
2673/// Note that to get the TFitResult, te fit should be done using the fit option `S`.
2674/// Example:
2675/// ~~~~{.cpp}
2676/// TFitResultPtr r = histo->Fit(func, "S");
2677/// func->IntegralError(x1,x2,r->GetParams(), r->GetCovarianceMatrix()->GetMatrixArray() );
2678/// ~~~~
2679///
2680/// IMPORTANT NOTE1:
2681///
2682/// A null pointer to the parameter values vector and to the covariance matrix can be passed.
2683/// In this case, when the parameter values pointer is null, the parameter values stored in this
2684/// TF1 function object are used in the integral error computation.
2685/// When the poassed pointer to the covariance matrix is null, a covariance matrix from the last fit is retrieved
2686/// from a global fitter instance when it exists. Note that the global fitter instance
2687/// esists only when ROOT is not running with multi-threading enabled (ROOT::IsImplicitMTEnabled() == True).
2688/// When the ovariance matrix from the last fit cannot be retrieved, an error message is printed and a zero value is
2689/// returned.
2690///
2691///
2692/// IMPORTANT NOTE2:
2693///
2694/// When no covariance matrix is passed and in the meantime a fit is done
2695/// using another function, the routine will signal an error and it will return zero only
2696/// when the number of fit parameter is different than the values stored in TF1 (TF1::GetNpar() ).
2697/// In the case that npar is the same, an incorrect result is returned.
2698///
2699/// IMPORTANT NOTE3:
2700///
2701/// The user must pass a pointer to the elements of the full covariance matrix
2702/// dimensioned with the right size (npar*npar), where npar is the total number of parameters (TF1::GetNpar()),
2703/// including also the fixed parameters. The covariance matrix must be retrieved from the TFitResult class as
2704/// shown above and not from TVirtualFitter::GetCovarianceMatrix() function.
2705
2706Double_t TF1::IntegralError(Double_t a, Double_t b, const Double_t *params, const Double_t *covmat, Double_t epsilon)
2707{
2708 Double_t x1[1];
2709 Double_t x2[1];
2710 x1[0] = a, x2[0] = b;
2711 return ROOT::TF1Helper::IntegralError(this, 1, x1, x2, params, covmat, epsilon);
2712}
2713
2714////////////////////////////////////////////////////////////////////////////////
2715/// Return Error on Integral of a parametric function with dimension larger than one
2716/// between a[] and b[] due to the parameters uncertainties.
2717/// For a TF1 with dimension larger than 1 (for example a TF2 or TF3)
2718/// TF1::IntegralMultiple is used for the integral calculation
2719///
2720/// In addition to the integral limits, this method takes as input a pointer to the fitted parameter values
2721/// and a pointer the covariance matrix from the fit. These pointers should be retrieved from the
2722/// previously performed fit using the TFitResult class.
2723/// Note that to get the TFitResult, te fit should be done using the fit option `S`.
2724/// Example:
2725/// ~~~~{.cpp}
2726/// TFitResultPtr r = histo2d->Fit(func2, "S");
2727/// func2->IntegralError(a,b,r->GetParams(), r->GetCovarianceMatrix()->GetMatrixArray() );
2728/// ~~~~
2729///
2730/// IMPORTANT NOTE1:
2731///
2732/// A null pointer to the parameter values vector and to the covariance matrix can be passed.
2733/// In this case, when the parameter values pointer is null, the parameter values stored in this
2734/// TF1 function object are used in the integral error computation.
2735/// When the poassed pointer to the covariance matrix is null, a covariance matrix from the last fit is retrieved
2736/// from a global fitter instance when it exists. Note that the global fitter instance
2737/// esists only when ROOT is not running with multi-threading enabled (ROOT::IsImplicitMTEnabled() == True).
2738/// When the ovariance matrix from the last fit cannot be retrieved, an error message is printed and a zero value is
2739/// returned.
2740///
2741///
2742/// IMPORTANT NOTE2:
2743///
2744/// When no covariance matrix is passed and in the meantime a fit is done
2745/// using another function, the routine will signal an error and it will return zero only
2746/// when the number of fit parameter is different than the values stored in TF1 (TF1::GetNpar() ).
2747/// In the case that npar is the same, an incorrect result is returned.
2748///
2749/// IMPORTANT NOTE3:
2750///
2751/// The user must pass a pointer to the elements of the full covariance matrix
2752/// dimensioned with the right size (npar*npar), where npar is the total number of parameters (TF1::GetNpar()),
2753/// including also the fixed parameters. The covariance matrix must be retrieved from the TFitResult class as
2754/// shown above and not from TVirtualFitter::GetCovarianceMatrix() function.
2755
2756Double_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)
2757{
2758 return ROOT::TF1Helper::IntegralError(this, n, a, b, params, covmat, epsilon);
2759}
2760
2761#ifdef INTHEFUTURE
2762////////////////////////////////////////////////////////////////////////////////
2763/// Gauss-Legendre integral, see CalcGaussLegendreSamplingPoints
2764
2766{
2767 if (!g) return 0;
2768 return IntegralFast(g->GetN(), g->GetX(), g->GetY(), a, b, params);
2769}
2770#endif
2771
2772
2773////////////////////////////////////////////////////////////////////////////////
2774/// Gauss-Legendre integral, see CalcGaussLegendreSamplingPoints
2775
2776Double_t TF1::IntegralFast(Int_t num, Double_t * /* x */, Double_t * /* w */, Double_t a, Double_t b, Double_t *params, Double_t epsilon)
2777{
2778 // Now x and w are not used!
2779
2780 ROOT::Math::WrappedTF1 wf1(*this);
2781 if (params)
2782 wf1.SetParameters(params);
2783 ROOT::Math::GaussLegendreIntegrator gli(num, epsilon);
2784 gli.SetFunction(wf1);
2785 return gli.Integral(a, b);
2786
2787}
2788
2789
2790////////////////////////////////////////////////////////////////////////////////
2791/// See more general prototype below.
2792/// This interface kept for back compatibility
2793/// It is recommended to use the other interface where one can specify also epsabs and the maximum number of
2794/// points
2795
2797{
2798 Int_t nfnevl, ifail;
2800 Double_t result = IntegralMultiple(n, a, b, maxpts, epsrel, epsrel, relerr, nfnevl, ifail);
2801 if (ifail > 0) {
2802 Warning("IntegralMultiple", "failed code=%d, ", ifail);
2803 }
2804 return result;
2805}
2806
2807
2808////////////////////////////////////////////////////////////////////////////////
2809/// This function computes, to an attempted specified accuracy, the value of
2810/// the integral
2811///
2812/// \param[in] n Number of dimensions [2,15]
2813/// \param[in] a,b One-dimensional arrays of length >= N . On entry A[i], and B[i],
2814/// contain the lower and upper limits of integration, respectively.
2815/// \param[in] maxpts Maximum number of function evaluations to be allowed.
2816/// maxpts >= 2^n +2*n*(n+1) +1
2817/// if maxpts<minpts, maxpts is set to 10*minpts
2818/// \param[in] epsrel Specified relative accuracy.
2819/// \param[in] epsabs Specified absolute accuracy.
2820/// The integration algorithm will attempt to reach either the relative or the absolute accuracy.
2821/// In case the maximum function called is reached the algorithm will stop earlier without having reached
2822/// the desired accuracy
2823///
2824/// \param[out] relerr Contains, on exit, an estimation of the relative accuracy of the result.
2825/// \param[out] nfnevl number of function evaluations performed.
2826/// \param[out] ifail
2827/// \parblock
2828/// 0 Normal exit. At least minpts and at most maxpts calls to the function were performed.
2829///
2830/// 1 maxpts is too small for the specified accuracy eps. The result and relerr contain the values obtainable for the
2831/// specified value of maxpts.
2832///
2833/// 3 n<2 or n>15
2834/// \endparblock
2835///
2836/// Method:
2837///
2838/// The default method used is the Genz-Mallik adaptive multidimensional algorithm
2839/// using the class ROOT::Math::AdaptiveIntegratorMultiDim (see the reference documentation of the class)
2840///
2841/// Other methods can be used by setting ROOT::Math::IntegratorMultiDimOptions::SetDefaultIntegrator()
2842/// to different integrators.
2843/// Other possible integrators are MC integrators based on the ROOT::Math::GSLMCIntegrator class
2844/// Possible methods are : Vegas, Miser or Plain
2845/// IN case of MC integration the accuracy is determined by the number of function calls, one should be
2846/// careful not to use a too large value of maxpts
2847///
2848
2849Double_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)
2850{
2852
2853 double result = 0;
2857 ROOT::Math::AdaptiveIntegratorMultiDim aimd(wf1, epsabs, epsrel, maxpts);
2858 //aimd.SetMinPts(minpts); // use default minpts ( n^2 + 2 * n * (n+1) +1 )
2859 result = aimd.Integral(a, b);
2860 relerr = aimd.RelError();
2861 nfnevl = aimd.NEval();
2862 ifail = aimd.Status();
2863 } else {
2864 // use default abs tolerance = relative tolerance
2866 result = imd.Integral(a, b);
2867 relerr = (result != 0) ? imd.Error() / std::abs(result) : imd.Error();
2868 nfnevl = 0;
2869 ifail = imd.Status();
2870 }
2871
2872
2873 return result;
2874}
2875
2876
2877////////////////////////////////////////////////////////////////////////////////
2878/// Return kTRUE if the function is valid
2879
2881{
2882 if (fFormula) return fFormula->IsValid();
2883 if (fMethodCall) return fMethodCall->IsValid();
2884 // function built on compiled functors are always valid by definition
2885 // (checked at compiled time)
2886 // invalid is a TF1 where the functor is null pointer and has not been saved
2887 if (!fFunctor && fSave.empty()) return kFALSE;
2888 return kTRUE;
2889}
2890
2891
2892//______________________________________________________________________________
2893
2894
2896{
2897 if (fType == EFType::kFormula) {
2898 printf("Formula based function: %s \n", GetName());
2899 assert(fFormula);
2900 fFormula->Print(option);
2901 } else if (fType > 0) {
2903 printf("Interpreted based function: %s(double *x, double *p). Ndim = %d, Npar = %d \n", GetName(), GetNdim(),
2904 GetNpar());
2905 else if (fType == EFType::kCompositionFcn) {
2906 printf("Composition based function: %s. Ndim = %d, Npar = %d \n", GetName(), GetNdim(), GetNpar());
2907 if (!fComposition)
2908 printf("fComposition not found!\n"); // this would be bad
2909 } else {
2910 if (fFunctor)
2911 printf("Compiled based function: %s based on a functor object. Ndim = %d, Npar = %d\n", GetName(),
2912 GetNdim(), GetNpar());
2913 else {
2914 printf("Function based on a list of points from a compiled based function: %s. Ndim = %d, Npar = %d, Npx "
2915 "= %zu\n",
2916 GetName(), GetNdim(), GetNpar(), fSave.size());
2917 if (fSave.empty())
2918 Warning("Print", "Function %s is based on a list of points but list is empty", GetName());
2919 }
2920 }
2921 TString opt(option);
2922 opt.ToUpper();
2923 if (opt.Contains("V")) {
2924 // print list of parameters
2925 if (fNpar > 0) {
2926 printf("List of Parameters: \n");
2927 for (int i = 0; i < fNpar; ++i)
2928 printf(" %20s = %10f \n", GetParName(i), GetParameter(i));
2929 }
2930 if (!fSave.empty()) {
2931 // print list of saved points
2932 printf("List of Saved points (N=%d): \n", int(fSave.size()));
2933 for (auto &x : fSave)
2934 printf("( %10f ) ", x);
2935 printf("\n");
2936 }
2937 }
2938 }
2939 if (fHistogram) {
2940 printf("Contained histogram\n");
2942 }
2943}
2944
2945////////////////////////////////////////////////////////////////////////////////
2946/// Paint this function with its current attributes.
2947/// The function is going to be converted in an histogram and the corresponding
2948/// histogram is painted.
2949/// The painted histogram can be retrieved calling afterwards the method TF1::GetHistogram()
2950
2952{
2953 fgCurrent = this;
2954
2955 TString opt0 = option, opt = option, optSAME;
2956 opt.ToLower();
2957
2958 if (opt.Contains("sames"))
2959 optSAME = "sames";
2960 else if (opt.Contains("same"))
2961 optSAME = "same";
2962 if (optSAME.Length())
2963 opt.ReplaceAll(optSAME, "");
2964 opt.ReplaceAll(' ', "");
2965
2966 Double_t xmin = fXmin, xmax = fXmax, pmin = fXmin, pmax = fXmax;
2967 if (gPad) {
2968 pmin = gPad->PadtoX(gPad->GetUxmin());
2969 pmax = gPad->PadtoX(gPad->GetUxmax());
2970 }
2971 if (optSAME.Length()) {
2972 // Completely outside
2973 if (xmax < pmin) return;
2974 if (xmin > pmax) return;
2975 }
2976
2977 // create an histogram using the function content (re-use it if already existing)
2979
2980 auto is_pfc = opt0.Index("PFC"); // Automatic Fill Color
2981 auto is_plc = opt0.Index("PLC"); // Automatic Line Color
2982 auto is_pmc = opt0.Index("PMC"); // Automatic Marker Color
2983 if (is_pfc != kNPOS || is_plc != kNPOS || is_pmc != kNPOS) {
2984 Int_t i = gPad->NextPaletteColor();
2985 if (is_pfc != kNPOS) { opt0.Replace(is_pfc, 3, " "); fHistogram->SetFillColor(i); }
2986 if (is_plc != kNPOS) { opt0.Replace(is_plc, 3, " "); fHistogram->SetLineColor(i); }
2987 if (is_pmc != kNPOS) { opt0.Replace(is_pmc, 3, " "); fHistogram->SetMarkerColor(i); }
2988 }
2989
2990 // set the optimal minimum and maximum
2993 if (minimum <= 0 && gPad && gPad->GetLogy()) minimum = -1111; // This can happen when switching from lin to log scale.
2994 if (gPad && gPad->GetUymin() < fHistogram->GetMinimum() &&
2995 !fHistogram->TestBit(TH1::kIsZoomed)) minimum = -1111; // This can happen after unzooming a fit.
2996 if (minimum == -1111) { // This can happen after unzooming.
2998 minimum = fHistogram->GetYaxis()->GetXmin();
2999 } else {
3000 minimum = fMinimum;
3001 // Optimize the computation of the scale in Y in case the min/max of the
3002 // function oscillate around a constant value
3003 if (minimum == -1111) {
3004 Double_t hmin;
3005 if (optSAME.Length() && gPad) hmin = gPad->GetUymin();
3006 else hmin = fHistogram->GetMinimum();
3007 if (hmin > 0) {
3008 Double_t hmax;
3009 Double_t hminpos = hmin;
3010 if (optSAME.Length() && gPad) hmax = gPad->GetUymax();
3011 else hmax = fHistogram->GetMaximum();
3012 hmin -= 0.05 * (hmax - hmin);
3013 if (hmin < 0) hmin = 0;
3014 if (hmin <= 0 && gPad && gPad->GetLogy()) hmin = hminpos;
3015 minimum = hmin;
3016 }
3017 }
3018 }
3019 fHistogram->SetMinimum(minimum);
3020 }
3021 if (maximum == -1111) {
3023 maximum = fHistogram->GetYaxis()->GetXmax();
3024 } else {
3025 maximum = fMaximum;
3026 }
3027 fHistogram->SetMaximum(maximum);
3028 }
3029
3030 // Draw the histogram.
3031 if (!gPad) return;
3032 if (opt.Length() == 0) {
3033 optSAME.Prepend("lf");
3034 fHistogram->Paint(optSAME.Data());
3035 } else {
3036 fHistogram->Paint(opt0.Data());
3037 }
3038}
3039
3040////////////////////////////////////////////////////////////////////////////////
3041/// Create histogram with bin content equal to function value
3042/// computed at the bin center
3043/// This histogram will be used to paint the function
3044/// A re-creation is forced and a new histogram is done if recreate=true
3045
3047{
3048 Int_t i;
3049 Double_t xv[1];
3050
3051 TH1 *histogram = nullptr;
3052
3053
3054 // Create a temporary histogram and fill each channel with the function value
3055 // Preserve axis titles
3056 TString xtitle = "";
3057 TString ytitle = "";
3058 char *semicol = (char *)strstr(GetTitle(), ";");
3059 if (semicol) {
3060 Int_t nxt = strlen(semicol);
3061 char *ctemp = new char[nxt];
3062 strlcpy(ctemp, semicol + 1, nxt);
3063 semicol = (char *)strstr(ctemp, ";");
3064 if (semicol) {
3065 *semicol = 0;
3066 ytitle = semicol + 1;
3067 }
3068 xtitle = ctemp;
3069 delete [] ctemp;
3070 }
3071 if (fHistogram) {
3072 // delete previous histograms if were done if done in different mode
3073 xtitle = fHistogram->GetXaxis()->GetTitle();
3074 ytitle = fHistogram->GetYaxis()->GetTitle();
3075 Bool_t test_logx = fHistogram->TestBit(TH1::kLogX);
3076 if (!gPad->GetLogx() && test_logx) {
3077 delete fHistogram;
3078 fHistogram = nullptr;
3079 recreate = kTRUE;
3080 }
3081 if (gPad->GetLogx() && !test_logx) {
3082 delete fHistogram;
3083 fHistogram = nullptr;
3084 recreate = kTRUE;
3085 }
3086 }
3087
3088 if (fHistogram && !recreate) {
3089 histogram = fHistogram;
3091 } else {
3092 // If logx, we must bin in logx and not in x
3093 // otherwise in case of several decades, one gets wrong results.
3094 if (xmin > 0 && gPad && gPad->GetLogx()) {
3095 Double_t *xbins = new Double_t[fNpx + 1];
3096 Double_t xlogmin = TMath::Log10(xmin);
3097 Double_t xlogmax = TMath::Log10(xmax);
3098 Double_t dlogx = (xlogmax - xlogmin) / ((Double_t)fNpx);
3099 for (i = 0; i <= fNpx; i++) {
3100 xbins[i] = gPad->PadtoX(xlogmin + i * dlogx);
3101 }
3102 histogram = new TH1D("Func", GetTitle(), fNpx, xbins);
3103 histogram->SetBit(TH1::kLogX);
3104 delete [] xbins;
3105 } else {
3106 histogram = new TH1D("Func", GetTitle(), fNpx, xmin, xmax);
3107 }
3108 if (fMinimum != -1111) histogram->SetMinimum(fMinimum);
3109 if (fMaximum != -1111) histogram->SetMaximum(fMaximum);
3110 histogram->SetDirectory(nullptr);
3111 }
3112 R__ASSERT(histogram);
3113
3114 // Restore axis titles.
3115 histogram->GetXaxis()->SetTitle(xtitle.Data());
3116 histogram->GetYaxis()->SetTitle(ytitle.Data());
3117 Double_t *parameters = GetParameters();
3118
3119 InitArgs(xv, parameters);
3120 for (i = 1; i <= fNpx; i++) {
3121 xv[0] = histogram->GetBinCenter(i);
3122 histogram->SetBinContent(i, EvalPar(xv, parameters));
3123 }
3124
3125 // Copy Function attributes to histogram attributes.
3126 histogram->SetBit(TH1::kNoStats);
3127 histogram->SetLineColor(GetLineColor());
3128 histogram->SetLineStyle(GetLineStyle());
3129 histogram->SetLineWidth(GetLineWidth());
3130 histogram->SetFillColor(GetFillColor());
3131 histogram->SetFillStyle(GetFillStyle());
3132 histogram->SetMarkerColor(GetMarkerColor());
3133 histogram->SetMarkerStyle(GetMarkerStyle());
3134 histogram->SetMarkerSize(GetMarkerSize());
3135
3136 // update saved histogram in case it was deleted or if it is the first time the method is called
3137 // for example when called from TF1::GetHistogram()
3138 if (!fHistogram) fHistogram = histogram;
3139 return histogram;
3140
3141}
3142
3143
3144////////////////////////////////////////////////////////////////////////////////
3145/// Release parameter number ipar during a fit operation.
3146/// After releasing it, the parameter
3147/// can vary freely in the fit. The parameter limits are reset to 0,0.
3148
3150{
3151 if (ipar < 0 || ipar > GetNpar() - 1) return;
3152 SetParLimits(ipar, 0, 0);
3153}
3154
3155
3156////////////////////////////////////////////////////////////////////////////////
3157/// Save values of function in array fSave
3158
3160{
3161 if (!fSave.empty())
3162 fSave.clear();
3163
3164 Double_t *parameters = GetParameters();
3165 //if (fSave != 0) {delete [] fSave; fSave = 0;}
3167 //if parent is a histogram save the function at the center of the bins
3168 if ((xmin > 0 && xmax > 0) && TMath::Abs(TMath::Log10(xmax / xmin) > TMath::Log10(fNpx))) {
3169 TH1 *h = (TH1 *)fParent;
3170 Int_t bin1 = h->GetXaxis()->FindBin(xmin);
3171 Int_t bin2 = h->GetXaxis()->FindBin(xmax);
3172 int nsave = bin2 - bin1 + 4;
3173 fSave.resize(nsave);
3174 Double_t xv[1];
3175
3176 InitArgs(xv, parameters);
3177 for (Int_t i = bin1; i <= bin2; i++) {
3178 xv[0] = h->GetXaxis()->GetBinCenter(i);
3179 fSave[i - bin1] = EvalPar(xv, parameters);
3180 }
3181 fSave[nsave - 3] = xmin;
3182 fSave[nsave - 2] = xmax;
3183 fSave[nsave - 1] = xmax;
3184 return;
3185 }
3186 }
3187
3188 Int_t npx = fNpx;
3189 if (npx <= 0)
3190 return;
3191
3192 Double_t dx = (xmax - xmin) / fNpx;
3193 if (dx <= 0) {
3194 dx = (fXmax - fXmin) / fNpx;
3195 npx--;
3196 xmin = fXmin + 0.5 * dx;
3197 xmax = fXmax - 0.5 * dx;
3198 }
3199 if (npx <= 0)
3200 return;
3201 fSave.resize(npx + 3);
3202 Double_t xv[1];
3203 InitArgs(xv, parameters);
3204 for (Int_t i = 0; i <= npx; i++) {
3205 xv[0] = xmin + dx * i;
3206 fSave[i] = EvalPar(xv, parameters);
3207 }
3208 fSave[npx + 1] = xmin;
3209 fSave[npx + 2] = xmax;
3210}
3211
3212
3213////////////////////////////////////////////////////////////////////////////////
3214/// Save primitive as a C++ statement(s) on output stream out
3215
3216void TF1::SavePrimitive(std::ostream &out, Option_t *option /*= ""*/)
3217{
3218 Int_t i;
3219 char quote = '"';
3220
3221 // Save the function as C code independant from ROOT.
3222 if (strstr(option, "cc")) {
3223 out << "double " << GetName() << "(double xv) {" << std::endl;
3224 Double_t dx = (fXmax - fXmin) / (fNpx - 1);
3225 out << " double x[" << fNpx << "] = {" << std::endl;
3226 out << " ";
3227 Int_t n = 0;
3228 for (i = 0; i < fNpx; i++) {
3229 out << fXmin + dx *i ;
3230 if (i < fNpx - 1) out << ", ";
3231 if (n++ == 10) {
3232 out << std::endl;
3233 out << " ";
3234 n = 0;
3235 }
3236 }
3237 out << std::endl;
3238 out << " };" << std::endl;
3239 out << " double y[" << fNpx << "] = {" << std::endl;
3240 out << " ";
3241 n = 0;
3242 for (i = 0; i < fNpx; i++) {
3243 out << Eval(fXmin + dx * i);
3244 if (i < fNpx - 1) out << ", ";
3245 if (n++ == 10) {
3246 out << std::endl;
3247 out << " ";
3248 n = 0;
3249 }
3250 }
3251 out << std::endl;
3252 out << " };" << std::endl;
3253 out << " if (xv<x[0]) return y[0];" << std::endl;
3254 out << " if (xv>x[" << fNpx - 1 << "]) return y[" << fNpx - 1 << "];" << std::endl;
3255 out << " int i, j=0;" << std::endl;
3256 out << " for (i=1; i<" << fNpx << "; i++) { if (xv < x[i]) break; j++; }" << std::endl;
3257 out << " return y[j] + (y[j + 1] - y[j]) / (x[j + 1] - x[j]) * (xv - x[j]);" << std::endl;
3258 out << "}" << std::endl;
3259 return;
3260 }
3261
3262 out << " " << std::endl;
3263
3264 // Either f1Number is computed locally or set from outside
3265 static Int_t f1Number = 0;
3266 TString f1Name(GetName());
3267 const char *l = strstr(option, "#");
3268 if (l != nullptr) {
3269 sscanf(&l[1], "%d", &f1Number);
3270 } else {
3271 ++f1Number;
3272 }
3273 f1Name += f1Number;
3274
3275 const char *addToGlobList = fParent ? ", TF1::EAddToList::kNo" : ", TF1::EAddToList::kDefault";
3276
3277 if (!fType) {
3278 out << " TF1 *" << f1Name.Data() << " = new TF1(" << quote << GetName() << quote << "," << quote << GetTitle() << quote << "," << fXmin << "," << fXmax << addToGlobList << ");" << std::endl;
3279 if (fNpx != 100) {
3280 out << " " << f1Name.Data() << "->SetNpx(" << fNpx << ");" << std::endl;
3281 }
3282 } else {
3283 out << " TF1 *" << f1Name.Data() << " = new TF1(" << quote << "*" << GetName() << quote << "," << fXmin << "," << fXmax << "," << GetNpar() << ");" << std::endl;
3284 out << " //The original function : " << GetTitle() << " had originally been created by:" << std::endl;
3285 out << " //TF1 *" << GetName() << " = new TF1(" << quote << GetName() << quote << "," << GetTitle() << "," << fXmin << "," << fXmax << "," << GetNpar();
3286 out << ", 1" << addToGlobList << ");" << std::endl;
3287 out << " " << f1Name.Data() << "->SetRange(" << fXmin << "," << fXmax << ");" << std::endl;
3288 out << " " << f1Name.Data() << "->SetName(" << quote << GetName() << quote << ");" << std::endl;
3289 out << " " << f1Name.Data() << "->SetTitle(" << quote << GetTitle() << quote << ");" << std::endl;
3290 if (fNpx != 100) {
3291 out << " " << f1Name.Data() << "->SetNpx(" << fNpx << ");" << std::endl;
3292 }
3293 Double_t dx = (fXmax - fXmin) / fNpx;
3294 Double_t xv[1];
3295 Double_t *parameters = GetParameters();
3296 InitArgs(xv, parameters);
3297 for (i = 0; i <= fNpx; i++) {
3298 xv[0] = fXmin + dx * i;
3299 Double_t save = EvalPar(xv, parameters);
3300 out << " " << f1Name.Data() << "->SetSavedPoint(" << i << "," << save << ");" << std::endl;
3301 }
3302 out << " " << f1Name.Data() << "->SetSavedPoint(" << fNpx + 1 << "," << fXmin << ");" << std::endl;
3303 out << " " << f1Name.Data() << "->SetSavedPoint(" << fNpx + 2 << "," << fXmax << ");" << std::endl;
3304 }
3305
3306 if (TestBit(kNotDraw)) {
3307 out << " " << f1Name.Data() << "->SetBit(TF1::kNotDraw);" << std::endl;
3308 }
3309
3310 SaveFillAttributes(out, f1Name.Data(), 0, 1001);
3311 SaveMarkerAttributes(out, f1Name.Data(), 1, 1, 1);
3312 SaveLineAttributes(out, f1Name.Data(), 1, 1, 4);
3313
3314 if (GetChisquare() != 0) {
3315 out << " " << f1Name.Data() << "->SetChisquare(" << GetChisquare() << ");" << std::endl;
3316 out << " " << f1Name.Data() << "->SetNDF(" << GetNDF() << ");" << std::endl;
3317 }
3318
3319 if (GetXaxis()) GetXaxis()->SaveAttributes(out, f1Name.Data(), "->GetXaxis()");
3320 if (GetYaxis()) GetYaxis()->SaveAttributes(out, f1Name.Data(), "->GetYaxis()");
3321
3322 Double_t parmin, parmax;
3323 for (i = 0; i < GetNpar(); i++) {
3324 out << " " << f1Name.Data() << "->SetParameter(" << i << "," << GetParameter(i) << ");" << std::endl;
3325 out << " " << f1Name.Data() << "->SetParError(" << i << "," << GetParError(i) << ");" << std::endl;
3326 GetParLimits(i, parmin, parmax);
3327 out << " " << f1Name.Data() << "->SetParLimits(" << i << "," << parmin << "," << parmax << ");" << std::endl;
3328 }
3329 if (!strstr(option, "nodraw")) {
3330 out << " " << f1Name.Data() << "->Draw("
3331 << quote << option << quote << ");" << std::endl;
3332 }
3333}
3334
3335
3336////////////////////////////////////////////////////////////////////////////////
3337/// Static function setting the current function.
3338/// the current function may be accessed in static C-like functions
3339/// when fitting or painting a function.
3340
3342{
3343 fgCurrent = f1;
3344}
3345
3346////////////////////////////////////////////////////////////////////////////////
3347/// Set the result from the fit
3348/// parameter values, errors, chi2, etc...
3349/// Optionally a pointer to a vector (with size fNpar) of the parameter indices in the FitResult can be passed
3350/// This is useful in the case of a combined fit with different functions, and the FitResult contains the global result
3351/// By default it is assume that indpar = {0,1,2,....,fNpar-1}.
3352
3354{
3355 Int_t npar = GetNpar();
3356 if (result.IsEmpty()) {
3357 Warning("SetFitResult", "Empty Fit result - nothing is set in TF1");
3358 return;
3359 }
3360 if (indpar == nullptr && npar != (int) result.NPar()) {
3361 Error("SetFitResult", "Invalid Fit result passed - number of parameter is %d , different than TF1::GetNpar() = %d", npar, result.NPar());
3362 return;
3363 }
3364 if (result.Chi2() > 0)
3365 SetChisquare(result.Chi2());
3366 else
3367 SetChisquare(result.MinFcnValue());
3368
3369 SetNDF(result.Ndf());
3370 SetNumberFitPoints(result.Ndf() + result.NFreeParameters());
3371
3372
3373 for (Int_t i = 0; i < npar; ++i) {
3374 Int_t ipar = (indpar != nullptr) ? indpar[i] : i;
3375 if (ipar < 0) continue;
3376 GetParameters()[i] = result.Parameter(ipar);
3377 // in case errors are not present do not set them
3378 if (ipar < (int) result.Errors().size())
3379 fParErrors[i] = result.Error(ipar);
3380 }
3381 //invalidate cached integral since parameters have changed
3382 Update();
3383
3384}
3385
3386
3387////////////////////////////////////////////////////////////////////////////////
3388/// Set the maximum value along Y for this function
3389/// In case the function is already drawn, set also the maximum in the
3390/// helper histogram
3391
3393{
3394 fMaximum = maximum;
3395 if (fHistogram) fHistogram->SetMaximum(maximum);
3396 if (gPad) gPad->Modified();
3397}
3398
3399
3400////////////////////////////////////////////////////////////////////////////////
3401/// Set the minimum value along Y for this function
3402/// In case the function is already drawn, set also the minimum in the
3403/// helper histogram
3404
3406{
3407 fMinimum = minimum;
3408 if (fHistogram) fHistogram->SetMinimum(minimum);
3409 if (gPad) gPad->Modified();
3410}
3411
3412
3413////////////////////////////////////////////////////////////////////////////////
3414/// Set the number of degrees of freedom
3415/// ndf should be the number of points used in a fit - the number of free parameters
3416
3418{
3419 fNDF = ndf;
3420}
3421
3422
3423////////////////////////////////////////////////////////////////////////////////
3424/// Set the number of points used to draw the function
3425///
3426/// The default number of points along x is 100 for 1-d functions and 30 for 2-d/3-d functions
3427/// You can increase this value to get a better resolution when drawing
3428/// pictures with sharp peaks or to get a better result when using TF1::GetRandom
3429/// the minimum number of points is 4, the maximum is 10000000 for 1-d and 10000 for 2-d/3-d functions
3430
3432{
3433 const Int_t minPx = 4;
3434 Int_t maxPx = 10000000;
3435 if (GetNdim() > 1) maxPx = 10000;
3436 if (npx >= minPx && npx <= maxPx) {
3437 fNpx = npx;
3438 } else {
3439 if (npx < minPx) fNpx = minPx;
3440 if (npx > maxPx) fNpx = maxPx;
3441 Warning("SetNpx", "Number of points must be >=%d && <= %d, fNpx set to %d", minPx, maxPx, fNpx);
3442 }
3443 Update();
3444}
3445////////////////////////////////////////////////////////////////////////////////
3446/// Set name of parameter number ipar
3447
3448void TF1::SetParName(Int_t ipar, const char *name)
3449{
3450 if (fFormula) {
3451 if (ipar < 0 || ipar >= GetNpar()) return;
3452 fFormula->SetParName(ipar, name);
3453 } else
3454 fParams->SetParName(ipar, name);
3455}
3456
3457////////////////////////////////////////////////////////////////////////////////
3458/// Set up to 10 parameter names.
3459/// Empty strings will be skipped, meaning that the corresponding name will not be changed.
3460
3461void TF1::SetParNames(const char *name0, const char *name1, const char *name2, const char *name3, const char *name4,
3462 const char *name5, const char *name6, const char *name7, const char *name8, const char *name9, const char *name10)
3463{
3464 // Note: this is not made a variadic template method because it would
3465 // presumably break the context menu in the TBrowser. Also, probably this
3466 // method should not be virtual, because if the user wants to change
3467 // parameter name setting behavior, the SetParName() method can be
3468 // overridden.
3469 if (fFormula)
3470 fFormula->SetParNames(name0, name1, name2, name3, name4, name5, name6, name7, name8, name9, name10);
3471 else
3472 fParams->SetParNames(name0, name1, name2, name3, name4, name5, name6, name7, name8, name9, name10);
3473}
3474////////////////////////////////////////////////////////////////////////////////
3475/// Set error for parameter number ipar
3476
3478{
3479 if (ipar < 0 || ipar > GetNpar() - 1) return;
3480 fParErrors[ipar] = error;
3481}
3482
3483
3484////////////////////////////////////////////////////////////////////////////////
3485/// Set errors for all active parameters
3486/// when calling this function, the array errors must have at least fNpar values
3487
3488void TF1::SetParErrors(const Double_t *errors)
3489{
3490 if (!errors) return;
3491 for (Int_t i = 0; i < GetNpar(); i++) fParErrors[i] = errors[i];
3492}
3493
3494
3495////////////////////////////////////////////////////////////////////////////////
3496/// Set lower and upper limits for parameter ipar.
3497/// The specified limits will be used in a fit operation.
3498/// Note that when this function is a pre-defined function (e.g. gaus)
3499/// one needs to use the fit option "B" to have the limits used in the fit.
3500/// See TH1::Fit(TF1*, Option_t *, Option_t *, Double_t, Double_t) for the fitting documentation
3501/// and the [fitting options](\ref HFitOpt)
3502///
3503/// To fix a parameter, use TF1::FixParameter
3504
3505void TF1::SetParLimits(Int_t ipar, Double_t parmin, Double_t parmax)
3506{
3507 Int_t npar = GetNpar();
3508 if (ipar < 0 || ipar > npar - 1) return;
3509 if (int(fParMin.size()) != npar) {
3510 fParMin.resize(npar);
3511 }
3512 if (int(fParMax.size()) != npar) {
3513 fParMax.resize(npar);
3514 }
3515 fParMin[ipar] = parmin;
3516 fParMax[ipar] = parmax;
3517}
3518
3519
3520////////////////////////////////////////////////////////////////////////////////
3521/// Initialize the upper and lower bounds to draw the function.
3522///
3523/// The function range is also used in an histogram fit operation
3524/// when the option "R" is specified.
3525
3527{
3528 fXmin = xmin;
3529 fXmax = xmax;
3531 fComposition->SetRange(xmin, xmax); // automatically updates sub-functions
3532 }
3533 Update();
3534}
3535
3536
3537////////////////////////////////////////////////////////////////////////////////
3538/// Restore value of function saved at point
3539
3541{
3542 if (fSave.empty()) {
3543 fSave.resize(fNpx + 3);
3544 }
3545 if (point < 0 || point >= int(fSave.size())) return;
3546 fSave[point] = value;
3547}
3548
3549
3550////////////////////////////////////////////////////////////////////////////////
3551/// Set function title
3552/// if title has the form "fffffff;xxxx;yyyy", it is assumed that
3553/// the function title is "fffffff" and "xxxx" and "yyyy" are the
3554/// titles for the X and Y axis respectively.
3555
3556void TF1::SetTitle(const char *title)
3557{
3558 if (!title) return;
3559 fTitle = title;
3560 if (!fHistogram) return;
3561 fHistogram->SetTitle(title);
3562 if (gPad) gPad->Modified();
3563}
3564
3565
3566////////////////////////////////////////////////////////////////////////////////
3567/// Stream a class object.
3568
3570{
3571 if (b.IsReading()) {
3572 UInt_t R__s, R__c;
3573 Version_t v = b.ReadVersion(&R__s, &R__c);
3574 // process new version with new TFormula class which is contained in TF1
3575 //printf("reading TF1....- version %d..\n",v);
3576
3577 if (v > 7) {
3578 // new classes with new TFormula
3579 // need to register the objects
3580 b.ReadClassBuffer(TF1::Class(), this, v, R__s, R__c);
3581 if (!TestBit(kNotGlobal)) {
3583 gROOT->GetListOfFunctions()->Add(this);
3584 }
3585 return;
3586 } else {
3587 ROOT::v5::TF1Data fold;
3588 //printf("Reading TF1 as v5::TF1Data- version %d \n",v);
3589 fold.Streamer(b, v, R__s, R__c, TF1::Class());
3590 // convert old TF1 to new one
3591 ((TF1v5Convert *)this)->Convert(fold);
3592 }
3593 }
3594
3595 // Writing
3596 else {
3597 Int_t saved = 0;
3598 // save not-formula functions as array of points
3599 if (fType > 0 && fSave.empty() && fType != EFType::kCompositionFcn) {
3600 saved = 1;
3601 Save(fXmin, fXmax, 0, 0, 0, 0);
3602 }
3603 b.WriteClassBuffer(TF1::Class(), this);
3604
3605 // clear vector contents
3606 if (saved) {
3607 fSave.clear();
3608 }
3609 }
3610}
3611
3612
3613////////////////////////////////////////////////////////////////////////////////
3614/// Called by functions such as SetRange, SetNpx, SetParameters
3615/// to force the deletion of the associated histogram or Integral
3616
3618{
3619 if (fHistogram) {
3620 TString XAxisTitle = fHistogram->GetXaxis()->GetTitle();
3621 TString YAxisTitle = fHistogram->GetYaxis()->GetTitle();
3622 Int_t XLabCol = fHistogram->GetXaxis()->GetLabelColor();
3623 Int_t YLabCol = fHistogram->GetYaxis()->GetLabelColor();
3624 Int_t XLabFont = fHistogram->GetXaxis()->GetLabelFont();
3625 Int_t YLabFont = fHistogram->GetYaxis()->GetLabelFont();
3626 Float_t XLabOffset = fHistogram->GetXaxis()->GetLabelOffset();
3627 Float_t YLabOffset = fHistogram->GetYaxis()->GetLabelOffset();
3628 Float_t XLabSize = fHistogram->GetXaxis()->GetLabelSize();
3629 Float_t YLabSize = fHistogram->GetYaxis()->GetLabelSize();
3630 Int_t XNdiv = fHistogram->GetXaxis()->GetNdivisions();
3631 Int_t YNdiv = fHistogram->GetYaxis()->GetNdivisions();
3632
3633 delete fHistogram;
3634 fHistogram = nullptr;
3635 GetHistogram();
3636
3637 fHistogram->GetXaxis()->SetTitle(XAxisTitle.Data());
3638 fHistogram->GetYaxis()->SetTitle(YAxisTitle.Data());
3639 fHistogram->GetXaxis()->SetLabelColor(XLabCol);
3640 fHistogram->GetYaxis()->SetLabelColor(YLabCol);
3641 fHistogram->GetXaxis()->SetLabelFont(XLabFont);
3642 fHistogram->GetYaxis()->SetLabelFont(YLabFont);
3643 fHistogram->GetXaxis()->SetLabelOffset(XLabOffset);
3644 fHistogram->GetYaxis()->SetLabelOffset(YLabOffset);
3645 fHistogram->GetXaxis()->SetLabelSize(XLabSize);
3646 fHistogram->GetYaxis()->SetLabelSize(YLabSize);
3649 }
3650 if (!fIntegral.empty()) {
3651 fIntegral.clear();
3652 fAlpha.clear();
3653 fBeta.clear();
3654 fGamma.clear();
3655 }
3656 if (fNormalized) {
3657 // need to compute the integral of the not-normalized function
3658 fNormalized = false;
3660 fNormalized = true;
3661 } else
3662 fNormIntegral = 0;
3663
3664 // std::vector<double>x(fNdim);
3665 // if ((fType == 1) && !fFunctor->Empty()) (*fFunctor)x.data(), (Double_t*)fParams);
3667 // double-check that the parameters are correct
3668 fComposition->SetParameters(GetParameters());
3669
3670 fComposition->Update(); // should not be necessary, but just to be safe
3671 }
3672}
3673
3674////////////////////////////////////////////////////////////////////////////////
3675/// Static function to set the global flag to reject points
3676/// the fgRejectPoint global flag is tested by all fit functions
3677/// if TRUE the point is not included in the fit.
3678/// This flag can be set by a user in a fitting function.
3679/// The fgRejectPoint flag is reset by the TH1 and TGraph fitting functions.
3680
3682{
3683 fgRejectPoint = reject;
3684}
3685
3686
3687////////////////////////////////////////////////////////////////////////////////
3688/// See TF1::RejectPoint above
3689
3691{
3692 return fgRejectPoint;
3693}
3694
3695////////////////////////////////////////////////////////////////////////////////
3696/// Return nth moment of function between a and b
3697///
3698/// See TF1::Integral() for parameter definitions
3699
3701{
3702 // wrapped function in interface for integral calculation
3703 // using abs value of integral
3704
3705 TF1_EvalWrapper func(this, params, kTRUE, n);
3706
3708
3709 giod.SetFunction(func);
3710 giod.SetRelTolerance(epsilon);
3711
3712 Double_t norm = giod.Integral(a, b);
3713 if (norm == 0) {
3714 Error("Moment", "Integral zero over range");
3715 return 0;
3716 }
3717
3718 // calculate now integral of x^n f(x)
3719 // wrapped the member function EvalNum in interface required by integrator using the functor class
3721 giod.SetFunction(xnfunc);
3722
3723 Double_t res = giod.Integral(a, b) / norm;
3724
3725 return res;
3726}
3727
3728
3729////////////////////////////////////////////////////////////////////////////////
3730/// Return nth central moment of function between a and b
3731/// (i.e the n-th moment around the mean value)
3732///
3733/// See TF1::Integral() for parameter definitions
3734///
3735/// \author Gene Van Buren <gene@bnl.gov>
3736
3738{
3739 TF1_EvalWrapper func(this, params, kTRUE, n);
3740
3742
3743 giod.SetFunction(func);
3744 giod.SetRelTolerance(epsilon);
3745
3746 Double_t norm = giod.Integral(a, b);
3747 if (norm == 0) {
3748 Error("Moment", "Integral zero over range");
3749 return 0;
3750 }
3751
3752 // calculate now integral of xf(x)
3753 // wrapped the member function EvalFirstMom in interface required by integrator using the functor class
3755 giod.SetFunction(xfunc);
3756
3757 // estimate of mean value
3758 Double_t xbar = giod.Integral(a, b) / norm;
3759
3760 // use different mean value in function wrapper
3761 func.fX0 = xbar;
3763 giod.SetFunction(xnfunc);
3764
3765 Double_t res = giod.Integral(a, b) / norm;
3766 return res;
3767}
3768
3769
3770//______________________________________________________________________________
3771// some useful static utility functions to compute sampling points for IntegralFast
3772////////////////////////////////////////////////////////////////////////////////
3773/// Type safe interface (static method)
3774/// The number of sampling points are taken from the TGraph
3775
3776#ifdef INTHEFUTURE
3778{
3779 if (!g) return;
3780 CalcGaussLegendreSamplingPoints(g->GetN(), g->GetX(), g->GetY(), eps);
3781}
3782
3783
3784////////////////////////////////////////////////////////////////////////////////
3785/// Type safe interface (static method)
3786/// A TGraph is created with new with num points and the pointer to the
3787/// graph is returned by the function. It is the responsibility of the
3788/// user to delete the object.
3789/// if num is invalid (<=0) NULL is returned
3790
3792{
3793 if (num <= 0)
3794 return 0;
3795
3796 TGraph *g = new TGraph(num);
3797 CalcGaussLegendreSamplingPoints(g->GetN(), g->GetX(), g->GetY(), eps);
3798 return g;
3799}
3800#endif
3801
3802
3803////////////////////////////////////////////////////////////////////////////////
3804/// Type: unsafe but fast interface filling the arrays x and w (static method)
3805///
3806/// Given the number of sampling points this routine fills the arrays x and w
3807/// of length num, containing the abscissa and weight of the Gauss-Legendre
3808/// n-point quadrature formula.
3809///
3810/// Gauss-Legendre:
3811/** \f[
3812 W(x)=1 -1<x<1 \\
3813 (j+1)P_{j+1} = (2j+1)xP_j-jP_{j-1}
3814 \f]
3815**/
3816/// num is the number of sampling points (>0)
3817/// x and w are arrays of size num
3818/// eps is the relative precision
3819///
3820/// If num<=0 or eps<=0 no action is done.
3821///
3822/// Reference: Numerical Recipes in C, Second Edition
3823
3825{
3826 // This function is just kept like this for backward compatibility!
3827
3829 gli.GetWeightVectors(x, w);
3830
3831
3832}
3833
3834
3835/** \class TF1Parameters
3836TF1 Parameters class
3837*/
3838
3839////////////////////////////////////////////////////////////////////////////////
3840/// Returns the parameter number given a name
3841/// not very efficient but list of parameters is typically small
3842/// could use a map if needed
3843
3845{
3846 for (unsigned int i = 0; i < fParNames.size(); ++i) {
3847 if (fParNames[i] == std::string(name)) return i;
3848 }
3849 return -1;
3850}
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:85
#define ClassImp(name)
Definition Rtypes.h:377
#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
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 * q
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:15
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:354
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:348
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:4978
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:3844
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:3149
virtual void SetParError(Int_t ipar, Double_t error)
Set error for parameter number ipar.
Definition TF1.cxx:3477
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:3681
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:3824
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:2409
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:3417
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:2706
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:2776
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:3392
void Print(Option_t *option="") const override
This method must be overridden when a class wants to print itself.
Definition TF1.cxx:2895
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:3617
virtual Double_t GetProb() const
Return the fit probability.
Definition TF1.cxx:1955
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:2443
TAxis * GetZaxis() const
Get z axis of the function. (In case this object is a TF2 or TF3)
Definition TF1.cxx:2420
virtual Double_t GetRandom(TRandom *rng=nullptr, Option_t *opt=nullptr)
Return a random number following this function shape.
Definition TF1.cxx:2190
virtual void SetRange(Double_t xmin, Double_t xmax)
Initialize the upper and lower bounds to draw the function.
Definition TF1.cxx:3526
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:3488
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:3046
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:3341
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:2529
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:3556
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:3461
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:2495
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:3431
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:3569
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:2951
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:3700
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:3737
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:2480
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:2849
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:3405
virtual void GetRange(Double_t *xmin, Double_t *xmax) const
Return range of a generic N-D function.
Definition TF1.cxx:2279
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:3505
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 Int_t GetQuantiles(Int_t nprobSum, Double_t *q, const Double_t *probSum)
Compute Quantiles for density distribution of this function.
Definition TF1.cxx:1992
virtual void SetParName(Int_t ipar, const char *name)
Set name of parameter number ipar.
Definition TF1.cxx:3448
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:2342
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:3216
virtual Bool_t IsValid() const
Return kTRUE if the function is valid.
Definition TF1.cxx:2880
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:3690
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:2079
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:3159
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:3540
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:2619
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:3353
TAxis * GetXaxis() const
Get x axis of the function.
Definition TF1.cxx:2398
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:8928
virtual Double_t GetBinCenter(Int_t bin) const
Return bin center for 1D histogram.
Definition TH1.cxx:9132
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:6709
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:7000
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:8536
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:9213
void Paint(Option_t *option="") override
Control routine to paint any kind of histograms.
Definition TH1.cxx:6197
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:8626
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:438
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:659
virtual void Warning(const char *method, const char *msgfmt,...) const
Issue warning message.
Definition TObject.cxx:973
virtual TObject * FindObject(const char *name) const
Must be redefined in derived classes.
Definition TObject.cxx:402
virtual void AppendPad(Option_t *option="")
Append graphics object to current pad.
Definition TObject.cxx:184
void SetBit(UInt_t f, Bool_t set)
Set or unset the user status bits as specified in f.
Definition TObject.cxx:780
virtual Bool_t InheritsFrom(const char *classname) const
Returns kTRUE if object inherits from class "classname".
Definition TObject.cxx:524
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition TObject.cxx:987
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:961
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