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