Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
TF1.cxx
Go to the documentation of this file.
1// @(#)root/hist:$Id$
2// Author: Rene Brun 18/08/95
3
4/*************************************************************************
5 * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers. *
6 * All rights reserved. *
7 * *
8 * For the licensing terms see $ROOTSYS/LICENSE. *
9 * For the list of contributors see $ROOTSYS/README/CREDITS. *
10 *************************************************************************/
11
12#include <iostream>
13#include <memory>
14#include "strlcpy.h"
15#include "snprintf.h"
16#include "TROOT.h"
17#include "TBuffer.h"
18#include "TMath.h"
19#include "TF1.h"
20#include "TH1.h"
21#include "TGraph.h"
22#include "TVirtualPad.h"
23#include "TStyle.h"
24#include "TRandom.h"
25#include "TObjString.h"
26#include "TInterpreter.h"
27#include "TPluginManager.h"
28#include "TBrowser.h"
29#include "TColor.h"
30#include "TMethodCall.h"
31#include "TF1Helper.h"
32#include "TF1NormSum.h"
33#include "TF1Convolution.h"
34#include "TVectorD.h"
35#include "TMatrixDSym.h"
36#include "TVirtualMutex.h"
38#include "Math/WrappedTF1.h"
41#include "Math/BrentMethods.h"
42#include "Math/Integrator.h"
49#include "Math/Functor.h"
50#include "Math/Minimizer.h"
52#include "Math/Factory.h"
53#include "Math/ChebyshevPol.h"
54#include "Fit/FitResult.h"
55// for I/O backward compatibility
56#include "v5/TF1Data.h"
57
58#include "AnalyticalIntegrals.h"
59
60std::atomic<Bool_t> TF1::fgAbsValue(kFALSE);
62std::atomic<Bool_t> TF1::fgAddToGlobList(kTRUE);
64
65using TF1Updater_t = void (*)(Int_t nobjects, TObject **from, TObject **to);
67
68
69namespace {
70struct TF1v5Convert : public TF1 {
71public:
72 void Convert(ROOT::v5::TF1Data &from)
73 {
74 // convert old TF1 to new one
75 fNpar = from.GetNpar();
76 fNdim = from.GetNdim();
77 if (from.fType == 0) {
78 // formula functions
79 // if ndim is not 1 set xmin max to zero to avoid error in ctor
80 double xmin = from.fXmin;
81 double xmax = from.fXmax;
82 if (fNdim > 1) {
83 xmin = 0;
84 xmax = 0;
85 }
86 TF1 fnew(from.GetName(), from.GetExpFormula(), xmin, xmax);
87 if (fNdim > 1) {
88 fnew.SetRange(from.fXmin, from.fXmax);
89 }
90 fnew.Copy(*this);
91 // need to set parameter values
92 if (from.GetParameters())
93 fFormula->SetParameters(from.GetParameters());
94 } else {
95 // case of a function pointers
96 fParams = std::make_unique<TF1Parameters>(fNpar);
97 fName = from.GetName();
98 fTitle = from.GetTitle();
99 // need to set parameter values
100 if (from.GetParameters())
101 fParams->SetParameters(from.GetParameters());
102 }
103 // copy the other data members
104 fNpx = from.fNpx;
105 fType = (EFType)from.fType;
106 fNpfits = from.fNpfits;
107 fNDF = from.fNDF;
108 fChisquare = from.fChisquare;
109 fMaximum = from.fMaximum;
110 fMinimum = from.fMinimum;
111 fXmin = from.fXmin;
112 fXmax = from.fXmax;
113
114 if (from.fParErrors)
115 fParErrors = std::vector<Double_t>(from.fParErrors, from.fParErrors + fNpar);
116 if (from.fParMin)
117 fParMin = std::vector<Double_t>(from.fParMin, from.fParMin + fNpar);
118 if (from.fParMax)
119 fParMax = std::vector<Double_t>(from.fParMax, from.fParMax + fNpar);
120 if (from.fNsave > 0) {
121 assert(from.fSave);
122 fSave = std::vector<Double_t>(from.fSave, from.fSave + from.fNsave);
123 }
124 // set the bits
125 for (int ibit = 0; ibit < 24; ++ibit)
126 if (from.TestBit(BIT(ibit)))
127 SetBit(BIT(ibit));
128
129 // copy the graph attributes
130 from.TAttLine::Copy(*this);
131 from.TAttFill::Copy(*this);
132 from.TAttMarker::Copy(*this);
133 }
134};
135} // unnamed namespace
136
137static void R__v5TF1Updater(Int_t nobjects, TObject **from, TObject **to)
138{
139 auto **fromv5 = (ROOT::v5::TF1Data **)from;
140 auto **target = (TF1v5Convert **)to;
141
142 for (int i = 0; i < nobjects; ++i) {
143 if (fromv5[i] && target[i])
144 target[i]->Convert(*fromv5[i]);
145 }
146}
147
149
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] == '(')
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 stored 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 if (fHistogram) {
1033 auto *h1 = (TH1 *)fHistogram->Clone();
1034 h1->SetDirectory(nullptr);
1035 ((TF1 &)obj).fHistogram = h1;
1036 } else {
1037 ((TF1 &)obj).fHistogram = nullptr;
1038 }
1039 ((TF1 &)obj).fMethodCall = nullptr;
1040 ((TF1 &)obj).fNormalized = fNormalized;
1041 ((TF1 &)obj).fNormIntegral = fNormIntegral;
1042 ((TF1 &)obj).fFormula = nullptr;
1043
1044 if (fFormula) assert(fFormula->GetNpar() == fNpar);
1045
1046 // use copy-constructor of TMethodCall
1047 TMethodCall *m = (fMethodCall) ? new TMethodCall(*fMethodCall) : nullptr;
1048 ((TF1 &)obj).fMethodCall.reset(m);
1049
1050 TFormula *formulaToCopy = (fFormula) ? new TFormula(*fFormula) : nullptr;
1051 ((TF1 &)obj).fFormula.reset(formulaToCopy);
1052
1054 ((TF1 &)obj).fParams.reset(paramsToCopy);
1055
1056 TF1FunctorPointer *functorToCopy = (fFunctor) ? fFunctor->Clone() : nullptr;
1057 ((TF1 &)obj).fFunctor.reset(functorToCopy);
1058
1059 TF1AbsComposition *comp = nullptr;
1060 if (fComposition) {
1061 comp = (TF1AbsComposition *)fComposition->IsA()->New();
1062 fComposition->Copy(*comp);
1063 }
1064 ((TF1 &)obj).fComposition.reset(comp);
1065}
1066
1067
1068////////////////////////////////////////////////////////////////////////////////
1069/// Make a complete copy of the underlying object. If 'newname' is set,
1070/// the copy's name will be set to that name.
1071
1072TObject* TF1::Clone(const char* newname) const
1073{
1074
1075 TF1* obj = (TF1*) TNamed::Clone(newname);
1076
1077 if (fHistogram) {
1078 obj->fHistogram = (TH1*)fHistogram->Clone();
1079 obj->fHistogram->SetDirectory(nullptr);
1080 }
1081
1082 return obj;
1083}
1084
1085
1086////////////////////////////////////////////////////////////////////////////////
1087/// Returns the first derivative of the function at point x,
1088/// computed by Richardson's extrapolation method (use 2 derivative estimates
1089/// to compute a third, more accurate estimation)
1090/// first, derivatives with steps h and h/2 are computed by central difference formulas
1091/// \f[
1092/// D(h) = \frac{f(x+h) - f(x-h)}{2h}
1093/// \f]
1094/// the final estimate
1095/// \f[
1096/// D = \frac{4D(h/2) - D(h)}{3}
1097/// \f]
1098/// "Numerical Methods for Scientists and Engineers", H.M.Antia, 2nd edition"
1099///
1100/// if the argument params is null, the current function parameters are used,
1101/// otherwise the parameters in params are used.
1102///
1103/// the argument eps may be specified to control the step size (precision).
1104/// the step size is taken as eps*(xmax-xmin).
1105/// the default value (0.001) should be good enough for the vast majority
1106/// of functions. Give a smaller value if your function has many changes
1107/// of the second derivative in the function range.
1108///
1109/// Getting the error via TF1::DerivativeError:
1110/// (total error = roundoff error + interpolation error)
1111/// the estimate of the roundoff error is taken as follows:
1112/// \f[
1113/// err = k\sqrt{f(x)^{2} + x^{2}deriv^{2}}\sqrt{\sum ai^{2}},
1114/// \f]
1115/// where k is the double precision, ai are coefficients used in
1116/// central difference formulas
1117/// interpolation error is decreased by making the step size h smaller.
1118///
1119/// \author Anna Kreshuk
1120
1122{
1123 if (GetNdim() > 1) {
1124 Warning("Derivative", "Function dimension is larger than one");
1125 }
1126
1128 double xmin, xmax;
1129 GetRange(xmin, xmax);
1130 // this is not optimal (should be used the average x instead of the range)
1131 double h = eps * std::abs(xmax - xmin);
1132 if (h <= 0) h = 0.001;
1133 double der = 0;
1134 if (params) {
1135 ROOT::Math::WrappedTF1 wtf(*(const_cast<TF1 *>(this)));
1136 wtf.SetParameters(params);
1137 der = rd.Derivative1(wtf, x, h);
1138 } else {
1139 // no need to set parameters used a non-parametric wrapper to avoid allocating
1140 // an array with parameter values
1142 der = rd.Derivative1(wf, x, h);
1143 }
1144
1145 gErrorTF1 = rd.Error();
1146 return der;
1147
1148}
1149
1150
1151////////////////////////////////////////////////////////////////////////////////
1152/// Returns the second derivative of the function at point x,
1153/// computed by Richardson's extrapolation method (use 2 derivative estimates
1154/// to compute a third, more accurate estimation)
1155/// first, derivatives with steps h and h/2 are computed by central difference formulas
1156/// \f[
1157/// D(h) = \frac{f(x+h) - 2f(x) + f(x-h)}{h^{2}}
1158/// \f]
1159/// the final estimate
1160/// \f[
1161/// D = \frac{4D(h/2) - D(h)}{3}
1162/// \f]
1163/// "Numerical Methods for Scientists and Engineers", H.M.Antia, 2nd edition"
1164///
1165/// if the argument params is null, the current function parameters are used,
1166/// otherwise the parameters in params are used.
1167///
1168/// the argument eps may be specified to control the step size (precision).
1169/// the step size is taken as eps*(xmax-xmin).
1170/// the default value (0.001) should be good enough for the vast majority
1171/// of functions. Give a smaller value if your function has many changes
1172/// of the second derivative in the function range.
1173///
1174/// Getting the error via TF1::DerivativeError:
1175/// (total error = roundoff error + interpolation error)
1176/// the estimate of the roundoff error is taken as follows:
1177/// \f[
1178/// err = k\sqrt{f(x)^{2} + x^{2}deriv^{2}}\sqrt{\sum ai^{2}},
1179/// \f]
1180/// where k is the double precision, ai are coefficients used in
1181/// central difference formulas
1182/// interpolation error is decreased by making the step size h smaller.
1183///
1184/// \author Anna Kreshuk
1185
1187{
1188 if (GetNdim() > 1) {
1189 Warning("Derivative2", "Function dimension is larger than one");
1190 }
1191
1193 double xmin, xmax;
1194 GetRange(xmin, xmax);
1195 // this is not optimal (should be used the average x instead of the range)
1196 double h = eps * std::abs(xmax - xmin);
1197 if (h <= 0) h = 0.001;
1198 double der = 0;
1199 if (params) {
1200 ROOT::Math::WrappedTF1 wtf(*(const_cast<TF1 *>(this)));
1201 wtf.SetParameters(params);
1202 der = rd.Derivative2(wtf, x, h);
1203 } else {
1204 // no need to set parameters used a non-parametric wrapper to avoid allocating
1205 // an array with parameter values
1207 der = rd.Derivative2(wf, x, h);
1208 }
1209
1210 gErrorTF1 = rd.Error();
1211
1212 return der;
1213}
1214
1215
1216////////////////////////////////////////////////////////////////////////////////
1217/// Returns the third derivative of the function at point x,
1218/// computed by Richardson's extrapolation method (use 2 derivative estimates
1219/// to compute a third, more accurate estimation)
1220/// first, derivatives with steps h and h/2 are computed by central difference formulas
1221/// \f[
1222/// D(h) = \frac{f(x+2h) - 2f(x+h) + 2f(x-h) - f(x-2h)}{2h^{3}}
1223/// \f]
1224/// the final estimate
1225/// \f[
1226/// D = \frac{4D(h/2) - D(h)}{3}
1227/// \f]
1228/// "Numerical Methods for Scientists and Engineers", H.M.Antia, 2nd edition"
1229///
1230/// if the argument params is null, the current function parameters are used,
1231/// otherwise the parameters in params are used.
1232///
1233/// the argument eps may be specified to control the step size (precision).
1234/// the step size is taken as eps*(xmax-xmin).
1235/// the default value (0.001) should be good enough for the vast majority
1236/// of functions. Give a smaller value if your function has many changes
1237/// of the second derivative in the function range.
1238///
1239/// Getting the error via TF1::DerivativeError:
1240/// (total error = roundoff error + interpolation error)
1241/// the estimate of the roundoff error is taken as follows:
1242/// \f[
1243/// err = k\sqrt{f(x)^{2} + x^{2}deriv^{2}}\sqrt{\sum ai^{2}},
1244/// \f]
1245/// where k is the double precision, ai are coefficients used in
1246/// central difference formulas
1247/// interpolation error is decreased by making the step size h smaller.
1248///
1249/// \author Anna Kreshuk
1250
1252{
1253 if (GetNdim() > 1) {
1254 Warning("Derivative3", "Function dimension is larger than one");
1255 }
1256
1258 double xmin, xmax;
1259 GetRange(xmin, xmax);
1260 // this is not optimal (should be used the average x instead of the range)
1261 double h = eps * std::abs(xmax - xmin);
1262 if (h <= 0) h = 0.001;
1263 double der = 0;
1264 if (params) {
1265 ROOT::Math::WrappedTF1 wtf(*(const_cast<TF1 *>(this)));
1266 wtf.SetParameters(params);
1267 der = rd.Derivative3(wtf, x, h);
1268 } else {
1269 // no need to set parameters used a non-parametric wrapper to avoid allocating
1270 // an array with parameter values
1272 der = rd.Derivative3(wf, x, h);
1273 }
1274
1275 gErrorTF1 = rd.Error();
1276 return der;
1277
1278}
1279
1280
1281////////////////////////////////////////////////////////////////////////////////
1282/// Static function returning the error of the last call to the of Derivative's
1283/// functions
1284
1286{
1287 return gErrorTF1;
1288}
1289
1290
1291////////////////////////////////////////////////////////////////////////////////
1292/// Compute distance from point px,py to a function.
1293///
1294/// Compute the closest distance of approach from point px,py to this
1295/// function. The distance is computed in pixels units.
1296///
1297/// Note that px is called with a negative value when the TF1 is in
1298/// TGraph or TH1 list of functions. In this case there is no point
1299/// looking at the histogram axis.
1300
1302{
1303 if (!fHistogram) return 9999;
1304 Int_t distance = 9999;
1305 if (px >= 0) {
1307 if (distance <= 1) return distance;
1308 } else {
1309 px = -px;
1310 }
1311
1312 Double_t xx[1];
1313 Double_t x = gPad->AbsPixeltoX(px);
1314 xx[0] = gPad->PadtoX(x);
1315 if (xx[0] < fXmin || xx[0] > fXmax) return distance;
1316 Double_t fval = Eval(xx[0]);
1317 Double_t y = gPad->YtoPad(fval);
1318 Int_t pybin = gPad->YtoAbsPixel(y);
1319 return TMath::Abs(py - pybin);
1320}
1321
1322
1323////////////////////////////////////////////////////////////////////////////////
1324/// Draw this function with its current attributes.
1325///
1326/// Possible option values are:
1327///
1328/// option | description
1329/// -------|----------------------------------------
1330/// "SAME" | superimpose on top of existing picture
1331/// "L" | connect all computed points with a straight line
1332/// "C" | connect all computed points with a smooth curve
1333/// "FC" | draw a fill area below a smooth curve
1334///
1335/// Note that the default value is "L". Therefore to draw on top
1336/// of an existing picture, specify option "LSAME"
1337///
1338/// NB. You must use DrawCopy if you want to draw several times the same
1339/// function in the current canvas.
1340
1342{
1343 TString opt = option;
1344 opt.ToLower();
1345 if (gPad && !opt.Contains("same")) gPad->Clear();
1346
1348
1349 gPad->IncrementPaletteColor(1, opt);
1350}
1351
1352
1353////////////////////////////////////////////////////////////////////////////////
1354/// Draw a copy of this function with its current attributes.
1355///
1356/// This function MUST be used instead of Draw when you want to draw
1357/// the same function with different parameters settings in the same canvas.
1358///
1359/// Possible option values are:
1360///
1361/// option | description
1362/// -------|----------------------------------------
1363/// "SAME" | superimpose on top of existing picture
1364/// "L" | connect all computed points with a straight line
1365/// "C" | connect all computed points with a smooth curve
1366/// "FC" | draw a fill area below a smooth curve
1367///
1368/// Note that the default value is "L". Therefore to draw on top
1369/// of an existing picture, specify option "LSAME"
1370
1372{
1373 TF1 *newf1 = (TF1 *)this->IsA()->New();
1374 Copy(*newf1);
1375 newf1->AppendPad(option);
1376 newf1->SetBit(kCanDelete);
1377 return newf1;
1378}
1379
1380
1381////////////////////////////////////////////////////////////////////////////////
1382/// Draw derivative of this function
1383///
1384/// An intermediate TGraph object is built and drawn with option.
1385/// The function returns a pointer to the TGraph object. Do:
1386///
1387/// TGraph *g = (TGraph*)myfunc.DrawDerivative(option);
1388///
1389/// The resulting graph will be drawn into the current pad.
1390/// If this function is used via the context menu, it recommended
1391/// to create a new canvas/pad before invoking this function.
1392
1394{
1395 TVirtualPad::TContext ctxt(gROOT->GetSelectedPad(), true, true);
1396
1397 TGraph *gr = new TGraph(this, "d");
1398 gr->Draw(option);
1399 return gr;
1400}
1401
1402
1403////////////////////////////////////////////////////////////////////////////////
1404/// Draw integral of this function
1405///
1406/// An intermediate TGraph object is built and drawn with option.
1407/// The function returns a pointer to the TGraph object. Do:
1408///
1409/// TGraph *g = (TGraph*)myfunc.DrawIntegral(option);
1410///
1411/// The resulting graph will be drawn into the current pad.
1412/// If this function is used via the context menu, it recommended
1413/// to create a new canvas/pad before invoking this function.
1414
1416{
1417 TVirtualPad::TContext ctxt(gROOT->GetSelectedPad(), true, true);
1418
1419 TGraph *gr = new TGraph(this, "i");
1420 gr->Draw(option);
1421 return gr;
1422}
1423
1424
1425////////////////////////////////////////////////////////////////////////////////
1426/// Draw function between xmin and xmax.
1427
1429{
1430// //if(Compile(formula)) return ;
1431 SetRange(xmin, xmax);
1432
1433 Draw(option);
1434}
1435
1436
1437////////////////////////////////////////////////////////////////////////////////
1438/// Evaluate this function.
1439///
1440/// Computes the value of this function (general case for a 3-d function)
1441/// at point x,y,z.
1442/// For a 1-d function give y=0 and z=0
1443/// The current value of variables x,y,z is passed through x, y and z.
1444/// The parameters used will be the ones in the array params if params is given
1445/// otherwise parameters will be taken from the stored data members fParams
1446
1448{
1449 if (fType == EFType::kFormula) return fFormula->Eval(x, y, z, t);
1450
1451 Double_t xx[4] = {x, y, z, t};
1452 Double_t *pp = (Double_t *)fParams->GetParameters();
1453 // if (fType == EFType::kInterpreted)((TF1 *)this)->InitArgs(xx, pp);
1454 return ((TF1 *)this)->EvalPar(xx, pp);
1455}
1456
1457
1458////////////////////////////////////////////////////////////////////////////////
1459/// Evaluate function with given coordinates and parameters.
1460///
1461/// Compute the value of this function at point defined by array x
1462/// and current values of parameters in array params.
1463/// If argument params is omitted or equal 0, the internal values
1464/// of parameters (array fParams) will be used instead.
1465/// For a 1-D function only x[0] must be given.
1466/// In case of a multi-dimensional function, the arrays x must be
1467/// filled with the corresponding number of dimensions.
1468///
1469/// WARNING. In case of an interpreted function (fType=2), it is the
1470/// user's responsibility to initialize the parameters via InitArgs
1471/// before calling this function.
1472/// InitArgs should be called at least once to specify the addresses
1473/// of the arguments x and params.
1474/// InitArgs should be called every time these addresses change.
1475
1477{
1478 //fgCurrent = this;
1479
1480 if (fType == EFType::kFormula) {
1482
1483 if (fNormalized && fNormIntegral != 0)
1484 return fFormula->EvalPar(x, params) / fNormIntegral;
1485 else
1486 return fFormula->EvalPar(x, params);
1487 }
1488 Double_t result = 0;
1490 if (fFunctor) {
1491 assert(fParams);
1492 if (params) result = ((TF1FunctorPointerImpl<Double_t> *)fFunctor.get())->fImpl((Double_t *)x, (Double_t *)params);
1493 else result = ((TF1FunctorPointerImpl<Double_t> *)fFunctor.get())->fImpl((Double_t *)x, (Double_t *)fParams->GetParameters());
1494
1495 } else result = GetSave(x);
1496
1497 if (fNormalized && fNormIntegral != 0)
1499
1500 return result;
1501 }
1502 if (fType == EFType::kInterpreted) {
1503 if (fMethodCall) fMethodCall->Execute(result);
1504 else result = GetSave(x);
1505
1506 if (fNormalized && fNormIntegral != 0)
1508
1509 return result;
1510 }
1511
1512#ifdef R__HAS_VECCORE
1513 if (fType == EFType::kTemplVec) {
1514 if (fFunctor) {
1515 if (params) result = EvalParVec(x, params);
1516 else result = EvalParVec(x, (Double_t *) fParams->GetParameters());
1517 }
1518 else {
1519 result = GetSave(x);
1520 }
1521
1522 if (fNormalized && fNormIntegral != 0)
1524
1525 return result;
1526 }
1527#endif
1528
1530 if (!fComposition)
1531 Error("EvalPar", "Composition function not found");
1532
1533 result = (*fComposition)(x, params);
1534 }
1535
1536 return result;
1537}
1538
1539/// Evaluate the uncertainty of the function at location x due to the parameter
1540/// uncertainties. If covMatrix is nullptr, assumes uncorrelated uncertainties,
1541/// otherwise the input covariance matrix (e.g. from a fit performed with
1542/// option "S") is used. Implemented for 1-d only.
1543/// @note to obtain confidence intervals of a fit result for drawing purposes,
1544/// see instead ROOT::Fit::FitResult::GetConfidenceInterval()
1546{
1547 TVectorD grad(GetNpar());
1548 GradientPar(&x, grad.GetMatrixArray());
1549 if (!covMatrix) {
1550 Double_t variance = 0;
1551 for(Int_t iPar = 0; iPar < GetNpar(); iPar++) {
1553 }
1554 return std::sqrt(variance);
1555 }
1556 return std::sqrt(covMatrix->Similarity(grad));
1557}
1558
1559////////////////////////////////////////////////////////////////////////////////
1560/// Execute action corresponding to one event.
1561///
1562/// This member function is called when a F1 is clicked with the locator
1563
1565{
1566 if (!gPad) return;
1567
1568 if (fHistogram) fHistogram->ExecuteEvent(event, px, py);
1569
1570 if (!gPad->GetView()) {
1571 if (event == kMouseMotion) gPad->SetCursor(kHand);
1572 }
1573}
1574
1575
1576////////////////////////////////////////////////////////////////////////////////
1577/// Fix the value of a parameter for a fit operation
1578/// The specified value will be used in the fit and
1579/// the parameter will be constant (nor varying) during fitting
1580/// Note that when using pre-defined functions (e.g gaus),
1581/// one needs to use the fit option 'B' to have the fix of the paramter
1582/// effective. See TH1::Fit(TF1*, Option_t *, Option_t *, Double_t, Double_t) for
1583/// the fitting documentation and the fitting options.
1584
1586{
1587 if (ipar < 0 || ipar > GetNpar() - 1) return;
1588 SetParameter(ipar, value);
1589 if (value != 0) SetParLimits(ipar, value, value);
1590 else SetParLimits(ipar, 1, 1);
1591}
1592
1593
1594////////////////////////////////////////////////////////////////////////////////
1595/// Static function returning the current function being processed
1596
1598{
1599 ::Warning("TF1::GetCurrent", "This function is obsolete and is working only for the current painted functions");
1600 return fgCurrent;
1601}
1602
1603
1604////////////////////////////////////////////////////////////////////////////////
1605/// Return a pointer to the histogram used to visualise the function
1606/// Note that this histogram is managed by the function and
1607/// in same case it is automatically deleted when some TF1 functions are called
1608/// such as TF1::SetParameters, TF1::SetNpx, TF1::SetRange
1609/// It is then reccomended either to clone the return object or calling again teh GetHistogram
1610/// function whenever is needed
1611
1613{
1614 if (fHistogram) return fHistogram;
1615
1616 // histogram has not been yet created - create it
1617 // should not we make this function not const ??
1618 const_cast<TF1 *>(this)->fHistogram = const_cast<TF1 *>(this)->CreateHistogram();
1619 if (!fHistogram) Error("GetHistogram", "Error creating histogram for function %s of type %s", GetName(), IsA()->GetName());
1620 return fHistogram;
1621}
1622
1623
1624////////////////////////////////////////////////////////////////////////////////
1625/// Returns the maximum value of the function
1626///
1627/// Method:
1628/// First, the grid search is used to bracket the maximum
1629/// with the step size = (xmax-xmin)/fNpx.
1630/// This way, the step size can be controlled via the SetNpx() function.
1631/// If the function is unimodal or if its extrema are far apart, setting
1632/// the fNpx to a small value speeds the algorithm up many times.
1633/// Then, Brent's method is applied on the bracketed interval
1634/// epsilon (default = 1.E-10) controls the relative accuracy (if |x| > 1 )
1635/// and absolute (if |x| < 1) and maxiter (default = 100) controls the maximum number
1636/// of iteration of the Brent algorithm
1637/// If the flag logx is set the grid search is done in log step size
1638/// This is done automatically if the log scale is set in the current Pad
1639///
1640/// NOTE: see also TF1::GetMaximumX and TF1::GetX
1641
1643{
1644 if (xmin >= xmax) {
1645 xmin = fXmin;
1646 xmax = fXmax;
1647 }
1648
1649 if (!logx && gPad != nullptr) logx = gPad->GetLogx();
1650
1652 GInverseFunc g(this);
1654 bm.SetFunction(wf1, xmin, xmax);
1655 bm.SetNpx(fNpx);
1656 bm.SetLogScan(logx);
1657 bm.Minimize(maxiter, epsilon, epsilon);
1658 Double_t x;
1659 x = - bm.FValMinimum();
1660
1661 return x;
1662}
1663
1664
1665////////////////////////////////////////////////////////////////////////////////
1666/// Returns the X value corresponding to the maximum value of the function
1667///
1668/// Method:
1669/// First, the grid search is used to bracket the maximum
1670/// with the step size = (xmax-xmin)/fNpx.
1671/// This way, the step size can be controlled via the SetNpx() function.
1672/// If the function is unimodal or if its extrema are far apart, setting
1673/// the fNpx to a small value speeds the algorithm up many times.
1674/// Then, Brent's method is applied on the bracketed interval
1675/// epsilon (default = 1.E-10) controls the relative accuracy (if |x| > 1 )
1676/// and absolute (if |x| < 1) and maxiter (default = 100) controls the maximum number
1677/// of iteration of the Brent algorithm
1678/// If the flag logx is set the grid search is done in log step size
1679/// This is done automatically if the log scale is set in the current Pad
1680///
1681/// NOTE: see also TF1::GetX
1682
1684{
1685 if (xmin >= xmax) {
1686 xmin = fXmin;
1687 xmax = fXmax;
1688 }
1689
1690 if (!logx && gPad != nullptr) logx = gPad->GetLogx();
1691
1693 GInverseFunc g(this);
1695 bm.SetFunction(wf1, xmin, xmax);
1696 bm.SetNpx(fNpx);
1697 bm.SetLogScan(logx);
1698 bm.Minimize(maxiter, epsilon, epsilon);
1699 Double_t x;
1700 x = bm.XMinimum();
1701
1702 return x;
1703}
1704
1705
1706////////////////////////////////////////////////////////////////////////////////
1707/// Returns the minimum value of the function on the (xmin, xmax) interval
1708///
1709/// Method:
1710/// First, the grid search is used to bracket the maximum
1711/// with the step size = (xmax-xmin)/fNpx. This way, the step size
1712/// can be controlled via the SetNpx() function. If the function is
1713/// unimodal or if its extrema are far apart, setting the fNpx to
1714/// a small value speeds the algorithm up many times.
1715/// Then, Brent's method is applied on the bracketed interval
1716/// epsilon (default = 1.E-10) controls the relative accuracy (if |x| > 1 )
1717/// and absolute (if |x| < 1) and maxiter (default = 100) controls the maximum number
1718/// of iteration of the Brent algorithm
1719/// If the flag logx is set the grid search is done in log step size
1720/// This is done automatically if the log scale is set in the current Pad
1721///
1722/// NOTE: see also TF1::GetMaximumX and TF1::GetX
1723
1725{
1726 if (xmin >= xmax) {
1727 xmin = fXmin;
1728 xmax = fXmax;
1729 }
1730
1731 if (!logx && gPad != nullptr) logx = gPad->GetLogx();
1732
1735 bm.SetFunction(wf1, xmin, xmax);
1736 bm.SetNpx(fNpx);
1737 bm.SetLogScan(logx);
1738 bm.Minimize(maxiter, epsilon, epsilon);
1739 Double_t x;
1740 x = bm.FValMinimum();
1741
1742 return x;
1743}
1744
1745////////////////////////////////////////////////////////////////////////////////
1746/// Find the minimum of a function of whatever dimension.
1747/// While GetMinimum works only for 1D function , GetMinimumNDim works for all dimensions
1748/// since it uses the minimizer interface
1749/// vector x at beginning will contained the initial point, on exit will contain the result
1750
1752{
1753 R__ASSERT(x != nullptr);
1754
1755 int ndim = GetNdim();
1756 if (ndim == 0) {
1757 Error("GetMinimumNDim", "Function of dimension 0 - return Eval(x)");
1758 return (const_cast<TF1 &>(*this))(x);
1759 }
1760
1761 // create minimizer class
1765
1766 if (min == nullptr) {
1767 Error("GetMinimumNDim", "Error creating minimizer %s", minimName);
1768 return 0;
1769 }
1770
1771 // minimizer will be set using default values
1772 if (epsilon > 0) min->SetTolerance(epsilon);
1773 if (maxiter > 0) min->SetMaxFunctionCalls(maxiter);
1774
1775 // create wrapper class from TF1 (cannot use Functor, t.b.i.)
1776 ROOT::Math::WrappedMultiFunction<TF1 &> objFunc(const_cast<TF1 &>(*this), ndim);
1777 // create -f(x) when searching for the maximum
1778 GInverseFuncNdim invFunc(const_cast<TF1 *>(this));
1780 if (!findmax)
1781 min->SetFunction(objFunc);
1782 else
1783 min->SetFunction(objFuncInv);
1784
1785 std::vector<double> rmin(ndim);
1786 std::vector<double> rmax(ndim);
1787 GetRange(&rmin[0], &rmax[0]);
1788 for (int i = 0; i < ndim; ++i) {
1789 const char *xname = nullptr;
1790 double stepSize = 0.1;
1791 // use range for step size or give some value depending on x if range is not defined
1792 if (rmax[i] > rmin[i])
1793 stepSize = (rmax[i] - rmin[i]) / 100;
1794 else if (std::abs(x[i]) > 1.)
1795 stepSize = 0.1 * x[i];
1796
1797 // set variable names
1798 if (ndim <= 3) {
1799 if (i == 0) {
1800 xname = "x";
1801 } else if (i == 1) {
1802 xname = "y";
1803 } else {
1804 xname = "z";
1805 }
1806 } else {
1807 xname = TString::Format("x_%d", i);
1808 // arbitrary step sie (should be computed from range)
1809 }
1810
1811 if (rmin[i] < rmax[i]) {
1812 //Info("GetMinMax","setting limits on %s - [ %f , %f ]",xname,rmin[i],rmax[i]);
1813 min->SetLimitedVariable(i, xname, x[i], stepSize, rmin[i], rmax[i]);
1814 } else {
1815 min->SetVariable(i, xname, x[i], stepSize);
1816 }
1817 }
1818
1819 bool ret = min->Minimize();
1820 if (!ret) {
1821 Error("GetMinimumNDim", "Error minimizing function %s", GetName());
1822 }
1823 if (min->X()) std::copy(min->X(), min->X() + ndim, x);
1824 double fmin = min->MinValue();
1825 delete min;
1826 // need to revert sign in case looking for maximum
1827 return (findmax) ? -fmin : fmin;
1828
1829}
1830
1831
1832////////////////////////////////////////////////////////////////////////////////
1833/// Returns the X value corresponding to the minimum value of the function
1834/// on the (xmin, xmax) interval
1835///
1836/// Method:
1837/// First, the grid search is used to bracket the maximum
1838/// with the step size = (xmax-xmin)/fNpx. This way, the step size
1839/// can be controlled via the SetNpx() function. If the function is
1840/// unimodal or if its extrema are far apart, setting the fNpx to
1841/// a small value speeds the algorithm up many times.
1842/// Then, Brent's method is applied on the bracketed interval
1843/// epsilon (default = 1.E-10) controls the relative accuracy (if |x| > 1 )
1844/// and absolute (if |x| < 1) and maxiter (default = 100) controls the maximum number
1845/// of iteration of the Brent algorithm
1846/// If the flag logx is set the grid search is done in log step size
1847/// This is done automatically if the log scale is set in the current Pad
1848///
1849/// NOTE: see also TF1::GetX
1850
1852{
1853 if (xmin >= xmax) {
1854 xmin = fXmin;
1855 xmax = fXmax;
1856 }
1857
1860 bm.SetFunction(wf1, xmin, xmax);
1861 bm.SetNpx(fNpx);
1862 bm.SetLogScan(logx);
1863 bm.Minimize(maxiter, epsilon, epsilon);
1864 Double_t x;
1865 x = bm.XMinimum();
1866
1867 return x;
1868}
1869
1870
1871////////////////////////////////////////////////////////////////////////////////
1872/// Returns the X value corresponding to the function value fy for (xmin<x<xmax).
1873/// in other words it can find the roots of the function when fy=0 and successive calls
1874/// by changing the next call to [xmin+eps,xmax] where xmin is the previous root.
1875///
1876/// Method:
1877/// First, the grid search is used to bracket the maximum
1878/// with the step size = (xmax-xmin)/fNpx. This way, the step size
1879/// can be controlled via the SetNpx() function. If the function is
1880/// unimodal or if its extrema are far apart, setting the fNpx to
1881/// a small value speeds the algorithm up many times.
1882/// Then, Brent's method is applied on the bracketed interval
1883/// epsilon (default = 1.E-10) controls the relative accuracy (if |x| > 1 )
1884/// and absolute (if |x| < 1) and maxiter (default = 100) controls the maximum number
1885/// of iteration of the Brent algorithm
1886/// If the flag logx is set the grid search is done in log step size
1887/// This is done automatically if the log scale is set in the current Pad
1888///
1889/// NOTE: see also TF1::GetMaximumX, TF1::GetMinimumX
1890
1892{
1893 if (xmin >= xmax) {
1894 xmin = fXmin;
1895 xmax = fXmax;
1896 }
1897
1898 if (!logx && gPad != nullptr) logx = gPad->GetLogx();
1899
1900 GFunc g(this, fy);
1903 brf.SetFunction(wf1, xmin, xmax);
1904 brf.SetNpx(fNpx);
1905 brf.SetLogScan(logx);
1906 bool ret = brf.Solve(maxiter, epsilon, epsilon);
1907 if (!ret) Error("GetX","[%f,%f] is not a valid interval",xmin,xmax);
1908 return (ret) ? brf.Root() : TMath::QuietNaN();
1909}
1910
1911////////////////////////////////////////////////////////////////////////////////
1912/// Return the number of degrees of freedom in the fit
1913/// the fNDF parameter has been previously computed during a fit.
1914/// The number of degrees of freedom corresponds to the number of points
1915/// used in the fit minus the number of free parameters.
1916
1918{
1919 Int_t npar = GetNpar();
1920 if (fNDF == 0 && (fNpfits > npar)) return fNpfits - npar;
1921 return fNDF;
1922}
1923
1924
1925////////////////////////////////////////////////////////////////////////////////
1926/// Return the number of free parameters
1927
1929{
1930 Int_t ntot = GetNpar();
1931 Int_t nfree = ntot;
1932 Double_t al, bl;
1933 for (Int_t i = 0; i < ntot; i++) {
1934 ((TF1 *)this)->GetParLimits(i, al, bl);
1935 if (al * bl != 0 && al >= bl) nfree--;
1936 }
1937 return nfree;
1938}
1939
1940
1941////////////////////////////////////////////////////////////////////////////////
1942/// Redefines TObject::GetObjectInfo.
1943/// Displays the function info (x, function value)
1944/// corresponding to cursor position px,py
1945
1946char *TF1::GetObjectInfo(Int_t px, Int_t /* py */) const
1947{
1948 static char info[64];
1949 Double_t x = gPad->PadtoX(gPad->AbsPixeltoX(px));
1950 snprintf(info, 64, "(x=%g, f=%g)", x, ((TF1 *)this)->Eval(x));
1951 return info;
1952}
1953
1954
1955////////////////////////////////////////////////////////////////////////////////
1956/// Return value of parameter number ipar
1957
1959{
1960 if (ipar < 0 || ipar > GetNpar() - 1) return 0;
1961 return fParErrors[ipar];
1962}
1963
1964
1965////////////////////////////////////////////////////////////////////////////////
1966/// Return limits for parameter ipar.
1967
1969{
1970 parmin = 0;
1971 parmax = 0;
1972 int n = fParMin.size();
1973 assert(n == int(fParMax.size()) && n <= fNpar);
1974 if (ipar < 0 || ipar > n - 1) return;
1975 parmin = fParMin[ipar];
1976 parmax = fParMax[ipar];
1977}
1978
1979
1980////////////////////////////////////////////////////////////////////////////////
1981/// Return the fit probability
1982
1984{
1985 if (fNDF <= 0) return 0;
1986 return TMath::Prob(fChisquare, fNDF);
1987}
1988
1989////////////////////////////////////////////////////////////////////////////////
1990/// Compute Quantiles for density distribution of this function
1991///
1992/// Quantile x_p of a probability distribution Function F is defined as
1993/// \f[
1994/// F(x_{p}) = \int_{xmin}^{x_{p}} f dx = p \text{with} 0 <= p <= 1.
1995/// \f]
1996/// For instance the median \f$ x_{\frac{1}{2}} \f$ of a distribution is defined as that value
1997/// of the random variable for which the distribution function equals 0.5:
1998/// \f[
1999/// F(x_{\frac{1}{2}}) = \prod(x < x_{\frac{1}{2}}) = \frac{1}{2}
2000/// \f]
2001///
2002/// \param[in] n maximum size of array xp and size of array p
2003/// \param[out] xp array filled with n quantiles evaluated at p. Memory has to be preallocated by caller.
2004/// \param[in] p array of cumulative probabilities where quantiles should be evaluated.
2005/// It is assumed to contain at least n values.
2006/// \return n, the number of quantiles computed (same as input argument n)
2007///
2008/// Getting quantiles from two histograms and storing results in a TGraph,
2009/// a so-called QQ-plot
2010///
2011/// TGraph *gr = new TGraph(nprob);
2012/// f1->GetQuantiles(nprob,gr->GetX(),p);
2013/// f2->GetQuantiles(nprob,gr->GetY(),p);
2014/// gr->Draw("alp");
2015///
2016/// \author Eddy Offermann
2017/// \warning Function leads to undefined behavior if xp or p are null or
2018/// their size does not match with n
2019
2021{
2022 // LM: change to use fNpx
2023 // should we change code to use a root finder ?
2024 // It should be more precise and more efficient
2025 const Int_t npx = TMath::Max(fNpx, 2 * n);
2026 const Double_t xMin = GetXmin();
2027 const Double_t xMax = GetXmax();
2028 const Double_t dx = (xMax - xMin) / npx;
2029
2030 TArrayD integral(npx + 1);
2031 TArrayD alpha(npx);
2032 TArrayD beta(npx);
2033 TArrayD gamma(npx);
2034
2035 integral[0] = 0;
2036 Int_t intNegative = 0;
2037 Int_t i;
2038 for (i = 0; i < npx; i++) {
2039 Double_t integ = Integral(Double_t(xMin + i * dx), Double_t(xMin + i * dx + dx), 0.0);
2040 if (integ < 0) {
2041 intNegative++;
2042 integ = -integ;
2043 }
2044 integral[i + 1] = integral[i] + integ;
2045 }
2046
2047 if (intNegative > 0)
2048 Warning("GetQuantiles", "function:%s has %d negative values: abs assumed",
2049 GetName(), intNegative);
2050 if (integral[npx] == 0) {
2051 Error("GetQuantiles", "Integral of function is zero");
2052 return 0;
2053 }
2054
2055 const Double_t total = integral[npx];
2056 for (i = 1; i <= npx; i++) integral[i] /= total;
2057 //the integral r for each bin is approximated by a parabola
2058 // x = alpha + beta*r +gamma*r**2
2059 // compute the coefficients alpha, beta, gamma for each bin
2060 for (i = 0; i < npx; i++) {
2061 const Double_t x0 = xMin + dx * i;
2062 const Double_t r2 = integral[i + 1] - integral[i];
2063 const Double_t r1 = Integral(x0, x0 + 0.5 * dx, 0.0) / total;
2064 gamma[i] = (2 * r2 - 4 * r1) / (dx * dx);
2065 beta[i] = r2 / dx - gamma[i] * dx;
2066 alpha[i] = x0;
2067 gamma[i] *= 2;
2068 }
2069
2070 // Be careful because of finite precision in the integral; Use the fact that the integral
2071 // is monotone increasing
2072 for (i = 0; i < n; i++) {
2073 const Double_t r = p[i];
2074 Int_t bin = TMath::Max(TMath::BinarySearch(npx + 1, integral.GetArray(), r), (Long64_t)0);
2075 // in case the prob is 1
2076 if (bin == npx) {
2077 xp[i] = xMax;
2078 continue;
2079 }
2080 // LM use a tolerance 1.E-12 (integral precision)
2081 while (bin < npx - 1 && TMath::AreEqualRel(integral[bin + 1], r, 1E-12)) {
2082 if (TMath::AreEqualRel(integral[bin + 2], r, 1E-12)) bin++;
2083 else break;
2084 }
2085
2086 const Double_t rr = r - integral[bin];
2087 if (rr != 0.0) {
2088 Double_t xx = 0.0;
2089 const Double_t fac = -2.*gamma[bin] * rr / beta[bin] / beta[bin];
2090 if (fac != 0 && fac <= 1)
2091 xx = (-beta[bin] + TMath::Sqrt(beta[bin] * beta[bin] + 2 * gamma[bin] * rr)) / gamma[bin];
2092 else if (beta[bin] != 0.)
2093 xx = rr / beta[bin];
2094 xp[i] = alpha[bin] + xx;
2095 } else {
2096 xp[i] = alpha[bin];
2097 if (integral[bin + 1] == r) xp[i] += dx;
2098 }
2099 }
2100
2101 return n;
2102}
2103////////////////////////////////////////////////////////////////////////////////
2104///
2105/// Compute the cumulative function at fNpx points between fXmin and fXmax.
2106/// Option can be used to force a log scale (option = "log"), linear (option = "lin") or automatic if empty.
2108
2109 fIntegral.resize(fNpx + 1);
2110 fAlpha.resize(fNpx + 1);
2111 fBeta.resize(fNpx);
2112 fGamma.resize(fNpx);
2113 fIntegral[0] = 0;
2114 fAlpha[fNpx] = 0;
2116 Int_t intNegative = 0;
2117 Int_t i;
2119 Double_t dx;
2122 TString opt(option);
2123 opt.ToUpper();
2124 // perform a log binning if specified by user (option="Log") or if some conditions are met
2125 // and the user explicitly does not specify a Linear binning option
2126 if (opt.Contains("LOG") || ((xmin > 0 && xmax / xmin > fNpx) && !opt.Contains("LIN"))) {
2127 logbin = kTRUE;
2128 fAlpha[fNpx] = 1;
2131 if (gDebug)
2132 Info("GetRandom", "Use log scale for tabulating the integral in [%f,%f] with %d points", fXmin, fXmax, fNpx);
2133 }
2134 dx = (xmax - xmin) / fNpx;
2135
2136 std::vector<Double_t> xx(fNpx + 1);
2137 for (i = 0; i < fNpx; i++) {
2138 xx[i] = xmin + i * dx;
2139 }
2140 xx[fNpx] = xmax;
2141 for (i = 0; i < fNpx; i++) {
2142 if (logbin) {
2143 integ = Integral(TMath::Power(10, xx[i]), TMath::Power(10, xx[i + 1]), 0.0);
2144 } else {
2145 integ = Integral(xx[i], xx[i + 1], 0.0);
2146 }
2147 if (integ < 0) {
2148 intNegative++;
2149 integ = -integ;
2150 }
2151 fIntegral[i + 1] = fIntegral[i] + integ;
2152 }
2153 if (intNegative > 0) {
2154 Warning("GetRandom", "function:%s has %d negative values: abs assumed", GetName(), intNegative);
2155 }
2156 if (fIntegral[fNpx] == 0) {
2157 Error("GetRandom", "Integral of function is zero");
2158 return kFALSE;
2159 }
2161 for (i = 1; i <= fNpx; i++) { // normalize integral to 1
2162 fIntegral[i] /= total;
2163 }
2164 // the integral r for each bin is approximated by a parabola
2165 // x = alpha + beta*r +gamma*r**2
2166 // compute the coefficients alpha, beta, gamma for each bin
2167 Double_t x0, r1, r2, r3;
2168 for (i = 0; i < fNpx; i++) {
2169 x0 = xx[i];
2170 r2 = fIntegral[i + 1] - fIntegral[i];
2171 if (logbin)
2172 r1 = Integral(TMath::Power(10, x0), TMath::Power(10, x0 + 0.5 * dx), 0.0) / total;
2173 else
2174 r1 = Integral(x0, x0 + 0.5 * dx, 0.0) / total;
2175 r3 = 2 * r2 - 4 * r1;
2176 if (TMath::Abs(r3) > 1e-8)
2177 fGamma[i] = r3 / (dx * dx);
2178 else
2179 fGamma[i] = 0;
2180 fBeta[i] = r2 / dx - fGamma[i] * dx;
2181 fAlpha[i] = x0;
2182 fGamma[i] *= 2;
2183 }
2184 return kTRUE;
2185}
2186
2187////////////////////////////////////////////////////////////////////////////////
2188/// Return a random number following this function shape.
2189///
2190/// @param rng Random number generator. By default (or when passing a nullptr) the global gRandom is used
2191/// @param option Option string which controls the binning used to compute the integral. Default mode is automatic depending of
2192/// xmax, xmin and Npx (function points).
2193/// Possible values are:
2194/// - "LOG" to force usage of log scale for tabulating the integral
2195/// - "LIN" to force usage of linear scale when tabulating the integral
2196///
2197/// The distribution contained in the function fname (TF1) is integrated
2198/// over the channel contents.
2199/// It is normalized to 1.
2200/// For each bin the integral is approximated by a parabola.
2201/// The parabola coefficients are stored as non persistent data members
2202/// Getting one random number implies:
2203/// - Generating a random number between 0 and 1 (say r1)
2204/// - Look in which bin in the normalized integral r1 corresponds to
2205/// - Evaluate the parabolic curve in the selected bin to find the corresponding X value.
2206///
2207/// The user can provide as optional parameter a Random number generator.
2208/// By default gRandom is used
2209///
2210/// If the ratio fXmax/fXmin > fNpx the integral is tabulated in log scale in x
2211/// A log scale for the intergral is also always used if a user specifies the "LOG" option
2212/// Instead if a user requestes a "LIN" option the integral binning is never done in log scale
2213/// whatever the fXmax/fXmin ratio is
2214///
2215/// Note that the parabolic approximation is very good as soon as the number of bins is greater than 50.
2216
2217
2219{
2220 // Check if integral array must be built
2221 if (fIntegral.empty()) {
2223 if (!ret) return TMath::QuietNaN();
2224 }
2225
2226
2227 // return random number
2228 Double_t r = (rng) ? rng->Rndm() : gRandom->Rndm();
2229 Int_t bin = TMath::BinarySearch(fNpx, fIntegral.data(), r);
2230 Double_t rr = r - fIntegral[bin];
2231
2232 Double_t yy;
2233 if (fGamma[bin] != 0)
2234 yy = (-fBeta[bin] + TMath::Sqrt(fBeta[bin] * fBeta[bin] + 2 * fGamma[bin] * rr)) / fGamma[bin];
2235 else
2236 yy = rr / fBeta[bin];
2237 Double_t x = fAlpha[bin] + yy;
2238 if (fAlpha[fNpx] > 0) return TMath::Power(10, x);
2239 return x;
2240}
2241
2242
2243////////////////////////////////////////////////////////////////////////////////
2244/// Return a random number following this function shape in [xmin,xmax]
2245///
2246/// The distribution contained in the function fname (TF1) is integrated
2247/// over the channel contents.
2248/// It is normalized to 1.
2249/// For each bin the integral is approximated by a parabola.
2250/// The parabola coefficients are stored as non persistent data members
2251/// Getting one random number implies:
2252/// - Generating a random number between 0 and 1 (say r1)
2253/// - Look in which bin in the normalized integral r1 corresponds to
2254/// - Evaluate the parabolic curve in the selected bin to find
2255/// the corresponding X value.
2256///
2257/// The parabolic approximation is very good as soon as the number
2258/// of bins is greater than 50.
2259///
2260/// @param xmin minimum value for generated random numbers
2261/// @param xmax maximum value for generated random numbers
2262/// @param rng (optional) random number generator pointer
2263/// @param option (optional) : `LOG` or `LIN` to force the usage of a log or linear scale for computing the cumulative integral table
2264///
2265/// IMPORTANT NOTE
2266///
2267/// The integral of the function is computed at fNpx points. If the function
2268/// has sharp peaks, you should increase the number of points (SetNpx)
2269/// such that the peak is correctly tabulated at several points.
2270
2272{
2273 // Check if integral array must be built
2274 if (fIntegral.empty()) {
2276 if (!ret) return TMath::QuietNaN();
2277 }
2278
2279 // return random number
2280 Double_t dx = (fXmax - fXmin) / fNpx;
2281 Int_t nbinmin = (Int_t)((xmin - fXmin) / dx);
2282 Int_t nbinmax = (Int_t)((xmax - fXmin) / dx) + 2;
2283 if (nbinmax > fNpx) nbinmax = fNpx;
2284
2287
2288 Double_t r, x, xx, rr;
2289 do {
2290 r = (rng) ? rng->Uniform(pmin, pmax) : gRandom->Uniform(pmin, pmax);
2291
2292 Int_t bin = TMath::BinarySearch(fNpx, fIntegral.data(), r);
2293 rr = r - fIntegral[bin];
2294
2295 if (fGamma[bin] != 0)
2296 xx = (-fBeta[bin] + TMath::Sqrt(fBeta[bin] * fBeta[bin] + 2 * fGamma[bin] * rr)) / fGamma[bin];
2297 else
2298 xx = rr / fBeta[bin];
2299 x = fAlpha[bin] + xx;
2300 } while (x < xmin || x > xmax);
2301 return x;
2302}
2303
2304////////////////////////////////////////////////////////////////////////////////
2305/// Return range of a generic N-D function.
2306
2308{
2309 int ndim = GetNdim();
2310
2311 double xmin = 0, ymin = 0, zmin = 0, xmax = 0, ymax = 0, zmax = 0;
2312 GetRange(xmin, ymin, zmin, xmax, ymax, zmax);
2313 for (int i = 0; i < ndim; ++i) {
2314 if (i == 0) {
2315 rmin[0] = xmin;
2316 rmax[0] = xmax;
2317 } else if (i == 1) {
2318 rmin[1] = ymin;
2319 rmax[1] = ymax;
2320 } else if (i == 2) {
2321 rmin[2] = zmin;
2322 rmax[2] = zmax;
2323 } else {
2324 rmin[i] = 0;
2325 rmax[i] = 0;
2326 }
2327 }
2328}
2329
2330
2331////////////////////////////////////////////////////////////////////////////////
2332/// Return range of a 1-D function.
2333
2335{
2336 xmin = fXmin;
2337 xmax = fXmax;
2338}
2339
2340
2341////////////////////////////////////////////////////////////////////////////////
2342/// Return range of a 2-D function.
2343
2345{
2346 xmin = fXmin;
2347 xmax = fXmax;
2348 ymin = 0;
2349 ymax = 0;
2350}
2351
2352
2353////////////////////////////////////////////////////////////////////////////////
2354/// Return range of function.
2355
2357{
2358 xmin = fXmin;
2359 xmax = fXmax;
2360 ymin = 0;
2361 ymax = 0;
2362 zmin = 0;
2363 zmax = 0;
2364}
2365
2366
2367////////////////////////////////////////////////////////////////////////////////
2368/// Get value corresponding to X in array of fSave values
2369
2371{
2372 if (fSave.empty()) return 0;
2373 //if (fSave == 0) return 0;
2374 int nsave = fSave.size();
2375 Double_t x = Double_t(xx[0]);
2376 Double_t y, dx, xmin, xmax, xlow, xup, ylow, yup;
2378 //if parent is a histogram the function had been saved at the center of the bins
2379 //we make a linear interpolation between the saved values
2380 xmin = fSave[nsave - 3];
2381 xmax = fSave[nsave - 2];
2382 if (fSave[nsave - 1] == xmax) {
2383 TH1 *h = (TH1 *)fParent;
2384 TAxis *xaxis = h->GetXaxis();
2385 Int_t bin1 = xaxis->FindBin(xmin);
2386 Int_t binup = xaxis->FindBin(xmax);
2387 Int_t bin = xaxis->FindBin(x);
2388 if (bin < binup) {
2389 xlow = xaxis->GetBinCenter(bin);
2390 xup = xaxis->GetBinCenter(bin + 1);
2391 ylow = fSave[bin - bin1];
2392 yup = fSave[bin - bin1 + 1];
2393 } else {
2394 xlow = xaxis->GetBinCenter(bin - 1);
2395 xup = xaxis->GetBinCenter(bin);
2396 ylow = fSave[bin - bin1 - 1];
2397 yup = fSave[bin - bin1];
2398 }
2399 dx = xup - xlow;
2400 y = ((xup * ylow - xlow * yup) + x * (yup - ylow)) / dx;
2401 return y;
2402 }
2403 }
2404 Int_t np = nsave - 3;
2405 xmin = fSave[np + 1];
2406 xmax = fSave[np + 2];
2407 dx = (xmax - xmin) / np;
2408 if (x < xmin || x > xmax) return 0;
2409 // return a Nan in case of x=nan, otherwise will crash later
2410 if (TMath::IsNaN(x)) return x;
2411 if (dx <= 0) return 0;
2412
2413 Int_t bin = TMath::Min(np - 1, Int_t((x - xmin) / dx));
2414 xlow = xmin + bin * dx;
2415 xup = xlow + dx;
2416 ylow = fSave[bin];
2417 yup = fSave[bin + 1];
2418 y = ((xup * ylow - xlow * yup) + x * (yup - ylow)) / dx;
2419 return y;
2420}
2421
2422
2423////////////////////////////////////////////////////////////////////////////////
2424/// Get x axis of the function.
2425
2427{
2428 TH1 *h = GetHistogram();
2429 if (!h) return nullptr;
2430 return h->GetXaxis();
2431}
2432
2433
2434////////////////////////////////////////////////////////////////////////////////
2435/// Get y axis of the function.
2436
2438{
2439 TH1 *h = GetHistogram();
2440 if (!h) return nullptr;
2441 return h->GetYaxis();
2442}
2443
2444
2445////////////////////////////////////////////////////////////////////////////////
2446/// Get z axis of the function. (In case this object is a TF2 or TF3)
2447
2449{
2450 TH1 *h = GetHistogram();
2451 if (!h) return nullptr;
2452 return h->GetZaxis();
2453}
2454
2455
2456
2457////////////////////////////////////////////////////////////////////////////////
2458/// Compute the gradient (derivative) wrt a parameter ipar
2459///
2460/// \param ipar index of parameter for which the derivative is computed
2461/// \param x point, where the derivative is computed
2462/// \param eps - if the errors of parameters have been computed, the step used in
2463/// numerical differentiation is eps*parameter_error.
2464///
2465/// if the errors have not been computed, step=eps is used
2466/// default value of eps = 0.01
2467/// Method is the same as in Derivative() function
2468///
2469/// If a parameter is fixed, the gradient on this parameter = 0
2470
2472{
2473 return GradientParTempl<Double_t>(ipar, x, eps);
2474}
2475
2476////////////////////////////////////////////////////////////////////////////////
2477/// Compute the gradient wrt parameters
2478/// If the TF1 object is based on a formula expression (TFormula)
2479/// and TFormula::GenerateGradientPar() has been successfully called
2480/// automatic differentiation using CLAD is used instead of the default
2481/// numerical differentiation
2482///
2483/// \param x point, were the gradient is computed
2484/// \param grad used to return the computed gradient, assumed to be of at least fNpar size
2485/// \param eps if the errors of parameters have been computed, the step used in
2486/// numerical differentiation is eps*parameter_error.
2487///
2488/// if the errors have not been computed, step=eps is used
2489/// default value of eps = 0.01
2490/// Method is the same as in Derivative() function
2491///
2492/// If a parameter is fixed, the gradient on this parameter = 0
2493
2494void TF1::GradientPar(const Double_t *x, Double_t *grad, Double_t eps) const
2495{
2496 if (fFormula && fFormula->HasGeneratedGradient()) {
2497 // need to zero the gradient buffer
2498 std::fill(grad, grad + fNpar, 0.);
2499 fFormula->GradientPar(x,grad);
2500 }
2501 else
2502 GradientParTempl<Double_t>(x, grad, eps);
2503}
2504
2505////////////////////////////////////////////////////////////////////////////////
2506/// Initialize parameters addresses.
2507
2508void TF1::InitArgs(const Double_t *x, const Double_t *params)
2509{
2510 if (fMethodCall) {
2511 Longptr_t args[2];
2512 args[0] = (Longptr_t)x;
2513 if (params) args[1] = (Longptr_t)params;
2514 else args[1] = (Longptr_t)GetParameters();
2515 fMethodCall->SetParamPtrs(args);
2516 }
2517}
2518
2519
2520////////////////////////////////////////////////////////////////////////////////
2521/// Create the basic function objects
2522
2524{
2525 TF1 *f1;
2527 if (!gROOT->GetListOfFunctions()->FindObject("gaus")) {
2528 f1 = new TF1("gaus", "gaus", -1, 1);
2529 f1->SetParameters(1, 0, 1);
2530 f1 = new TF1("gausn", "gausn", -1, 1);
2531 f1->SetParameters(1, 0, 1);
2532 f1 = new TF1("landau", "landau", -1, 1);
2533 f1->SetParameters(1, 0, 1);
2534 f1 = new TF1("landaun", "landaun", -1, 1);
2535 f1->SetParameters(1, 0, 1);
2536 f1 = new TF1("expo", "expo", -1, 1);
2537 f1->SetParameters(1, 1);
2538 for (Int_t i = 0; i < 10; i++) {
2539 auto f1name = TString::Format("pol%d", i);
2540 f1 = new TF1(f1name.Data(), f1name.Data(), -1, 1);
2541 f1->SetParameters(1, 1, 1, 1, 1, 1, 1, 1, 1, 1);
2542 // create also chebyshev polynomial
2543 // (note polynomial object will not be deleted)
2544 // note that these functions cannot be stored
2546 Double_t min = -1;
2547 Double_t max = 1;
2548 f1 = new TF1(TString::Format("chebyshev%d", i), pol, min, max, i + 1, 1);
2549 f1->SetParameters(1, 1, 1, 1, 1, 1, 1, 1, 1, 1);
2550 }
2551
2552 }
2553}
2554////////////////////////////////////////////////////////////////////////////////
2555/// IntegralOneDim or analytical integral
2556
2558{
2559 Double_t error = 0;
2560 if (GetNumber() > 0) {
2561 Double_t result = 0.;
2562 if (gDebug) {
2563 Info("computing analytical integral for function %s with number %d", GetName(), GetNumber());
2564 }
2565 result = AnalyticalIntegral(this, a, b);
2566 // if it is a formula that havent been implemented in analytical integral a NaN is return
2567 if (!TMath::IsNaN(result)) return result;
2568 if (gDebug)
2569 Warning("analytical integral not available for %s - with number %d compute numerical integral", GetName(), GetNumber());
2570 }
2571 return IntegralOneDim(a, b, epsrel, epsrel, error);
2572}
2573
2574////////////////////////////////////////////////////////////////////////////////
2575/// Return Integral of function between a and b using the given parameter values and
2576/// relative and absolute tolerance.
2577///
2578/// The default integrator defined in ROOT::Math::IntegratorOneDimOptions::DefaultIntegrator() is used
2579/// If ROOT contains the MathMore library the default integrator is set to be
2580/// the adaptive ROOT::Math::GSLIntegrator (based on QUADPACK) or otherwise the
2581/// ROOT::Math::GaussIntegrator is used
2582/// See the reference documentation of these classes for more information about the
2583/// integration algorithms
2584/// To change integration algorithm just do :
2585/// ROOT::Math::IntegratorOneDimOptions::SetDefaultIntegrator(IntegratorName);
2586/// Valid integrator names are:
2587/// - Gauss : for ROOT::Math::GaussIntegrator
2588/// - GaussLegendre : for ROOT::Math::GaussLegendreIntegrator
2589/// - Adaptive : for ROOT::Math::GSLIntegrator adaptive method (QAG)
2590/// - AdaptiveSingular : for ROOT::Math::GSLIntegrator adaptive singular method (QAGS)
2591/// - NonAdaptive : for ROOT::Math::GSLIntegrator non adaptive (QNG)
2592///
2593/// In order to use the GSL integrators one needs to have the MathMore library installed
2594///
2595/// Note 1:
2596///
2597/// Values of the function f(x) at the interval end-points A and B are not
2598/// required. The subprogram may therefore be used when these values are
2599/// undefined.
2600///
2601/// Note 2:
2602///
2603/// Instead of TF1::Integral, you may want to use the combination of
2604/// TF1::CalcGaussLegendreSamplingPoints and TF1::IntegralFast.
2605/// See an example with the following script:
2606///
2607/// ~~~ {.cpp}
2608/// void gint() {
2609/// TF1 *g = new TF1("g","gaus",-5,5);
2610/// g->SetParameters(1,0,1);
2611/// //default gaus integration method uses 6 points
2612/// //not suitable to integrate on a large domain
2613/// double r1 = g->Integral(0,5);
2614/// double r2 = g->Integral(0,1000);
2615///
2616/// //try with user directives computing more points
2617/// Int_t np = 1000;
2618/// double *x=new double[np];
2619/// double *w=new double[np];
2620/// g->CalcGaussLegendreSamplingPoints(np,x,w,1e-15);
2621/// double r3 = g->IntegralFast(np,x,w,0,5);
2622/// double r4 = g->IntegralFast(np,x,w,0,1000);
2623/// double r5 = g->IntegralFast(np,x,w,0,10000);
2624/// double r6 = g->IntegralFast(np,x,w,0,100000);
2625/// printf("g->Integral(0,5) = %g\n",r1);
2626/// printf("g->Integral(0,1000) = %g\n",r2);
2627/// printf("g->IntegralFast(n,x,w,0,5) = %g\n",r3);
2628/// printf("g->IntegralFast(n,x,w,0,1000) = %g\n",r4);
2629/// printf("g->IntegralFast(n,x,w,0,10000) = %g\n",r5);
2630/// printf("g->IntegralFast(n,x,w,0,100000)= %g\n",r6);
2631/// delete [] x;
2632/// delete [] w;
2633/// }
2634/// ~~~
2635///
2636/// This example produces the following results:
2637///
2638/// ~~~ {.cpp}
2639/// g->Integral(0,5) = 1.25331
2640/// g->Integral(0,1000) = 1.25319
2641/// g->IntegralFast(n,x,w,0,5) = 1.25331
2642/// g->IntegralFast(n,x,w,0,1000) = 1.25331
2643/// g->IntegralFast(n,x,w,0,10000) = 1.25331
2644/// g->IntegralFast(n,x,w,0,100000)= 1.253
2645/// ~~~
2646
2648{
2649 //Double_t *parameters = GetParameters();
2650 TF1_EvalWrapper wf1(this, nullptr, fgAbsValue);
2651 Double_t result = 0;
2652 Int_t status = 0;
2657 iod.SetFunction(wf1);
2658 if (a != - TMath::Infinity() && b != TMath::Infinity())
2659 result = iod.Integral(a, b);
2660 else if (a == - TMath::Infinity() && b != TMath::Infinity())
2661 result = iod.IntegralLow(b);
2662 else if (a != - TMath::Infinity() && b == TMath::Infinity())
2663 result = iod.IntegralUp(a);
2664 else if (a == - TMath::Infinity() && b == TMath::Infinity())
2665 result = iod.Integral();
2666 error = iod.Error();
2667 status = iod.Status();
2668 } else {
2670 if (a != - TMath::Infinity() && b != TMath::Infinity())
2671 result = iod.Integral(a, b);
2672 else if (a == - TMath::Infinity() && b != TMath::Infinity())
2673 result = iod.IntegralLow(b);
2674 else if (a != - TMath::Infinity() && b == TMath::Infinity())
2675 result = iod.IntegralUp(a);
2676 else if (a == - TMath::Infinity() && b == TMath::Infinity())
2677 result = iod.Integral();
2678 error = iod.Error();
2679 status = iod.Status();
2680 }
2681 if (status != 0) {
2683 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);
2684 TString msg("\t\tFunction Parameters = {");
2685 for (int ipar = 0; ipar < GetNpar(); ++ipar) {
2686 msg += TString::Format(" %s = %f ", GetParName(ipar), GetParameter(ipar));
2687 if (ipar < GetNpar() - 1) msg += TString(",");
2688 else msg += TString("}");
2689 }
2690 Info("IntegralOneDim", "%s", msg.Data());
2691 }
2692 return result;
2693}
2694
2695////////////////////////////////////////////////////////////////////////////////
2696/// Return Error on Integral of a parametric function between a and b
2697/// due to the parameter uncertainties and their covariance matrix from the fit.
2698/// In addition to the integral limits, this method takes as input a pointer to the fitted parameter values
2699/// and a pointer the covariance matrix from the fit. These pointers should be retrieved from the
2700/// previously performed fit using the TFitResult class.
2701/// Note that to get the TFitResult, te fit should be done using the fit option `S`.
2702/// Example:
2703/// ~~~~{.cpp}
2704/// TFitResultPtr r = histo->Fit(func, "S");
2705/// func->IntegralError(x1,x2,r->GetParams(), r->GetCovarianceMatrix()->GetMatrixArray() );
2706/// ~~~~
2707///
2708/// IMPORTANT NOTE1:
2709///
2710/// A null pointer to the parameter values vector and to the covariance matrix can be passed.
2711/// In this case, when the parameter values pointer is null, the parameter values stored in this
2712/// TF1 function object are used in the integral error computation.
2713/// When the poassed pointer to the covariance matrix is null, a covariance matrix from the last fit is retrieved
2714/// from a global fitter instance when it exists. Note that the global fitter instance
2715/// esists only when ROOT is not running with multi-threading enabled (ROOT::IsImplicitMTEnabled() == True).
2716/// When the ovariance matrix from the last fit cannot be retrieved, an error message is printed and a zero value is
2717/// returned.
2718///
2719///
2720/// IMPORTANT NOTE2:
2721///
2722/// When no covariance matrix is passed and in the meantime a fit is done
2723/// using another function, the routine will signal an error and it will return zero only
2724/// when the number of fit parameter is different than the values stored in TF1 (TF1::GetNpar() ).
2725/// In the case that npar is the same, an incorrect result is returned.
2726///
2727/// IMPORTANT NOTE3:
2728///
2729/// The user must pass a pointer to the elements of the full covariance matrix
2730/// dimensioned with the right size (npar*npar), where npar is the total number of parameters (TF1::GetNpar()),
2731/// including also the fixed parameters. The covariance matrix must be retrieved from the TFitResult class as
2732/// shown above and not from TVirtualFitter::GetCovarianceMatrix() function.
2733
2735{
2736 Double_t x1[1];
2737 Double_t x2[1];
2738 x1[0] = a, x2[0] = b;
2739 return ROOT::TF1Helper::IntegralError(this, 1, x1, x2, params, covmat, epsilon);
2740}
2741
2742////////////////////////////////////////////////////////////////////////////////
2743/// Return Error on Integral of a parametric function with dimension larger than one
2744/// between a[] and b[] due to the parameters uncertainties.
2745/// For a TF1 with dimension larger than 1 (for example a TF2 or TF3)
2746/// TF1::IntegralMultiple is used for the integral calculation
2747///
2748/// In addition to the integral limits, this method takes as input a pointer to the fitted parameter values
2749/// and a pointer the covariance matrix from the fit. These pointers should be retrieved from the
2750/// previously performed fit using the TFitResult class.
2751/// Note that to get the TFitResult, te fit should be done using the fit option `S`.
2752/// Example:
2753/// ~~~~{.cpp}
2754/// TFitResultPtr r = histo2d->Fit(func2, "S");
2755/// func2->IntegralError(a,b,r->GetParams(), r->GetCovarianceMatrix()->GetMatrixArray() );
2756/// ~~~~
2757///
2758/// IMPORTANT NOTE1:
2759///
2760/// A null pointer to the parameter values vector and to the covariance matrix can be passed.
2761/// In this case, when the parameter values pointer is null, the parameter values stored in this
2762/// TF1 function object are used in the integral error computation.
2763/// When the poassed pointer to the covariance matrix is null, a covariance matrix from the last fit is retrieved
2764/// from a global fitter instance when it exists. Note that the global fitter instance
2765/// esists only when ROOT is not running with multi-threading enabled (ROOT::IsImplicitMTEnabled() == True).
2766/// When the ovariance matrix from the last fit cannot be retrieved, an error message is printed and a zero value is
2767/// returned.
2768///
2769///
2770/// IMPORTANT NOTE2:
2771///
2772/// When no covariance matrix is passed and in the meantime a fit is done
2773/// using another function, the routine will signal an error and it will return zero only
2774/// when the number of fit parameter is different than the values stored in TF1 (TF1::GetNpar() ).
2775/// In the case that npar is the same, an incorrect result is returned.
2776///
2777/// IMPORTANT NOTE3:
2778///
2779/// The user must pass a pointer to the elements of the full covariance matrix
2780/// dimensioned with the right size (npar*npar), where npar is the total number of parameters (TF1::GetNpar()),
2781/// including also the fixed parameters. The covariance matrix must be retrieved from the TFitResult class as
2782/// shown above and not from TVirtualFitter::GetCovarianceMatrix() function.
2783
2784Double_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)
2785{
2786 return ROOT::TF1Helper::IntegralError(this, n, a, b, params, covmat, epsilon);
2787}
2788
2789#ifdef INTHEFUTURE
2790////////////////////////////////////////////////////////////////////////////////
2791/// Gauss-Legendre integral, see CalcGaussLegendreSamplingPoints
2792
2794{
2795 if (!g) return 0;
2796 return IntegralFast(g->GetN(), g->GetX(), g->GetY(), a, b, params);
2797}
2798#endif
2799
2800
2801////////////////////////////////////////////////////////////////////////////////
2802/// Gauss-Legendre integral, see CalcGaussLegendreSamplingPoints
2803
2804Double_t TF1::IntegralFast(Int_t num, Double_t * /* x */, Double_t * /* w */, Double_t a, Double_t b, Double_t *params, Double_t epsilon)
2805{
2806 // Now x and w are not used!
2807
2809 if (params)
2810 wf1.SetParameters(params);
2812 gli.SetFunction(wf1);
2813 return gli.Integral(a, b);
2814
2815}
2816
2817
2818////////////////////////////////////////////////////////////////////////////////
2819/// See more general prototype below.
2820/// This interface kept for back compatibility
2821/// It is recommended to use the other interface where one can specify also epsabs and the maximum number of
2822/// points
2823
2825{
2829 if (ifail > 0) {
2830 Warning("IntegralMultiple", "failed code=%d, ", ifail);
2831 }
2832 return result;
2833}
2834
2835
2836////////////////////////////////////////////////////////////////////////////////
2837/// This function computes, to an attempted specified accuracy, the value of
2838/// the integral
2839///
2840/// \param[in] n Number of dimensions [2,15]
2841/// \param[in] a,b One-dimensional arrays of length >= N . On entry A[i], and B[i],
2842/// contain the lower and upper limits of integration, respectively.
2843/// \param[in] maxpts Maximum number of function evaluations to be allowed.
2844/// maxpts >= 2^n +2*n*(n+1) +1
2845/// if maxpts<minpts, maxpts is set to 10*minpts
2846/// \param[in] epsrel Specified relative accuracy.
2847/// \param[in] epsabs Specified absolute accuracy.
2848/// The integration algorithm will attempt to reach either the relative or the absolute accuracy.
2849/// In case the maximum function called is reached the algorithm will stop earlier without having reached
2850/// the desired accuracy
2851///
2852/// \param[out] relerr Contains, on exit, an estimation of the relative accuracy of the result.
2853/// \param[out] nfnevl number of function evaluations performed.
2854/// \param[out] ifail
2855/// \parblock
2856/// 0 Normal exit. At least minpts and at most maxpts calls to the function were performed.
2857///
2858/// 1 maxpts is too small for the specified accuracy eps. The result and relerr contain the values obtainable for the
2859/// specified value of maxpts.
2860///
2861/// 3 n<2 or n>15
2862/// \endparblock
2863///
2864/// Method:
2865///
2866/// The default method used is the Genz-Mallik adaptive multidimensional algorithm
2867/// using the class ROOT::Math::AdaptiveIntegratorMultiDim (see the reference documentation of the class)
2868///
2869/// Other methods can be used by setting ROOT::Math::IntegratorMultiDimOptions::SetDefaultIntegrator()
2870/// to different integrators.
2871/// Other possible integrators are MC integrators based on the ROOT::Math::GSLMCIntegrator class
2872/// Possible methods are : Vegas, Miser or Plain
2873/// IN case of MC integration the accuracy is determined by the number of function calls, one should be
2874/// careful not to use a too large value of maxpts
2875///
2876
2878{
2880
2881 double result = 0;
2886 //aimd.SetMinPts(minpts); // use default minpts ( n^2 + 2 * n * (n+1) +1 )
2887 result = aimd.Integral(a, b);
2888 relerr = aimd.RelError();
2889 nfnevl = aimd.NEval();
2890 ifail = aimd.Status();
2891 } else {
2892 // use default abs tolerance = relative tolerance
2894 result = imd.Integral(a, b);
2895 relerr = (result != 0) ? imd.Error() / std::abs(result) : imd.Error();
2896 nfnevl = 0;
2897 ifail = imd.Status();
2898 }
2899
2900
2901 return result;
2902}
2903
2904
2905////////////////////////////////////////////////////////////////////////////////
2906/// Return kTRUE if the function is valid
2907
2909{
2910 if (fFormula) return fFormula->IsValid();
2911 if (fMethodCall) return fMethodCall->IsValid();
2912 // function built on compiled functors are always valid by definition
2913 // (checked at compiled time)
2914 // invalid is a TF1 where the functor is null pointer and has not been saved
2915 if (!fFunctor && fSave.empty()) return kFALSE;
2916 return kTRUE;
2917}
2918
2919
2920//______________________________________________________________________________
2921
2922
2924{
2925 if (fType == EFType::kFormula) {
2926 printf("Formula based function: %s \n", GetName());
2928 fFormula->Print(option);
2929 } else if (fType > 0) {
2931 printf("Interpreted based function: %s(double *x, double *p). Ndim = %d, Npar = %d \n", GetName(), GetNdim(),
2932 GetNpar());
2933 else if (fType == EFType::kCompositionFcn) {
2934 printf("Composition based function: %s. Ndim = %d, Npar = %d \n", GetName(), GetNdim(), GetNpar());
2935 if (!fComposition)
2936 printf("fComposition not found!\n"); // this would be bad
2937 } else {
2938 if (fFunctor)
2939 printf("Compiled based function: %s based on a functor object. Ndim = %d, Npar = %d\n", GetName(),
2940 GetNdim(), GetNpar());
2941 else {
2942 printf("Function based on a list of points from a compiled based function: %s. Ndim = %d, Npar = %d, Npx "
2943 "= %zu\n",
2944 GetName(), GetNdim(), GetNpar(), fSave.size());
2945 if (fSave.empty())
2946 Warning("Print", "Function %s is based on a list of points but list is empty", GetName());
2947 }
2948 }
2949 TString opt(option);
2950 opt.ToUpper();
2951 if (opt.Contains("V")) {
2952 // print list of parameters
2953 if (fNpar > 0) {
2954 printf("List of Parameters: \n");
2955 for (int i = 0; i < fNpar; ++i)
2956 printf(" %20s = %10f \n", GetParName(i), GetParameter(i));
2957 }
2958 if (!fSave.empty()) {
2959 // print list of saved points
2960 printf("List of Saved points (N=%d): \n", int(fSave.size()));
2961 for (auto &x : fSave)
2962 printf("( %10f ) ", x);
2963 printf("\n");
2964 }
2965 }
2966 }
2967 if (fHistogram) {
2968 printf("Contained histogram\n");
2970 }
2971}
2972
2973////////////////////////////////////////////////////////////////////////////////
2974/// Paint this function with its current attributes.
2975/// The function is going to be converted in an histogram and the corresponding
2976/// histogram is painted.
2977/// The painted histogram can be retrieved calling afterwards the method TF1::GetHistogram()
2978
2980{
2981 fgCurrent = this;
2982
2983 TString opt0 = option, opt = option, optSAME;
2984 opt.ToLower();
2985
2986 if (opt.Contains("sames"))
2987 optSAME = "sames";
2988 else if (opt.Contains("same"))
2989 optSAME = "same";
2990 if (optSAME.Length())
2991 opt.ReplaceAll(optSAME, "");
2992 opt.ReplaceAll(' ', "");
2993
2995 if (gPad) {
2996 pmin = gPad->PadtoX(gPad->GetUxmin());
2997 pmax = gPad->PadtoX(gPad->GetUxmax());
2998 }
2999 if (optSAME.Length()) {
3000 // Completely outside
3001 if (xmax < pmin) return;
3002 if (xmin > pmax) return;
3003 }
3004
3005 // create an histogram using the function content (re-use it if already existing)
3007
3008 auto is_pfc = opt0.Index("PFC"); // Automatic Fill Color
3009 auto is_plc = opt0.Index("PLC"); // Automatic Line Color
3010 auto is_pmc = opt0.Index("PMC"); // Automatic Marker Color
3011 if (is_pfc != kNPOS || is_plc != kNPOS || is_pmc != kNPOS) {
3012 Int_t i = gPad->NextPaletteColor();
3013 if (is_pfc != kNPOS) { opt0.Replace(is_pfc, 3, " "); fHistogram->SetFillColor(i); }
3014 if (is_plc != kNPOS) { opt0.Replace(is_plc, 3, " "); fHistogram->SetLineColor(i); }
3015 if (is_pmc != kNPOS) { opt0.Replace(is_pmc, 3, " "); fHistogram->SetMarkerColor(i); }
3016 }
3017
3018 // set the optimal minimum and maximum
3021 if (minimum <= 0 && gPad && gPad->GetLogy()) minimum = -1111; // This can happen when switching from lin to log scale.
3022 if (gPad && gPad->GetUymin() < fHistogram->GetMinimum() &&
3023 !fHistogram->TestBit(TH1::kIsZoomed)) minimum = -1111; // This can happen after unzooming a fit.
3024 if (minimum == -1111) { // This can happen after unzooming.
3027 } else {
3028 minimum = fMinimum;
3029 // Optimize the computation of the scale in Y in case the min/max of the
3030 // function oscillate around a constant value
3031 if (minimum == -1111) {
3032 Double_t hmin;
3033 if (optSAME.Length() && gPad) hmin = gPad->GetUymin();
3034 else hmin = fHistogram->GetMinimum();
3035 if (hmin > 0) {
3036 Double_t hmax;
3038 if (optSAME.Length() && gPad) hmax = gPad->GetUymax();
3039 else hmax = fHistogram->GetMaximum();
3040 hmin -= 0.05 * (hmax - hmin);
3041 if (hmin < 0) hmin = 0;
3043 minimum = hmin;
3044 }
3045 }
3046 }
3048 }
3049 if (maximum == -1111) {
3052 } else {
3053 maximum = fMaximum;
3054 }
3056 }
3057
3058 // Draw the histogram.
3059 if (!gPad) return;
3060 if (opt.Length() == 0) {
3061 optSAME.Prepend("lf");
3062 fHistogram->Paint(optSAME.Data());
3063 } else {
3064 fHistogram->Paint(opt0.Data());
3065 }
3066}
3067
3068////////////////////////////////////////////////////////////////////////////////
3069/// Create histogram with bin content equal to function value
3070/// computed at the bin center
3071/// This histogram will be used to paint the function
3072/// A re-creation is forced and a new histogram is done if recreate=true
3073
3075{
3076 Int_t i;
3077 Double_t xv[1];
3078
3079 TH1 *histogram = nullptr;
3080
3081
3082 // Create a temporary histogram and fill each channel with the function value
3083 // Preserve axis titles
3084 TString xtitle = "";
3085 TString ytitle = "";
3086 char *semicol = (char *)strstr(GetTitle(), ";");
3087 if (semicol) {
3089 char *ctemp = new char[nxt];
3090 strlcpy(ctemp, semicol + 1, nxt);
3091 semicol = (char *)strstr(ctemp, ";");
3092 if (semicol) {
3093 *semicol = 0;
3094 ytitle = semicol + 1;
3095 }
3096 xtitle = ctemp;
3097 delete [] ctemp;
3098 }
3099 if (fHistogram) {
3100 // delete previous histograms if were done if done in different mode
3104 if (!gPad->GetLogx() && test_logx) {
3105 delete fHistogram;
3106 fHistogram = nullptr;
3107 recreate = kTRUE;
3108 }
3109 if (gPad->GetLogx() && !test_logx) {
3110 delete fHistogram;
3111 fHistogram = nullptr;
3112 recreate = kTRUE;
3113 }
3114 }
3115
3116 if (fHistogram && !recreate) {
3119 } else {
3120 // If logx, we must bin in logx and not in x
3121 // otherwise in case of several decades, one gets wrong results.
3122 if (xmin > 0 && gPad && gPad->GetLogx()) {
3123 Double_t *xbins = new Double_t[fNpx + 1];
3127 for (i = 0; i <= fNpx; i++) {
3128 xbins[i] = gPad->PadtoX(xlogmin + i * dlogx);
3129 }
3130 histogram = new TH1D("Func", GetTitle(), fNpx, xbins);
3131 histogram->SetBit(TH1::kLogX);
3132 delete [] xbins;
3133 } else {
3134 histogram = new TH1D("Func", GetTitle(), fNpx, xmin, xmax);
3135 }
3136 if (fMinimum != -1111) histogram->SetMinimum(fMinimum);
3137 if (fMaximum != -1111) histogram->SetMaximum(fMaximum);
3138 histogram->SetDirectory(nullptr);
3139 }
3141
3142 // Restore axis titles.
3143 histogram->GetXaxis()->SetTitle(xtitle.Data());
3144 histogram->GetYaxis()->SetTitle(ytitle.Data());
3145 Double_t *parameters = GetParameters();
3146
3147 InitArgs(xv, parameters);
3148 for (i = 1; i <= fNpx; i++) {
3149 xv[0] = histogram->GetBinCenter(i);
3150 histogram->SetBinContent(i, EvalPar(xv, parameters));
3151 }
3152
3153 // Copy Function attributes to histogram attributes.
3154 histogram->SetBit(TH1::kNoStats);
3155 histogram->Sumw2(kFALSE);
3156 histogram->SetLineColor(GetLineColor());
3157 histogram->SetLineStyle(GetLineStyle());
3158 histogram->SetLineWidth(GetLineWidth());
3159 histogram->SetFillColor(GetFillColor());
3160 histogram->SetFillStyle(GetFillStyle());
3161 histogram->SetMarkerColor(GetMarkerColor());
3162 histogram->SetMarkerStyle(GetMarkerStyle());
3163 histogram->SetMarkerSize(GetMarkerSize());
3164
3165 // update saved histogram in case it was deleted or if it is the first time the method is called
3166 // for example when called from TF1::GetHistogram()
3168 return histogram;
3169
3170}
3171
3172
3173////////////////////////////////////////////////////////////////////////////////
3174/// Release parameter number ipar during a fit operation.
3175/// After releasing it, the parameter
3176/// can vary freely in the fit. The parameter limits are reset to 0,0.
3177
3179{
3180 if (ipar < 0 || ipar > GetNpar() - 1) return;
3181 SetParLimits(ipar, 0, 0);
3182}
3183
3184
3185////////////////////////////////////////////////////////////////////////////////
3186/// Save values of function in array fSave
3187
3189{
3190 if (!fSave.empty())
3191 fSave.clear();
3192
3193 Double_t *parameters = GetParameters();
3194 //if (fSave != 0) {delete [] fSave; fSave = 0;}
3196 //if parent is a histogram save the function at the center of the bins
3197 if ((xmin > 0 && xmax > 0) && TMath::Abs(TMath::Log10(xmax / xmin) > TMath::Log10(fNpx))) {
3198 TH1 *h = (TH1 *)fParent;
3199 Int_t bin1 = h->GetXaxis()->FindBin(xmin);
3200 Int_t bin2 = h->GetXaxis()->FindBin(xmax);
3201 int nsave = bin2 - bin1 + 4;
3202 fSave.resize(nsave);
3203 Double_t xv[1];
3204
3205 InitArgs(xv, parameters);
3206 for (Int_t i = bin1; i <= bin2; i++) {
3207 xv[0] = h->GetXaxis()->GetBinCenter(i);
3208 fSave[i - bin1] = EvalPar(xv, parameters);
3209 }
3210 fSave[nsave - 3] = xmin;
3211 fSave[nsave - 2] = xmax;
3212 fSave[nsave - 1] = xmax;
3213 return;
3214 }
3215 }
3216
3217 Int_t npx = fNpx;
3218 if (npx <= 0)
3219 return;
3220
3221 Double_t dx = (xmax - xmin) / fNpx;
3222 if (dx <= 0) {
3223 dx = (fXmax - fXmin) / fNpx;
3224 npx--;
3225 xmin = fXmin + 0.5 * dx;
3226 xmax = fXmax - 0.5 * dx;
3227 }
3228 if (npx <= 0)
3229 return;
3230 fSave.resize(npx + 3);
3231 Double_t xv[1];
3232 InitArgs(xv, parameters);
3233 for (Int_t i = 0; i <= npx; i++) {
3234 xv[0] = xmin + dx * i;
3235 fSave[i] = EvalPar(xv, parameters);
3236 }
3237 fSave[npx + 1] = xmin;
3238 fSave[npx + 2] = xmax;
3239}
3240
3241
3242////////////////////////////////////////////////////////////////////////////////
3243/// Provide variable name for function for saving as primitive
3244/// When TH1 or TGraph stores list of functions, it applies special coding of created variable names
3245
3247{
3248 thread_local Int_t storeNumber = 0;
3249 TString funcName = GetName();
3250 const char *l = strstr(option, "#");
3251 Int_t number = ++storeNumber;
3252 if (l != nullptr)
3253 sscanf(l + 1, "%d", &number);
3254
3255 funcName += number;
3256 return gInterpreter->MapCppName(funcName);
3257}
3258
3259
3260////////////////////////////////////////////////////////////////////////////////
3261/// Save primitive as a C++ statement(s) on output stream out
3262
3263void TF1::SavePrimitive(std::ostream &out, Option_t *option /*= ""*/)
3264{
3265 // Save the function as C code independent from ROOT.
3266 if (option && strstr(option, "cc")) {
3267 out << "double " << GetName() << "(double xv) {\n";
3268 Double_t dx = (fXmax - fXmin) / (fNpx - 1);
3269 out << " double x[" << fNpx << "] = {\n";
3270 out << " ";
3271 Int_t n = 0;
3272 for (Int_t i = 0; i < fNpx; i++) {
3273 out << fXmin + dx * i;
3274 if (i < fNpx - 1)
3275 out << ", ";
3276 if (n++ == 10) {
3277 out << "\n ";
3278 n = 0;
3279 }
3280 }
3281 out << "\n";
3282 out << " };\n";
3283 out << " double y[" << fNpx << "] = {\n";
3284 out << " ";
3285 n = 0;
3286 for (Int_t i = 0; i < fNpx; i++) {
3287 out << Eval(fXmin + dx * i);
3288 if (i < fNpx - 1)
3289 out << ", ";
3290 if (n++ == 10) {
3291 out << "\n ";
3292 n = 0;
3293 }
3294 }
3295 out << "\n";
3296 out << " };\n";
3297 out << " if (xv<x[0]) return y[0];\n";
3298 out << " if (xv>x[" << fNpx - 1 << "]) return y[" << fNpx - 1 << "];\n";
3299 out << " int i, j=0;\n";
3300 out << " for (i=1; i<" << fNpx << "; i++) { if (xv < x[i]) break; j++; }\n";
3301 out << " return y[j] + (y[j + 1] - y[j]) / (x[j + 1] - x[j]) * (xv - x[j]);\n";
3302 out << "}\n";
3303 return;
3304 }
3305
3307
3308 const char *addToGlobList = fParent ? ", TF1::EAddToList::kNo" : ", TF1::EAddToList::kDefault";
3309
3310 out << " \n";
3311 if (!fType) {
3312 out << " TF1 *" << f1Name << " = new TF1(\"" << GetName() << "\", \""
3313 << TString(GetTitle()).ReplaceSpecialCppChars() << "\", " << fXmin << "," << fXmax << addToGlobList << ");\n";
3314 if (fNpx != 100)
3315 out << " " << f1Name << "->SetNpx(" << fNpx << ");\n";
3316 } else {
3317 out << " TF1 *" << f1Name << " = new TF1(\"" << "*" << GetName() << "\", " << fXmin << "," << fXmax
3318 << "," << GetNpar() << ");\n";
3319 out << " // The original function : " << GetTitle() << " had originally been created by:\n";
3320 out << " // TF1 *" << GetName() << " = new TF1(\"" << GetName() << "\", \"" << GetTitle() << "\", "
3321 << fXmin << "," << fXmax << "," << GetNpar() << ", 1" << addToGlobList << ");\n";
3322 out << " " << f1Name << "->SetRange(" << fXmin << "," << fXmax << ");\n";
3324 if (fNpx != 100)
3325 out << " " << f1Name << "->SetNpx(" << fNpx << ");\n";
3326
3328 if (fSave.empty() && (fType != EFType::kCompositionFcn)) {
3329 saved = kTRUE;
3330 Save(fXmin, fXmax, 0, 0, 0, 0);
3331 }
3332 if (!fSave.empty()) {
3333 TString vect = SavePrimitiveVector(out, f1Name, fSave.size(), fSave.data());
3334 out << " for (int n = 0; n < " << fSave.size() << "; n++)\n";
3335 out << " " << f1Name << "->SetSavedPoint(n, " << vect << "[n]);\n";
3336 }
3337
3338 if (saved)
3339 fSave.clear();
3340 }
3341
3342 if (TestBit(kNotDraw))
3343 out << " " << f1Name.Data() << "->SetBit(TF1::kNotDraw);\n";
3344
3345 SaveFillAttributes(out, f1Name, -1, 0);
3346 SaveMarkerAttributes(out, f1Name, -1, -1, -1);
3347 SaveLineAttributes(out, f1Name, -1, -1, -1);
3348
3349 if (GetChisquare() != 0) {
3350 out << " " << f1Name << "->SetChisquare(" << GetChisquare() << ");\n";
3351 out << " " << f1Name << "->SetNDF(" << GetNDF() << ");\n";
3352 }
3353
3355 for (Int_t i = 0; i < GetNpar(); i++) {
3356 out << " " << f1Name << "->SetParameter(" << i << ", " << GetParameter(i) << ");\n";
3357 out << " " << f1Name << "->SetParError(" << i << ", " << GetParError(i) << ");\n";
3359 out << " " << f1Name << "->SetParLimits(" << i << ", " << parmin << ", " << parmax << ");\n";
3360 }
3361
3362 if (fHistogram && !strstr(option, "same")) {
3363 GetXaxis()->SaveAttributes(out, f1Name, "->GetXaxis()");
3364 GetYaxis()->SaveAttributes(out, f1Name, "->GetYaxis()");
3365 }
3366
3368}
3369
3370////////////////////////////////////////////////////////////////////////////////
3371/// Static function setting the current function.
3372/// the current function may be accessed in static C-like functions
3373/// when fitting or painting a function.
3374
3376{
3377 fgCurrent = f1;
3378}
3379
3380////////////////////////////////////////////////////////////////////////////////
3381/// Set the result from the fit
3382/// parameter values, errors, chi2, etc...
3383/// Optionally a pointer to a vector (with size fNpar) of the parameter indices in the FitResult can be passed
3384/// This is useful in the case of a combined fit with different functions, and the FitResult contains the global result
3385/// By default it is assume that indpar = {0,1,2,....,fNpar-1}.
3386
3388{
3389 Int_t npar = GetNpar();
3390 if (result.IsEmpty()) {
3391 Warning("SetFitResult", "Empty Fit result - nothing is set in TF1");
3392 return;
3393 }
3394 if (indpar == nullptr && npar != (int) result.NPar()) {
3395 Error("SetFitResult", "Invalid Fit result passed - number of parameter is %d , different than TF1::GetNpar() = %d", npar, result.NPar());
3396 return;
3397 }
3398 if (result.Chi2() > 0)
3399 SetChisquare(result.Chi2());
3400 else
3401 SetChisquare(result.MinFcnValue());
3402
3403 SetNDF(result.Ndf());
3404 SetNumberFitPoints(result.Ndf() + result.NFreeParameters());
3405
3406
3407 for (Int_t i = 0; i < npar; ++i) {
3408 Int_t ipar = (indpar != nullptr) ? indpar[i] : i;
3409 if (ipar < 0) continue;
3410 GetParameters()[i] = result.Parameter(ipar);
3411 // in case errors are not present do not set them
3412 if (ipar < (int) result.Errors().size())
3413 fParErrors[i] = result.Error(ipar);
3414 }
3415 //invalidate cached integral since parameters have changed
3416 Update();
3417
3418}
3419
3420
3421////////////////////////////////////////////////////////////////////////////////
3422/// Set the maximum value along Y for this function
3423/// In case the function is already drawn, set also the maximum in the
3424/// helper histogram
3425
3427{
3428 fMaximum = maximum;
3430 if (gPad) gPad->Modified();
3431}
3432
3433
3434////////////////////////////////////////////////////////////////////////////////
3435/// Set the minimum value along Y for this function
3436/// In case the function is already drawn, set also the minimum in the
3437/// helper histogram
3438
3440{
3441 fMinimum = minimum;
3443 if (gPad) gPad->Modified();
3444}
3445
3446
3447////////////////////////////////////////////////////////////////////////////////
3448/// Set the number of degrees of freedom
3449/// ndf should be the number of points used in a fit - the number of free parameters
3450
3452{
3453 fNDF = ndf;
3454}
3455
3456
3457////////////////////////////////////////////////////////////////////////////////
3458/// Set the number of points used to draw the function
3459///
3460/// The default number of points along x is 100 for 1-d functions and 30 for 2-d/3-d functions
3461/// You can increase this value to get a better resolution when drawing
3462/// pictures with sharp peaks or to get a better result when using TF1::GetRandom
3463/// the minimum number of points is 4, the maximum is 10000000 for 1-d and 10000 for 2-d/3-d functions
3464
3466{
3467 const Int_t minPx = 4;
3468 Int_t maxPx = 10000000;
3469 if (GetNdim() > 1) maxPx = 10000;
3470 if (npx >= minPx && npx <= maxPx) {
3471 fNpx = npx;
3472 } else {
3473 if (npx < minPx) fNpx = minPx;
3474 if (npx > maxPx) fNpx = maxPx;
3475 Warning("SetNpx", "Number of points must be >=%d && <= %d, fNpx set to %d", minPx, maxPx, fNpx);
3476 }
3477 Update();
3478}
3479////////////////////////////////////////////////////////////////////////////////
3480/// Set name of parameter number ipar
3481
3482void TF1::SetParName(Int_t ipar, const char *name)
3483{
3484 if (fFormula) {
3485 if (ipar < 0 || ipar >= GetNpar()) return;
3486 fFormula->SetParName(ipar, name);
3487 } else
3488 fParams->SetParName(ipar, name);
3489}
3490
3491////////////////////////////////////////////////////////////////////////////////
3492/// Set up to 10 parameter names.
3493/// Empty strings will be skipped, meaning that the corresponding name will not be changed.
3494
3495void TF1::SetParNames(const char *name0, const char *name1, const char *name2, const char *name3, const char *name4,
3496 const char *name5, const char *name6, const char *name7, const char *name8, const char *name9, const char *name10)
3497{
3498 // Note: this is not made a variadic template method because it would
3499 // presumably break the context menu in the TBrowser. Also, probably this
3500 // method should not be virtual, because if the user wants to change
3501 // parameter name setting behavior, the SetParName() method can be
3502 // overridden.
3503 if (fFormula)
3505 else
3506 fParams->SetParNames(name0, name1, name2, name3, name4, name5, name6, name7, name8, name9, name10);
3507}
3508////////////////////////////////////////////////////////////////////////////////
3509/// Set error for parameter number ipar
3510
3512{
3513 if (ipar < 0 || ipar > GetNpar() - 1) return;
3514 fParErrors[ipar] = error;
3515}
3516
3517
3518////////////////////////////////////////////////////////////////////////////////
3519/// Set errors for all active parameters
3520/// when calling this function, the array errors must have at least fNpar values
3521
3523{
3524 if (!errors) return;
3525 for (Int_t i = 0; i < GetNpar(); i++) fParErrors[i] = errors[i];
3526}
3527
3528
3529////////////////////////////////////////////////////////////////////////////////
3530/// Set lower and upper limits for parameter ipar.
3531/// The specified limits will be used in a fit operation.
3532/// Note that when this function is a pre-defined function (e.g. gaus)
3533/// one needs to use the fit option "B" to have the limits used in the fit.
3534/// See TH1::Fit(TF1*, Option_t *, Option_t *, Double_t, Double_t) for the fitting documentation
3535/// and the [fitting options](\ref HFitOpt)
3536///
3537/// To fix a parameter, use TF1::FixParameter
3538
3540{
3541 Int_t npar = GetNpar();
3542 if (ipar < 0 || ipar > npar - 1) return;
3543 if (int(fParMin.size()) != npar) {
3544 fParMin.resize(npar);
3545 }
3546 if (int(fParMax.size()) != npar) {
3547 fParMax.resize(npar);
3548 }
3549 fParMin[ipar] = parmin;
3550 fParMax[ipar] = parmax;
3551}
3552
3553
3554////////////////////////////////////////////////////////////////////////////////
3555/// Initialize the upper and lower bounds to draw the function.
3556///
3557/// The function range is also used in an histogram fit operation
3558/// when the option "R" is specified.
3559
3561{
3562 fXmin = xmin;
3563 fXmax = xmax;
3565 fComposition->SetRange(xmin, xmax); // automatically updates sub-functions
3566 }
3567 Update();
3568}
3569
3570
3571////////////////////////////////////////////////////////////////////////////////
3572/// Restore value of function saved at point
3573
3575{
3576 if (fSave.empty()) {
3577 fSave.resize(fNpx + 3);
3578 }
3579 if (point < 0 || point >= int(fSave.size())) return;
3580 fSave[point] = value;
3581}
3582
3583
3584////////////////////////////////////////////////////////////////////////////////
3585/// Set function title
3586/// if title has the form "fffffff;xxxx;yyyy", it is assumed that
3587/// the function title is "fffffff" and "xxxx" and "yyyy" are the
3588/// titles for the X and Y axis respectively.
3589
3590void TF1::SetTitle(const char *title)
3591{
3592 if (!title) return;
3593 fTitle = title;
3594 if (!fHistogram) return;
3595 fHistogram->SetTitle(title);
3596 if (gPad) gPad->Modified();
3597}
3598
3599
3600////////////////////////////////////////////////////////////////////////////////
3601/// Stream a class object.
3602
3604{
3605 if (b.IsReading()) {
3606 UInt_t R__s, R__c;
3607 Version_t v = b.ReadVersion(&R__s, &R__c);
3608 // process new version with new TFormula class which is contained in TF1
3609 //printf("reading TF1....- version %d..\n",v);
3610
3611 if (v > 7) {
3612 // new classes with new TFormula
3613 // need to register the objects
3614 b.ReadClassBuffer(TF1::Class(), this, v, R__s, R__c);
3615 if (!TestBit(kNotGlobal)) {
3617 gROOT->GetListOfFunctions()->Add(this);
3618 }
3619 return;
3620 } else {
3622 //printf("Reading TF1 as v5::TF1Data- version %d \n",v);
3623 fold.Streamer(b, v, R__s, R__c, TF1::Class());
3624 // convert old TF1 to new one
3625 ((TF1v5Convert *)this)->Convert(fold);
3626 }
3627 }
3628
3629 // Writing
3630 else {
3631 Int_t saved = 0;
3632 // save not-formula functions as array of points
3633 if (fType > 0 && fSave.empty() && fType != EFType::kCompositionFcn) {
3634 saved = 1;
3635 Save(fXmin, fXmax, 0, 0, 0, 0);
3636 }
3637 b.WriteClassBuffer(TF1::Class(), this);
3638
3639 // clear vector contents
3640 if (saved) {
3641 fSave.clear();
3642 }
3643 }
3644}
3645
3646
3647////////////////////////////////////////////////////////////////////////////////
3648/// Called by functions such as SetRange, SetNpx, SetParameters
3649/// to force the deletion of the associated histogram or Integral
3650
3652{
3653 if (fHistogram) {
3657 fHistogram->GetXaxis()->TAttAxis::Copy(attx);
3658 fHistogram->GetYaxis()->TAttAxis::Copy(atty);
3659
3660 delete fHistogram;
3661 fHistogram = nullptr;
3662 GetHistogram();
3663
3666 attx.Copy(*(fHistogram->GetXaxis()));
3667 atty.Copy(*(fHistogram->GetYaxis()));
3668 }
3669 if (!fIntegral.empty()) {
3670 fIntegral.clear();
3671 fAlpha.clear();
3672 fBeta.clear();
3673 fGamma.clear();
3674 }
3675 if (fNormalized) {
3676 // need to compute the integral of the not-normalized function
3677 fNormalized = false;
3679 fNormalized = true;
3680 } else
3681 fNormIntegral = 0;
3682
3683 // std::vector<double>x(fNdim);
3684 // if ((fType == 1) && !fFunctor->Empty()) (*fFunctor)x.data(), (Double_t*)fParams);
3686 // double-check that the parameters are correct
3687 fComposition->SetParameters(GetParameters());
3688
3689 fComposition->Update(); // should not be necessary, but just to be safe
3690 }
3691}
3692
3693////////////////////////////////////////////////////////////////////////////////
3694/// Static function to set the global flag to reject points
3695/// the fgRejectPoint global flag is tested by all fit functions
3696/// if TRUE the point is not included in the fit.
3697/// This flag can be set by a user in a fitting function.
3698/// The fgRejectPoint flag is reset by the TH1 and TGraph fitting functions.
3699
3704
3705
3706////////////////////////////////////////////////////////////////////////////////
3707/// See TF1::RejectPoint above
3708
3710{
3711 return fgRejectPoint;
3712}
3713
3714////////////////////////////////////////////////////////////////////////////////
3715/// Return nth moment of function between a and b
3716///
3717/// See TF1::Integral() for parameter definitions
3718
3720{
3721 // wrapped function in interface for integral calculation
3722 // using abs value of integral
3723
3724 TF1_EvalWrapper func(this, params, kTRUE, n);
3725
3727
3728 giod.SetFunction(func);
3729 giod.SetRelTolerance(epsilon);
3730
3731 Double_t norm = giod.Integral(a, b);
3732 if (norm == 0) {
3733 Error("Moment", "Integral zero over range");
3734 return 0;
3735 }
3736
3737 // calculate now integral of x^n f(x)
3738 // wrapped the member function EvalNum in interface required by integrator using the functor class
3740 giod.SetFunction(xnfunc);
3741
3742 Double_t res = giod.Integral(a, b) / norm;
3743
3744 return res;
3745}
3746
3747
3748////////////////////////////////////////////////////////////////////////////////
3749/// Return nth central moment of function between a and b
3750/// (i.e the n-th moment around the mean value)
3751///
3752/// See TF1::Integral() for parameter definitions
3753///
3754/// \author Gene Van Buren <gene@bnl.gov>
3755
3757{
3758 TF1_EvalWrapper func(this, params, kTRUE, n);
3759
3761
3762 giod.SetFunction(func);
3763 giod.SetRelTolerance(epsilon);
3764
3765 Double_t norm = giod.Integral(a, b);
3766 if (norm == 0) {
3767 Error("Moment", "Integral zero over range");
3768 return 0;
3769 }
3770
3771 // calculate now integral of xf(x)
3772 // wrapped the member function EvalFirstMom in interface required by integrator using the functor class
3774 giod.SetFunction(xfunc);
3775
3776 // estimate of mean value
3777 Double_t xbar = giod.Integral(a, b) / norm;
3778
3779 // use different mean value in function wrapper
3780 func.fX0 = xbar;
3782 giod.SetFunction(xnfunc);
3783
3784 Double_t res = giod.Integral(a, b) / norm;
3785 return res;
3786}
3787
3788
3789//______________________________________________________________________________
3790// some useful static utility functions to compute sampling points for IntegralFast
3791////////////////////////////////////////////////////////////////////////////////
3792/// Type safe interface (static method)
3793/// The number of sampling points are taken from the TGraph
3794
3795#ifdef INTHEFUTURE
3797{
3798 if (!g) return;
3799 CalcGaussLegendreSamplingPoints(g->GetN(), g->GetX(), g->GetY(), eps);
3800}
3801
3802
3803////////////////////////////////////////////////////////////////////////////////
3804/// Type safe interface (static method)
3805/// A TGraph is created with new with num points and the pointer to the
3806/// graph is returned by the function. It is the responsibility of the
3807/// user to delete the object.
3808/// if num is invalid (<=0) NULL is returned
3809
3811{
3812 if (num <= 0)
3813 return 0;
3814
3815 TGraph *g = new TGraph(num);
3816 CalcGaussLegendreSamplingPoints(g->GetN(), g->GetX(), g->GetY(), eps);
3817 return g;
3818}
3819#endif
3820
3821
3822////////////////////////////////////////////////////////////////////////////////
3823/// Type: unsafe but fast interface filling the arrays x and w (static method)
3824///
3825/// Given the number of sampling points this routine fills the arrays x and w
3826/// of length num, containing the abscissa and weight of the Gauss-Legendre
3827/// n-point quadrature formula.
3828///
3829/// Gauss-Legendre:
3830/** \f[
3831 W(x)=1 -1<x<1 \\
3832 (j+1)P_{j+1} = (2j+1)xP_j-jP_{j-1}
3833 \f]
3834**/
3835/// num is the number of sampling points (>0)
3836/// x and w are arrays of size num
3837/// eps is the relative precision
3838///
3839/// If num<=0 or eps<=0 no action is done.
3840///
3841/// Reference: Numerical Recipes in C, Second Edition
3842
3844{
3845 // This function is just kept like this for backward compatibility!
3846
3848 gli.GetWeightVectors(x, w);
3849
3850
3851}
3852
3853
3854/** \class TF1Parameters
3855TF1 Parameters class
3856*/
3857
3858////////////////////////////////////////////////////////////////////////////////
3859/// Returns the parameter number given a name
3860/// not very efficient but list of parameters is typically small
3861/// could use a map if needed
3862
3864{
3865 for (unsigned int i = 0; i < fParNames.size(); ++i) {
3866 if (fParNames[i] == std::string(name)) return i;
3867 }
3868 return -1;
3869}
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:622
R__EXTERN TVirtualMutex * gROOTMutex
Definition TROOT.h:63
#define gROOT
Definition TROOT.h:414
R__EXTERN TRandom * gRandom
Definition TRandom.h:62
R__EXTERN TStyle * gStyle
Definition TStyle.h:442
#define R__LOCKGUARD(mutex)
#define gPad
#define snprintf
Definition civetweb.c: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:97
User class for performing function integration.
User class for performing function integration.
Interface (abstract class) for generic functions objects of one-dimension Provides a method to evalua...
Definition IFunction.h: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:5118
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:3863
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:1851
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:1724
virtual Double_t GetXmax() const
Definition TF1.h:592
virtual void ReleaseParameter(Int_t ipar)
Release parameter number ipar during a fit operation.
Definition TF1.cxx:3178
virtual void SetParError(Int_t ipar, Double_t error)
Set error for parameter number ipar.
Definition TF1.cxx:3511
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:3700
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:1121
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:1917
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:3843
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:1612
virtual void GetParLimits(Int_t ipar, Double_t &parmin, Double_t &parmax) const
Return limits for parameter ipar.
Definition TF1.cxx:1968
Int_t fNpar
Number of parameters.
Definition TF1.h:266
TAxis * GetYaxis() const
Get y axis of the function.
Definition TF1.cxx:2437
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:3451
virtual Double_t GetParError(Int_t ipar) const
Return value of parameter number ipar.
Definition TF1.cxx:1958
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:2734
virtual void SetChisquare(Double_t chi2)
Definition TF1.h:648
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:2804
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:3426
void Print(Option_t *option="") const override
This method must be overridden when a class wants to print itself.
Definition TF1.cxx:2923
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:3651
virtual Double_t GetProb() const
Return the fit probability.
Definition TF1.cxx:1983
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:2020
TAxis * GetZaxis() const
Get z axis of the function. (In case this object is a TF2 or TF3)
Definition TF1.cxx:2448
virtual Double_t GetRandom(TRandom *rng=nullptr, Option_t *opt=nullptr)
Return a random number following this function shape.
Definition TF1.cxx:2218
virtual void SetRange(Double_t xmin, Double_t xmax)
Initialize the upper and lower bounds to draw the function.
Definition TF1.cxx:3560
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
Double_t EvalUncertainty(Double_t x, const TMatrixDSym *covMatrix=nullptr) const
Evaluate the uncertainty of the function at location x due to the parameter uncertainties.
Definition TF1.cxx:1545
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:3246
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:3522
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:3074
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:1186
static void SetCurrent(TF1 *f1)
Static function setting the current function.
Definition TF1.cxx:3375
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:2557
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:3590
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:3495
static Double_t DerivativeError()
Static function returning the error of the last call to the of Derivative's functions.
Definition TF1.cxx:1285
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:2523
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:3465
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:3603
virtual void SetNumberFitPoints(Int_t npfits)
Definition TF1.h:660
void Paint(Option_t *option="") override
Paint this function with its current attributes.
Definition TF1.cxx:2979
TF1 & operator=(const TF1 &rhs)
Operator =.
Definition TF1.cxx:944
virtual Int_t GetNumberFreeParameters() const
Return the number of free parameters.
Definition TF1.cxx:1928
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:3719
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:3756
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:2508
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:2877
Int_t DistancetoPrimitive(Int_t px, Int_t py) override
Compute distance from point px,py to a function.
Definition TF1.cxx:1301
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:1341
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:3439
virtual void GetRange(Double_t *xmin, Double_t *xmax) const
Return range of a generic N-D function.
Definition TF1.cxx:2307
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:1476
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:3539
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:1891
static TF1 * GetCurrent()
Static function returning the current function being processed.
Definition TF1.cxx:1597
virtual void SetParName(Int_t ipar, const char *name)
Set name of parameter number ipar.
Definition TF1.cxx:3482
char * GetObjectInfo(Int_t px, Int_t py) const override
Redefines TObject::GetObjectInfo.
Definition TF1.cxx:1946
void ExecuteEvent(Int_t event, Int_t px, Int_t py) override
Execute action corresponding to one event.
Definition TF1.cxx:1564
virtual Double_t GetSave(const Double_t *x)
Get value corresponding to X in array of fSave values.
Definition TF1.cxx:2370
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:1371
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:3263
virtual Bool_t IsValid() const
Return kTRUE if the function is valid.
Definition TF1.cxx:2908
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:3709
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:1751
virtual void DrawF1(Double_t xmin, Double_t xmax, Option_t *option="")
Draw function between xmin and xmax.
Definition TF1.cxx:1428
Bool_t ComputeCdfTable(Option_t *opt)
Compute the cumulative function at fNpx points between fXmin and fXmax.
Definition TF1.cxx:2107
virtual void SetParameters(const Double_t *params)
Definition TF1.h:685
virtual TObject * DrawIntegral(Option_t *option="al")
Draw integral of this function.
Definition TF1.cxx:1415
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:1393
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:1447
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:1642
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:675
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:1251
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:3188
TObject * Clone(const char *newname=nullptr) const override
Make a complete copy of the underlying object.
Definition TF1.cxx:1072
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 Double_t GradientPar(Int_t ipar, const Double_t *x, Double_t eps=0.01) const
Compute the gradient (derivative) wrt a parameter ipar.
Definition TF1.cxx:2471
virtual void SetSavedPoint(Int_t point, Double_t value)
Restore value of function saved at point.
Definition TF1.cxx:3574
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:1585
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:1683
TClass * IsA() const override
Definition TF1.h:763
virtual Int_t GetNdim() const
Definition TF1.h:517
virtual Double_t GetXmin() const
Definition TF1.h:588
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:2647
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:3387
TAxis * GetXaxis() const
Get x axis of the function.
Definition TF1.cxx:2426
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:925
TH1 is the base class of all histogram classes in ROOT.
Definition TH1.h:108
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:8933
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:537
static TClass * Class()
@ kLogX
X-axis in log scale.
Definition TH1.h:406
@ kNoStats
Don't draw stats box.
Definition TH1.h:403
@ kIsZoomed
Bit set when zooming on Y axis.
Definition TH1.h:407
TAxis * GetXaxis()
Definition TH1.h:571
void Print(Option_t *option="") const override
Print some global quantities for this histogram.
Definition TH1.cxx: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:8541
virtual void SetMaximum(Double_t maximum=-1111)
Definition TH1.h:651
TAxis * GetYaxis()
Definition TH1.h:572
virtual void SetMinimum(Double_t minimum=-1111)
Definition TH1.h:652
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:533
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:8631
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:205
virtual void RecursiveRemove(TObject *obj)
Recursively remove this object from a list.
Definition TObject.cxx:678
static TString SavePrimitiveVector(std::ostream &out, const char *prefix, Int_t len, Double_t *arr, Bool_t empty_line=kFALSE)
Save array in the output stream "out" as vector.
Definition TObject.cxx:788
virtual void Warning(const char *method, const char *msgfmt,...) const
Issue warning message.
Definition TObject.cxx:1057
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:864
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:1071
void MakeZombie()
Definition TObject.h:53
static void SavePrimitiveDraw(std::ostream &out, const char *variable_name, Option_t *option=nullptr)
Save invocation of primitive Draw() method Skipped if option contains "nodraw" string.
Definition TObject.cxx:822
@ kCanDelete
if object in a list can be deleted
Definition TObject.h:68
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
TH1F * h1
Definition legend1.C:5
TF1 * f1
Definition legend1.C:11
Namespace for new Math classes and functions.
double IntegralError(TF1 *func, Int_t ndim, const double *a, const double *b, const double *params, const double *covmat, double epsilon)
Definition TF1Helper.cxx:39
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