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