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