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 "strlcpy.h"
13#include "TROOT.h"
14#include "TBuffer.h"
15#include "TMath.h"
16#include "TF1.h"
17#include "TH1.h"
18#include "TGraph.h"
19#include "TVirtualPad.h"
20#include "TStyle.h"
21#include "TRandom.h"
22#include "TObjString.h"
23#include "TInterpreter.h"
24#include "TPluginManager.h"
25#include "TBrowser.h"
26#include "TColor.h"
27#include "TMethodCall.h"
28#include "TF1Helper.h"
29#include "TF1NormSum.h"
30#include "TF1Convolution.h"
31#include "TVectorD.h"
32#include "TMatrixDSym.h"
33#include "TVirtualMutex.h"
35#include "Math/WrappedTF1.h"
38#include "Math/BrentMethods.h"
39#include "Math/Integrator.h"
46#include "Math/Functor.h"
47#include "Math/Minimizer.h"
49#include "Math/Factory.h"
50#include "Math/ChebyshevPol.h"
51#include "Fit/FitResult.h"
52// for I/O backward compatibility
53#include "v5/TF1Data.h"
54
55#include "AnalyticalIntegrals.h"
56
57#include <cstdio>
58#include <iostream>
59#include <memory>
60
61std::atomic<Bool_t> TF1::fgAbsValue(kFALSE);
63std::atomic<Bool_t> TF1::fgAddToGlobList(kTRUE);
65
66using TF1Updater_t = void (*)(Int_t nobjects, TObject **from, TObject **to);
68
69
70namespace {
71struct TF1v5Convert : public TF1 {
72public:
73 void Convert(ROOT::v5::TF1Data &from)
74 {
75 // convert old TF1 to new one
76 fNpar = from.GetNpar();
77 fNdim = from.GetNdim();
78 if (from.fType == 0) {
79 // formula functions
80 // if ndim is not 1 set xmin max to zero to avoid error in ctor
81 double xmin = from.fXmin;
82 double xmax = from.fXmax;
83 if (fNdim > 1) {
84 xmin = 0;
85 xmax = 0;
86 }
87 TF1 fnew(from.GetName(), from.GetExpFormula(), xmin, xmax);
88 if (fNdim > 1) {
89 fnew.SetRange(from.fXmin, from.fXmax);
90 }
91 fnew.Copy(*this);
92 // need to set parameter values
93 if (from.GetParameters())
94 fFormula->SetParameters(from.GetParameters());
95 } else {
96 // case of a function pointers
97 fParams = std::make_unique<TF1Parameters>(fNpar);
98 fName = from.GetName();
99 fTitle = from.GetTitle();
100 // need to set parameter values
101 if (from.GetParameters())
102 fParams->SetParameters(from.GetParameters());
103 }
104 // copy the other data members
105 fNpx = from.fNpx;
106 fType = (EFType)from.fType;
107 fNpfits = from.fNpfits;
108 fNDF = from.fNDF;
109 fChisquare = from.fChisquare;
110 fMaximum = from.fMaximum;
111 fMinimum = from.fMinimum;
112 fXmin = from.fXmin;
113 fXmax = from.fXmax;
114
115 if (from.fParErrors)
116 fParErrors = std::vector<Double_t>(from.fParErrors, from.fParErrors + fNpar);
117 if (from.fParMin)
118 fParMin = std::vector<Double_t>(from.fParMin, from.fParMin + fNpar);
119 if (from.fParMax)
120 fParMax = std::vector<Double_t>(from.fParMax, from.fParMax + fNpar);
121 if (from.fNsave > 0) {
122 assert(from.fSave);
123 fSave = std::vector<Double_t>(from.fSave, from.fSave + from.fNsave);
124 }
125 // set the bits
126 for (int ibit = 0; ibit < 24; ++ibit)
127 if (from.TestBit(BIT(ibit)))
128 SetBit(BIT(ibit));
129
130 // copy the graph attributes
131 from.TAttLine::Copy(*this);
132 from.TAttFill::Copy(*this);
133 from.TAttMarker::Copy(*this);
134 }
135};
136} // unnamed namespace
137
138static void R__v5TF1Updater(Int_t nobjects, TObject **from, TObject **to)
139{
140 auto **fromv5 = (ROOT::v5::TF1Data **)from;
141 auto **target = (TF1v5Convert **)to;
142
143 for (int i = 0; i < nobjects; ++i) {
144 if (fromv5[i] && target[i])
145 target[i]->Convert(*fromv5[i]);
146 }
147}
148
150
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
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
339
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
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); // 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
512 TNamed(name, formula), fType(EFType::kFormula)
513{
514 if (xmin < xmax) {
515 fXmin = xmin;
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
546 // remove spaces from these formulas
547 formula1.ReplaceAll(' ', "");
548 formula2.ReplaceAll(' ', "");
549
550 TF1 *function1 = (TF1 *)(gROOT->GetListOfFunctions()->FindObject(formula1));
551 if (!function1)
552 function1 = new TF1(formula1.Data(), formula1.Data(), xmin, xmax);
553 TF1 *function2 = (TF1 *)(gROOT->GetListOfFunctions()->FindObject(formula2));
554 if (!function2)
555 function2 = new TF1(formula2.Data(), formula2.Data(), xmin, xmax);
556
557 // std::cout << "functions have been defined" << std::endl;
558
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
602 formDense.ReplaceAll(' ', "");
603
604 // make sure standard functions are defined (e.g. gaus, expo)
606
607 // Go char-by-char to split terms and define the relevant functions
608 int parenCount = 0;
609 int termStart = 0;
611 newFuncs.SetOwner(kTRUE);
613 coeffNames.SetOwner(kTRUE);
615 for (int i = 0; i < formDense.Length(); ++i) {
616 if (formDense[i] == '(')
617 parenCount++;
618 else if (formDense[i] == ')')
619 parenCount--;
620 else if (formDense[i] == delimiter && parenCount == 0) {
621 // term goes from termStart to i
623 termStart = i + 1;
624 }
625 }
627
629
630 if (xmin == 0 && xmax == 1.) Info("TF1","Created TF1NormSum object using the default [0,1] range");
631
632 fNpar = normSum->GetNpar();
633 fNdim = 1; // (note: may want to extend functionality in the future)
634
636 fComposition = std::unique_ptr<TF1AbsComposition>(normSum);
637
638 fParams = std::make_unique<TF1Parameters>(fNpar);
639 fParams->SetParameters(&(normSum->GetParameters())[0]); // inherit default parameters from normSum
640
641 // Parameter names
642 for (int i = 0; i < fNpar; i++) {
643 if (coeffNames.At(i)) {
644 this->SetParName(i, coeffNames.At(i)->GetName());
645 } else {
646 this->SetParName(i, normSum->GetParName(i));
647 }
648 }
649
650 } else { // regular TFormula
651 fFormula = std::make_unique<TFormula>(name, formula, false, vectorize);
652 fNpar = fFormula->GetNpar();
653 // TFormula can have dimension zero, but since this is a TF1 minimal dim is 1
654 fNdim = fFormula->GetNdim() == 0 ? 1 : fFormula->GetNdim();
655 }
656 if (fNpar) {
657 fParErrors.resize(fNpar);
658 fParMin.resize(fNpar);
659 fParMax.resize(fNpar);
660 }
661 // do we want really to have this un-documented feature where we accept cases where dim > 1
662 // by setting xmin >= xmax ??
663 if (fNdim > 1 && xmin < xmax) {
664 Error("TF1", "function: %s/%s has dimension %d instead of 1", name, formula, fNdim);
665 MakeZombie();
666 }
667
669}
670
672{
673 if (opt == nullptr) return TF1::EAddToList::kDefault;
674 TString option(opt);
675 option.ToUpper();
676 if (option.Contains("NL")) return TF1::EAddToList::kNo;
677 if (option.Contains("GL")) return TF1::EAddToList::kAdd;
679}
680
682{
683 if (!opt) return false;
684 TString option(opt);
685 option.ToUpper();
686 if (option.Contains("VEC")) return true;
687 return false;
688}
689
690TF1::TF1(const char *name, const char *formula, Double_t xmin, Double_t xmax, Option_t * opt) :
691////////////////////////////////////////////////////////////////////////////////
692/// Same constructor as above (for TFormula based function) but passing an option strings
693/// available options
694/// VEC - vectorize the formula expressions (not possible for lambda based expressions)
695/// NL - function is not 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/// TF1 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#ifdef R__HAS_STD_EXPERIMENTAL_SIMD
1458
1459// Internal to TF1. Evaluates Vectorized TF1 on data of type Double_v
1460// The compiler should be able to inline this.
1461double TF1::EvalParVec(const Double_t *data, const Double_t *params)
1462{
1464 std::vector<ROOT::Double_v> d(fNdim);
1465 ROOT::Double_v res;
1466
1467 for (auto i = 0; i < fNdim; i++) {
1468 d[i] = ROOT::Double_v(data[i]);
1469 }
1470
1471 if (fFunctor) {
1472 res = ((TF1FunctorPointerImpl<ROOT::Double_v> *)fFunctor.get())->fImpl(d.data(), params);
1473 } else {
1474 // res = GetSave(x);
1475 return TMath::SignalingNaN();
1476 }
1477 return res[0];
1478}
1479#endif
1480
1481////////////////////////////////////////////////////////////////////////////////
1482/// Evaluate function with given coordinates and parameters.
1483///
1484/// Compute the value of this function at point defined by array x
1485/// and current values of parameters in array params.
1486/// If argument params is omitted or equal 0, the internal values
1487/// of parameters (array fParams) will be used instead.
1488/// For a 1-D function only x[0] must be given.
1489/// In case of a multi-dimensional function, the arrays x must be
1490/// filled with the corresponding number of dimensions.
1491///
1492/// WARNING. In case of an interpreted function (fType=2), it is the
1493/// user's responsibility to initialize the parameters via InitArgs
1494/// before calling this function.
1495/// InitArgs should be called at least once to specify the addresses
1496/// of the arguments x and params.
1497/// InitArgs should be called every time these addresses change.
1498
1500{
1501 //fgCurrent = this;
1502
1503 if (fType == EFType::kFormula) {
1505
1506 if (fNormalized && fNormIntegral != 0)
1507 return fFormula->EvalPar(x, params) / fNormIntegral;
1508 else
1509 return fFormula->EvalPar(x, params);
1510 }
1511 Double_t result = 0;
1513 if (fFunctor) {
1514 assert(fParams);
1515 if (params) result = ((TF1FunctorPointerImpl<Double_t> *)fFunctor.get())->fImpl((Double_t *)x, (Double_t *)params);
1516 else result = ((TF1FunctorPointerImpl<Double_t> *)fFunctor.get())->fImpl((Double_t *)x, (Double_t *)fParams->GetParameters());
1517
1518 } else result = GetSave(x);
1519
1520 if (fNormalized && fNormIntegral != 0)
1522
1523 return result;
1524 }
1525 if (fType == EFType::kInterpreted) {
1526 if (fMethodCall) fMethodCall->Execute(result);
1527 else result = GetSave(x);
1528
1529 if (fNormalized && fNormIntegral != 0)
1531
1532 return result;
1533 }
1534
1535#ifdef R__HAS_STD_EXPERIMENTAL_SIMD
1536 if (fType == EFType::kTemplVec) {
1537 if (fFunctor) {
1538 if (params) result = EvalParVec(x, params);
1539 else result = EvalParVec(x, (Double_t *) fParams->GetParameters());
1540 }
1541 else {
1542 result = GetSave(x);
1543 }
1544
1545 if (fNormalized && fNormIntegral != 0)
1547
1548 return result;
1549 }
1550#endif
1551
1553 if (!fComposition)
1554 Error("EvalPar", "Composition function not found");
1555
1556 result = (*fComposition)(x, params);
1557 }
1558
1559 return result;
1560}
1561
1562/// Evaluate the uncertainty of the function at location x due to the parameter
1563/// uncertainties. If covMatrix is nullptr, assumes uncorrelated uncertainties,
1564/// otherwise the input covariance matrix (e.g. from a fit performed with
1565/// option "S") is used. Implemented for 1-d only.
1566/// @note to obtain confidence intervals of a fit result for drawing purposes,
1567/// see instead ROOT::Fit::FitResult::GetConfidenceInterval()
1569{
1570 TVectorD grad(GetNpar());
1571 GradientPar(&x, grad.GetMatrixArray());
1572 if (!covMatrix) {
1573 Double_t variance = 0;
1574 for(Int_t iPar = 0; iPar < GetNpar(); iPar++) {
1576 }
1577 return std::sqrt(variance);
1578 }
1579 return std::sqrt(covMatrix->Similarity(grad));
1580}
1581
1582////////////////////////////////////////////////////////////////////////////////
1583/// Execute action corresponding to one event.
1584///
1585/// This member function is called when a F1 is clicked with the locator
1586
1588{
1589 if (!gPad) return;
1590
1591 if (fHistogram) fHistogram->ExecuteEvent(event, px, py);
1592
1593 if (!gPad->GetView()) {
1594 if (event == kMouseMotion) gPad->SetCursor(kHand);
1595 }
1596}
1597
1598
1599////////////////////////////////////////////////////////////////////////////////
1600/// Fix the value of a parameter for a fit operation
1601/// The specified value will be used in the fit and
1602/// the parameter will be constant (nor varying) during fitting
1603/// Note that when using pre-defined functions (e.g gaus),
1604/// one needs to use the fit option 'B' to have the fix of the paramter
1605/// effective. See TH1::Fit(TF1*, Option_t *, Option_t *, Double_t, Double_t) for
1606/// the fitting documentation and the fitting options.
1607
1609{
1610 if (ipar < 0 || ipar > GetNpar() - 1) return;
1611 SetParameter(ipar, value);
1612 if (value != 0) SetParLimits(ipar, value, value);
1613 else SetParLimits(ipar, 1, 1);
1614}
1615
1616
1617////////////////////////////////////////////////////////////////////////////////
1618/// Static function returning the current function being processed
1619
1621{
1622 ::Warning("TF1::GetCurrent", "This function is obsolete and is working only for the current painted functions");
1623 return fgCurrent;
1624}
1625
1626
1627////////////////////////////////////////////////////////////////////////////////
1628/// Return a pointer to the histogram used to visualise the function
1629/// Note that this histogram is managed by the function and
1630/// in same case it is automatically deleted when some TF1 functions are called
1631/// such as TF1::SetParameters, TF1::SetNpx, TF1::SetRange
1632/// It is then reccomended either to clone the return object or calling again teh GetHistogram
1633/// function whenever is needed
1634
1636{
1637 if (fHistogram) return fHistogram;
1638
1639 // histogram has not been yet created - create it
1640 // should not we make this function not const ??
1641 const_cast<TF1 *>(this)->fHistogram = const_cast<TF1 *>(this)->CreateHistogram();
1642 if (!fHistogram) Error("GetHistogram", "Error creating histogram for function %s of type %s", GetName(), IsA()->GetName());
1643 return fHistogram;
1644}
1645
1646
1647////////////////////////////////////////////////////////////////////////////////
1648/// Returns the maximum value of the function
1649///
1650/// Method:
1651/// First, the grid search is used to bracket the maximum
1652/// with the step size = (xmax-xmin)/fNpx.
1653/// This way, the step size can be controlled via the SetNpx() function.
1654/// If the function is unimodal or if its extrema are far apart, setting
1655/// the fNpx to a small value speeds the algorithm up many times.
1656/// Then, Brent's method is applied on the bracketed interval
1657/// epsilon (default = 1.E-10) controls the relative accuracy (if |x| > 1 )
1658/// and absolute (if |x| < 1) and maxiter (default = 100) controls the maximum number
1659/// of iteration of the Brent algorithm
1660/// If the flag logx is set the grid search is done in log step size
1661/// This is done automatically if the log scale is set in the current Pad
1662///
1663/// NOTE: see also TF1::GetMaximumX and TF1::GetX
1664
1666{
1667 if (xmin >= xmax) {
1668 xmin = fXmin;
1669 xmax = fXmax;
1670 }
1671
1672 if (!logx && gPad != nullptr) logx = gPad->GetLogx();
1673
1675 GInverseFunc g(this);
1677 bm.SetFunction(wf1, xmin, xmax);
1678 bm.SetNpx(fNpx);
1679 bm.SetLogScan(logx);
1680 bm.Minimize(maxiter, epsilon, epsilon);
1681 Double_t x;
1682 x = - bm.FValMinimum();
1683
1684 return x;
1685}
1686
1687
1688////////////////////////////////////////////////////////////////////////////////
1689/// Returns the X value corresponding to the maximum value of the function
1690///
1691/// Method:
1692/// First, the grid search is used to bracket the maximum
1693/// with the step size = (xmax-xmin)/fNpx.
1694/// This way, the step size can be controlled via the SetNpx() function.
1695/// If the function is unimodal or if its extrema are far apart, setting
1696/// the fNpx to a small value speeds the algorithm up many times.
1697/// Then, Brent's method is applied on the bracketed interval
1698/// epsilon (default = 1.E-10) controls the relative accuracy (if |x| > 1 )
1699/// and absolute (if |x| < 1) and maxiter (default = 100) controls the maximum number
1700/// of iteration of the Brent algorithm
1701/// If the flag logx is set the grid search is done in log step size
1702/// This is done automatically if the log scale is set in the current Pad
1703///
1704/// NOTE: see also TF1::GetX
1705
1707{
1708 if (xmin >= xmax) {
1709 xmin = fXmin;
1710 xmax = fXmax;
1711 }
1712
1713 if (!logx && gPad != nullptr) logx = gPad->GetLogx();
1714
1716 GInverseFunc g(this);
1718 bm.SetFunction(wf1, xmin, xmax);
1719 bm.SetNpx(fNpx);
1720 bm.SetLogScan(logx);
1721 bm.Minimize(maxiter, epsilon, epsilon);
1722 Double_t x;
1723 x = bm.XMinimum();
1724
1725 return x;
1726}
1727
1728
1729////////////////////////////////////////////////////////////////////////////////
1730/// Returns the minimum value of the function on the (xmin, xmax) interval
1731///
1732/// Method:
1733/// First, the grid search is used to bracket the maximum
1734/// with the step size = (xmax-xmin)/fNpx. This way, the step size
1735/// can be controlled via the SetNpx() function. If the function is
1736/// unimodal or if its extrema are far apart, setting the fNpx to
1737/// a small value speeds the algorithm up many times.
1738/// Then, Brent's method is applied on the bracketed interval
1739/// epsilon (default = 1.E-10) controls the relative accuracy (if |x| > 1 )
1740/// and absolute (if |x| < 1) and maxiter (default = 100) controls the maximum number
1741/// of iteration of the Brent algorithm
1742/// If the flag logx is set the grid search is done in log step size
1743/// This is done automatically if the log scale is set in the current Pad
1744///
1745/// NOTE: see also TF1::GetMaximumX and TF1::GetX
1746
1748{
1749 if (xmin >= xmax) {
1750 xmin = fXmin;
1751 xmax = fXmax;
1752 }
1753
1754 if (!logx && gPad != nullptr) logx = gPad->GetLogx();
1755
1758 bm.SetFunction(wf1, xmin, xmax);
1759 bm.SetNpx(fNpx);
1760 bm.SetLogScan(logx);
1761 bm.Minimize(maxiter, epsilon, epsilon);
1762 Double_t x;
1763 x = bm.FValMinimum();
1764
1765 return x;
1766}
1767
1768////////////////////////////////////////////////////////////////////////////////
1769/// Find the minimum of a function of whatever dimension.
1770/// While GetMinimum works only for 1D function , GetMinimumNDim works for all dimensions
1771/// since it uses the minimizer interface
1772/// vector x at beginning will contained the initial point, on exit will contain the result
1773
1775{
1776 R__ASSERT(x != nullptr);
1777
1778 int ndim = GetNdim();
1779 if (ndim == 0) {
1780 Error("GetMinimumNDim", "Function of dimension 0 - return Eval(x)");
1781 return (const_cast<TF1 &>(*this))(x);
1782 }
1783
1784 // create minimizer class
1788
1789 if (min == nullptr) {
1790 Error("GetMinimumNDim", "Error creating minimizer %s", minimName);
1791 return 0;
1792 }
1793
1794 // minimizer will be set using default values
1795 if (epsilon > 0) min->SetTolerance(epsilon);
1796 if (maxiter > 0) min->SetMaxFunctionCalls(maxiter);
1797
1798 // create wrapper class from TF1 (cannot use Functor, t.b.i.)
1799 ROOT::Math::WrappedMultiFunction<TF1 &> objFunc(const_cast<TF1 &>(*this), ndim);
1800 // create -f(x) when searching for the maximum
1801 GInverseFuncNdim invFunc(const_cast<TF1 *>(this));
1803 if (!findmax)
1804 min->SetFunction(objFunc);
1805 else
1806 min->SetFunction(objFuncInv);
1807
1808 std::vector<double> rmin(ndim);
1809 std::vector<double> rmax(ndim);
1810 GetRange(&rmin[0], &rmax[0]);
1811 for (int i = 0; i < ndim; ++i) {
1812 const char *xname = nullptr;
1813 double stepSize = 0.1;
1814 // use range for step size or give some value depending on x if range is not defined
1815 if (rmax[i] > rmin[i])
1816 stepSize = (rmax[i] - rmin[i]) / 100;
1817 else if (std::abs(x[i]) > 1.)
1818 stepSize = 0.1 * x[i];
1819
1820 // set variable names
1821 if (ndim <= 3) {
1822 if (i == 0) {
1823 xname = "x";
1824 } else if (i == 1) {
1825 xname = "y";
1826 } else {
1827 xname = "z";
1828 }
1829 } else {
1830 xname = TString::Format("x_%d", i);
1831 // arbitrary step sie (should be computed from range)
1832 }
1833
1834 if (rmin[i] < rmax[i]) {
1835 //Info("GetMinMax","setting limits on %s - [ %f , %f ]",xname,rmin[i],rmax[i]);
1836 min->SetLimitedVariable(i, xname, x[i], stepSize, rmin[i], rmax[i]);
1837 } else {
1838 min->SetVariable(i, xname, x[i], stepSize);
1839 }
1840 }
1841
1842 bool ret = min->Minimize();
1843 if (!ret) {
1844 Error("GetMinimumNDim", "Error minimizing function %s", GetName());
1845 }
1846 if (min->X()) std::copy(min->X(), min->X() + ndim, x);
1847 double fmin = min->MinValue();
1848 delete min;
1849 // need to revert sign in case looking for maximum
1850 return (findmax) ? -fmin : fmin;
1851
1852}
1853
1854
1855////////////////////////////////////////////////////////////////////////////////
1856/// Returns the X value corresponding to the minimum value of the function
1857/// on the (xmin, xmax) interval
1858///
1859/// Method:
1860/// First, the grid search is used to bracket the maximum
1861/// with the step size = (xmax-xmin)/fNpx. This way, the step size
1862/// can be controlled via the SetNpx() function. If the function is
1863/// unimodal or if its extrema are far apart, setting the fNpx to
1864/// a small value speeds the algorithm up many times.
1865/// Then, Brent's method is applied on the bracketed interval
1866/// epsilon (default = 1.E-10) controls the relative accuracy (if |x| > 1 )
1867/// and absolute (if |x| < 1) and maxiter (default = 100) controls the maximum number
1868/// of iteration of the Brent algorithm
1869/// If the flag logx is set the grid search is done in log step size
1870/// This is done automatically if the log scale is set in the current Pad
1871///
1872/// NOTE: see also TF1::GetX
1873
1875{
1876 if (xmin >= xmax) {
1877 xmin = fXmin;
1878 xmax = fXmax;
1879 }
1880
1883 bm.SetFunction(wf1, xmin, xmax);
1884 bm.SetNpx(fNpx);
1885 bm.SetLogScan(logx);
1886 bm.Minimize(maxiter, epsilon, epsilon);
1887 Double_t x;
1888 x = bm.XMinimum();
1889
1890 return x;
1891}
1892
1893
1894////////////////////////////////////////////////////////////////////////////////
1895/// Returns the X value corresponding to the function value fy for (xmin<x<xmax).
1896/// in other words it can find the roots of the function when fy=0 and successive calls
1897/// by changing the next call to [xmin+eps,xmax] where xmin is the previous root.
1898///
1899/// Method:
1900/// First, the grid search is used to bracket the maximum
1901/// with the step size = (xmax-xmin)/fNpx. This way, the step size
1902/// can be controlled via the SetNpx() function. If the function is
1903/// unimodal or if its extrema are far apart, setting the fNpx to
1904/// a small value speeds the algorithm up many times.
1905/// Then, Brent's method is applied on the bracketed interval
1906/// epsilon (default = 1.E-10) controls the relative accuracy (if |x| > 1 )
1907/// and absolute (if |x| < 1) and maxiter (default = 100) controls the maximum number
1908/// of iteration of the Brent algorithm
1909/// If the flag logx is set the grid search is done in log step size
1910/// This is done automatically if the log scale is set in the current Pad
1911///
1912/// NOTE: see also TF1::GetMaximumX, TF1::GetMinimumX
1913
1915{
1916 if (xmin >= xmax) {
1917 xmin = fXmin;
1918 xmax = fXmax;
1919 }
1920
1921 if (!logx && gPad != nullptr) logx = gPad->GetLogx();
1922
1923 GFunc g(this, fy);
1926 brf.SetFunction(wf1, xmin, xmax);
1927 brf.SetNpx(fNpx);
1928 brf.SetLogScan(logx);
1929 bool ret = brf.Solve(maxiter, epsilon, epsilon);
1930 if (!ret) Error("GetX","[%f,%f] is not a valid interval",xmin,xmax);
1931 return (ret) ? brf.Root() : TMath::QuietNaN();
1932}
1933
1934////////////////////////////////////////////////////////////////////////////////
1935/// Return the number of degrees of freedom in the fit
1936/// the fNDF parameter has been previously computed during a fit.
1937/// The number of degrees of freedom corresponds to the number of points
1938/// used in the fit minus the number of free parameters.
1939
1941{
1942 Int_t npar = GetNpar();
1943 if (fNDF == 0 && (fNpfits > npar)) return fNpfits - npar;
1944 return fNDF;
1945}
1946
1947
1948////////////////////////////////////////////////////////////////////////////////
1949/// Return the number of free parameters
1950
1952{
1953 Int_t ntot = GetNpar();
1954 Int_t nfree = ntot;
1955 Double_t al, bl;
1956 for (Int_t i = 0; i < ntot; i++) {
1957 ((TF1 *)this)->GetParLimits(i, al, bl);
1958 if (al * bl != 0 && al >= bl) nfree--;
1959 }
1960 return nfree;
1961}
1962
1963
1964////////////////////////////////////////////////////////////////////////////////
1965/// Redefines TObject::GetObjectInfo.
1966/// Displays the function info (x, function value)
1967/// corresponding to cursor position px,py
1968
1969char *TF1::GetObjectInfo(Int_t px, Int_t /* py */) const
1970{
1971 static char info[64];
1972 Double_t x = gPad->PadtoX(gPad->AbsPixeltoX(px));
1973 snprintf(info, 64, "(x=%g, f=%g)", x, ((TF1 *)this)->Eval(x));
1974 return info;
1975}
1976
1977
1978////////////////////////////////////////////////////////////////////////////////
1979/// Return value of parameter number ipar
1980
1982{
1983 if (ipar < 0 || ipar > GetNpar() - 1) return 0;
1984 return fParErrors[ipar];
1985}
1986
1987
1988////////////////////////////////////////////////////////////////////////////////
1989/// Return limits for parameter ipar.
1990
1992{
1993 parmin = 0;
1994 parmax = 0;
1995 int n = fParMin.size();
1996 assert(n == int(fParMax.size()) && n <= fNpar);
1997 if (ipar < 0 || ipar > n - 1) return;
1998 parmin = fParMin[ipar];
1999 parmax = fParMax[ipar];
2000}
2001
2002
2003////////////////////////////////////////////////////////////////////////////////
2004/// Return the fit probability
2005
2007{
2008 if (fNDF <= 0) return 0;
2009 return TMath::Prob(fChisquare, fNDF);
2010}
2011
2012////////////////////////////////////////////////////////////////////////////////
2013/// Compute Quantiles for density distribution of this function
2014///
2015/// Quantile x_p of a probability distribution Function F is defined as
2016/// \f[
2017/// F(x_{p}) = \int_{xmin}^{x_{p}} f dx = p \text{with} 0 <= p <= 1.
2018/// \f]
2019/// For instance the median \f$ x_{\frac{1}{2}} \f$ of a distribution is defined as that value
2020/// of the random variable for which the distribution function equals 0.5:
2021/// \f[
2022/// F(x_{\frac{1}{2}}) = \prod(x < x_{\frac{1}{2}}) = \frac{1}{2}
2023/// \f]
2024///
2025/// \param[in] n maximum size of array xp and size of array p
2026/// \param[out] xp array filled with n quantiles evaluated at p. Memory has to be preallocated by caller.
2027/// \param[in] p array of cumulative probabilities where quantiles should be evaluated.
2028/// It is assumed to contain at least n values.
2029/// \return n, the number of quantiles computed (same as input argument n)
2030///
2031/// Getting quantiles from two histograms and storing results in a TGraph,
2032/// a so-called QQ-plot
2033///
2034/// TGraph *gr = new TGraph(nprob);
2035/// f1->GetQuantiles(nprob,gr->GetX(),p);
2036/// f2->GetQuantiles(nprob,gr->GetY(),p);
2037/// gr->Draw("alp");
2038///
2039/// \author Eddy Offermann
2040/// \warning Function leads to undefined behavior if xp or p are null or
2041/// their size does not match with n
2042
2044{
2045 // LM: change to use fNpx
2046 // should we change code to use a root finder ?
2047 // It should be more precise and more efficient
2048 const Int_t npx = TMath::Max(fNpx, 2 * n);
2049 const Double_t xMin = GetXmin();
2050 const Double_t xMax = GetXmax();
2051 const Double_t dx = (xMax - xMin) / npx;
2052
2053 TArrayD integral(npx + 1);
2054 TArrayD alpha(npx);
2055 TArrayD beta(npx);
2056 TArrayD gamma(npx);
2057
2058 integral[0] = 0;
2059 Int_t intNegative = 0;
2060 Int_t i;
2061 for (i = 0; i < npx; i++) {
2062 Double_t integ = Integral(Double_t(xMin + i * dx), Double_t(xMin + i * dx + dx), 0.0);
2063 if (integ < 0) {
2064 intNegative++;
2065 integ = -integ;
2066 }
2067 integral[i + 1] = integral[i] + integ;
2068 }
2069
2070 if (intNegative > 0)
2071 Warning("GetQuantiles", "function:%s has %d negative values: abs assumed",
2072 GetName(), intNegative);
2073 if (integral[npx] == 0) {
2074 Error("GetQuantiles", "Integral of function is zero");
2075 return 0;
2076 }
2077
2078 const Double_t total = integral[npx];
2079 for (i = 1; i <= npx; i++) integral[i] /= total;
2080 //the integral r for each bin is approximated by a parabola
2081 // x = alpha + beta*r +gamma*r**2
2082 // compute the coefficients alpha, beta, gamma for each bin
2083 for (i = 0; i < npx; i++) {
2084 const Double_t x0 = xMin + dx * i;
2085 const Double_t r2 = integral[i + 1] - integral[i];
2086 const Double_t r1 = Integral(x0, x0 + 0.5 * dx, 0.0) / total;
2087 gamma[i] = (2 * r2 - 4 * r1) / (dx * dx);
2088 beta[i] = r2 / dx - gamma[i] * dx;
2089 alpha[i] = x0;
2090 gamma[i] *= 2;
2091 }
2092
2093 // Be careful because of finite precision in the integral; Use the fact that the integral
2094 // is monotone increasing
2095 for (i = 0; i < n; i++) {
2096 const Double_t r = p[i];
2097 Int_t bin = TMath::Max(TMath::BinarySearch(npx + 1, integral.GetArray(), r), (Long64_t)0);
2098 // in case the prob is 1
2099 if (bin == npx) {
2100 xp[i] = xMax;
2101 continue;
2102 }
2103 // LM use a tolerance 1.E-12 (integral precision)
2104 while (bin < npx - 1 && TMath::AreEqualRel(integral[bin + 1], r, 1E-12)) {
2105 if (TMath::AreEqualRel(integral[bin + 2], r, 1E-12)) bin++;
2106 else break;
2107 }
2108
2109 const Double_t rr = r - integral[bin];
2110 if (rr != 0.0) {
2111 Double_t xx = 0.0;
2112 const Double_t fac = -2.*gamma[bin] * rr / beta[bin] / beta[bin];
2113 if (fac != 0 && fac <= 1)
2114 xx = (-beta[bin] + TMath::Sqrt(beta[bin] * beta[bin] + 2 * gamma[bin] * rr)) / gamma[bin];
2115 else if (beta[bin] != 0.)
2116 xx = rr / beta[bin];
2117 xp[i] = alpha[bin] + xx;
2118 } else {
2119 xp[i] = alpha[bin];
2120 if (integral[bin + 1] == r) xp[i] += dx;
2121 }
2122 }
2123
2124 return n;
2125}
2126////////////////////////////////////////////////////////////////////////////////
2127///
2128/// Compute the cumulative function at fNpx points between fXmin and fXmax.
2129/// Option can be used to force a log scale (option = "log"), linear (option = "lin") or automatic if empty.
2131
2132 fIntegral.resize(fNpx + 1);
2133 fAlpha.resize(fNpx + 1);
2134 fBeta.resize(fNpx);
2135 fGamma.resize(fNpx);
2136 fIntegral[0] = 0;
2137 fAlpha[fNpx] = 0;
2139 Int_t intNegative = 0;
2140 Int_t i;
2142 Double_t dx;
2145 TString opt(option);
2146 opt.ToUpper();
2147 // perform a log binning if specified by user (option="Log") or if some conditions are met
2148 // and the user explicitly does not specify a Linear binning option
2149 if (opt.Contains("LOG") || ((xmin > 0 && xmax / xmin > fNpx) && !opt.Contains("LIN"))) {
2150 logbin = kTRUE;
2151 fAlpha[fNpx] = 1;
2154 if (gDebug)
2155 Info("GetRandom", "Use log scale for tabulating the integral in [%f,%f] with %d points", fXmin, fXmax, fNpx);
2156 }
2157 dx = (xmax - xmin) / fNpx;
2158
2159 std::vector<Double_t> xx(fNpx + 1);
2160 for (i = 0; i < fNpx; i++) {
2161 xx[i] = xmin + i * dx;
2162 }
2163 xx[fNpx] = xmax;
2164 for (i = 0; i < fNpx; i++) {
2165 if (logbin) {
2166 integ = Integral(TMath::Power(10, xx[i]), TMath::Power(10, xx[i + 1]), 0.0);
2167 } else {
2168 integ = Integral(xx[i], xx[i + 1], 0.0);
2169 }
2170 if (integ < 0) {
2171 intNegative++;
2172 integ = -integ;
2173 }
2174 fIntegral[i + 1] = fIntegral[i] + integ;
2175 }
2176 if (intNegative > 0) {
2177 Warning("GetRandom", "function:%s has %d negative values: abs assumed", GetName(), intNegative);
2178 }
2179 if (fIntegral[fNpx] == 0) {
2180 Error("GetRandom", "Integral of function is zero");
2181 return kFALSE;
2182 }
2184 for (i = 1; i <= fNpx; i++) { // normalize integral to 1
2185 fIntegral[i] /= total;
2186 }
2187 // the integral r for each bin is approximated by a parabola
2188 // x = alpha + beta*r +gamma*r**2
2189 // compute the coefficients alpha, beta, gamma for each bin
2190 Double_t x0, r1, r2, r3;
2191 for (i = 0; i < fNpx; i++) {
2192 x0 = xx[i];
2193 r2 = fIntegral[i + 1] - fIntegral[i];
2194 if (logbin)
2195 r1 = Integral(TMath::Power(10, x0), TMath::Power(10, x0 + 0.5 * dx), 0.0) / total;
2196 else
2197 r1 = Integral(x0, x0 + 0.5 * dx, 0.0) / total;
2198 r3 = 2 * r2 - 4 * r1;
2199 if (TMath::Abs(r3) > 1e-8)
2200 fGamma[i] = r3 / (dx * dx);
2201 else
2202 fGamma[i] = 0;
2203 fBeta[i] = r2 / dx - fGamma[i] * dx;
2204 fAlpha[i] = x0;
2205 fGamma[i] *= 2;
2206 }
2207 return kTRUE;
2208}
2209
2210////////////////////////////////////////////////////////////////////////////////
2211/// Return a random number following this function shape.
2212///
2213/// @param rng Random number generator. By default (or when passing a nullptr) the global gRandom is used
2214/// @param option Option string which controls the binning used to compute the integral. Default mode is automatic depending of
2215/// xmax, xmin and Npx (function points).
2216/// Possible values are:
2217/// - "LOG" to force usage of log scale for tabulating the integral
2218/// - "LIN" to force usage of linear scale when tabulating the integral
2219///
2220/// The distribution contained in the function fname (TF1) is integrated
2221/// over the channel contents.
2222/// It is normalized to 1.
2223/// For each bin the integral is approximated by a parabola.
2224/// The parabola coefficients are stored as non persistent data members
2225/// Getting one random number implies:
2226/// - Generating a random number between 0 and 1 (say r1)
2227/// - Look in which bin in the normalized integral r1 corresponds to
2228/// - Evaluate the parabolic curve in the selected bin to find the corresponding X value.
2229///
2230/// The user can provide as optional parameter a Random number generator.
2231/// By default gRandom is used
2232///
2233/// If the ratio fXmax/fXmin > fNpx the integral is tabulated in log scale in x
2234/// A log scale for the intergral is also always used if a user specifies the "LOG" option
2235/// Instead if a user requestes a "LIN" option the integral binning is never done in log scale
2236/// whatever the fXmax/fXmin ratio is
2237///
2238/// Note that the parabolic approximation is very good as soon as the number of bins is greater than 50.
2239
2240
2242{
2243 // Check if integral array must be built
2244 if (fIntegral.empty()) {
2246 if (!ret) return TMath::QuietNaN();
2247 }
2248
2249
2250 // return random number
2251 Double_t r = (rng) ? rng->Rndm() : gRandom->Rndm();
2253 Double_t rr = r - fIntegral[bin];
2254
2255 Double_t yy;
2256 if (fGamma[bin] != 0)
2257 yy = (-fBeta[bin] + TMath::Sqrt(fBeta[bin] * fBeta[bin] + 2 * fGamma[bin] * rr)) / fGamma[bin];
2258 else
2259 yy = rr / fBeta[bin];
2260 Double_t x = fAlpha[bin] + yy;
2261 if (fAlpha[fNpx] > 0) return TMath::Power(10, x);
2262 return x;
2263}
2264
2265
2266////////////////////////////////////////////////////////////////////////////////
2267/// Return a random number following this function shape in [xmin,xmax]
2268///
2269/// The distribution contained in the function fname (TF1) is integrated
2270/// over the channel contents.
2271/// It is normalized to 1.
2272/// For each bin the integral is approximated by a parabola.
2273/// The parabola coefficients are stored as non persistent data members
2274/// Getting one random number implies:
2275/// - Generating a random number between 0 and 1 (say r1)
2276/// - Look in which bin in the normalized integral r1 corresponds to
2277/// - Evaluate the parabolic curve in the selected bin to find
2278/// the corresponding X value.
2279///
2280/// The parabolic approximation is very good as soon as the number
2281/// of bins is greater than 50.
2282///
2283/// @param xmin minimum value for generated random numbers
2284/// @param xmax maximum value for generated random numbers
2285/// @param rng (optional) random number generator pointer
2286/// @param option (optional) : `LOG` or `LIN` to force the usage of a log or linear scale for computing the cumulative integral table
2287///
2288/// IMPORTANT NOTE
2289///
2290/// The integral of the function is computed at fNpx points. If the function
2291/// has sharp peaks, you should increase the number of points (SetNpx)
2292/// such that the peak is correctly tabulated at several points.
2293
2295{
2296 // Check if integral array must be built
2297 if (fIntegral.empty()) {
2299 if (!ret) return TMath::QuietNaN();
2300 }
2301
2302 // return random number
2303 Double_t dx = (fXmax - fXmin) / fNpx;
2304 Int_t nbinmin = (Int_t)((xmin - fXmin) / dx);
2305 Int_t nbinmax = (Int_t)((xmax - fXmin) / dx) + 2;
2306 if (nbinmax > fNpx) nbinmax = fNpx;
2307
2310
2311 Double_t r, x, xx, rr;
2312 do {
2313 r = (rng) ? rng->Uniform(pmin, pmax) : gRandom->Uniform(pmin, pmax);
2314
2316 rr = r - fIntegral[bin];
2317
2318 if (fGamma[bin] != 0)
2319 xx = (-fBeta[bin] + TMath::Sqrt(fBeta[bin] * fBeta[bin] + 2 * fGamma[bin] * rr)) / fGamma[bin];
2320 else
2321 xx = rr / fBeta[bin];
2322 x = fAlpha[bin] + xx;
2323 } while (x < xmin || x > xmax);
2324 return x;
2325}
2326
2327////////////////////////////////////////////////////////////////////////////////
2328/// Return range of a generic N-D function.
2329
2331{
2332 int ndim = GetNdim();
2333
2334 double xmin = 0, ymin = 0, zmin = 0, xmax = 0, ymax = 0, zmax = 0;
2335 GetRange(xmin, ymin, zmin, xmax, ymax, zmax);
2336 for (int i = 0; i < ndim; ++i) {
2337 if (i == 0) {
2338 rmin[0] = xmin;
2339 rmax[0] = xmax;
2340 } else if (i == 1) {
2341 rmin[1] = ymin;
2342 rmax[1] = ymax;
2343 } else if (i == 2) {
2344 rmin[2] = zmin;
2345 rmax[2] = zmax;
2346 } else {
2347 rmin[i] = 0;
2348 rmax[i] = 0;
2349 }
2350 }
2351}
2352
2353
2354////////////////////////////////////////////////////////////////////////////////
2355/// Return range of a 1-D function.
2356
2358{
2359 xmin = fXmin;
2360 xmax = fXmax;
2361}
2362
2363
2364////////////////////////////////////////////////////////////////////////////////
2365/// Return range of a 2-D function.
2366
2368{
2369 xmin = fXmin;
2370 xmax = fXmax;
2371 ymin = 0;
2372 ymax = 0;
2373}
2374
2375
2376////////////////////////////////////////////////////////////////////////////////
2377/// Return range of function.
2378
2380{
2381 xmin = fXmin;
2382 xmax = fXmax;
2383 ymin = 0;
2384 ymax = 0;
2385 zmin = 0;
2386 zmax = 0;
2387}
2388
2389
2390////////////////////////////////////////////////////////////////////////////////
2391/// Get value corresponding to X in array of fSave values
2392
2394{
2395 if (fSave.empty()) return 0;
2396 //if (fSave == 0) return 0;
2397 int nsave = fSave.size();
2398 Double_t x = Double_t(xx[0]);
2399 Double_t y, dx, xmin, xmax, xlow, xup, ylow, yup;
2401 //if parent is a histogram the function had been saved at the center of the bins
2402 //we make a linear interpolation between the saved values
2403 xmin = fSave[nsave - 3];
2404 xmax = fSave[nsave - 2];
2405 if (fSave[nsave - 1] == xmax) {
2406 TH1 *h = (TH1 *)fParent;
2407 TAxis *xaxis = h->GetXaxis();
2408 Int_t bin1 = xaxis->FindBin(xmin);
2409 Int_t binup = xaxis->FindBin(xmax);
2410 Int_t bin = xaxis->FindBin(x);
2411 if (bin < binup) {
2412 xlow = xaxis->GetBinCenter(bin);
2413 xup = xaxis->GetBinCenter(bin + 1);
2414 ylow = fSave[bin - bin1];
2415 yup = fSave[bin - bin1 + 1];
2416 } else {
2417 xlow = xaxis->GetBinCenter(bin - 1);
2418 xup = xaxis->GetBinCenter(bin);
2419 ylow = fSave[bin - bin1 - 1];
2420 yup = fSave[bin - bin1];
2421 }
2422 dx = xup - xlow;
2423 y = ((xup * ylow - xlow * yup) + x * (yup - ylow)) / dx;
2424 return y;
2425 }
2426 }
2427 Int_t np = nsave - 3;
2428 xmin = fSave[np + 1];
2429 xmax = fSave[np + 2];
2430 dx = (xmax - xmin) / np;
2431 if (x < xmin || x > xmax) return 0;
2432 // return a Nan in case of x=nan, otherwise will crash later
2433 if (TMath::IsNaN(x)) return x;
2434 if (dx <= 0) return 0;
2435
2436 Int_t bin = TMath::Min(np - 1, Int_t((x - xmin) / dx));
2437 xlow = xmin + bin * dx;
2438 xup = xlow + dx;
2439 ylow = fSave[bin];
2440 yup = fSave[bin + 1];
2441 y = ((xup * ylow - xlow * yup) + x * (yup - ylow)) / dx;
2442 return y;
2443}
2444
2445
2446////////////////////////////////////////////////////////////////////////////////
2447/// Get x axis of the function.
2448
2450{
2451 TH1 *h = GetHistogram();
2452 if (!h) return nullptr;
2453 return h->GetXaxis();
2454}
2455
2456
2457////////////////////////////////////////////////////////////////////////////////
2458/// Get y axis of the function.
2459
2461{
2462 TH1 *h = GetHistogram();
2463 if (!h) return nullptr;
2464 return h->GetYaxis();
2465}
2466
2467
2468////////////////////////////////////////////////////////////////////////////////
2469/// Get z axis of the function. (In case this object is a TF2 or TF3)
2470
2472{
2473 TH1 *h = GetHistogram();
2474 if (!h) return nullptr;
2475 return h->GetZaxis();
2476}
2477
2478
2479
2480////////////////////////////////////////////////////////////////////////////////
2481/// Compute the gradient (derivative) wrt a parameter ipar
2482///
2483/// \param ipar index of parameter for which the derivative is computed
2484/// \param x point, where the derivative is computed
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
2495{
2496 return GradientParTempl<Double_t>(ipar, x, eps);
2497}
2498
2499////////////////////////////////////////////////////////////////////////////////
2500/// Compute the gradient wrt parameters
2501/// If the TF1 object is based on a formula expression (TFormula)
2502/// and TFormula::GenerateGradientPar() has been successfully called
2503/// automatic differentiation using CLAD is used instead of the default
2504/// numerical differentiation
2505///
2506/// \param x point, were the gradient is computed
2507/// \param grad used to return the computed gradient, assumed to be of at least fNpar size
2508/// \param eps if the errors of parameters have been computed, the step used in
2509/// numerical differentiation is eps*parameter_error.
2510///
2511/// if the errors have not been computed, step=eps is used
2512/// default value of eps = 0.01
2513/// Method is the same as in Derivative() function
2514///
2515/// If a parameter is fixed, the gradient on this parameter = 0
2516
2517void TF1::GradientPar(const Double_t *x, Double_t *grad, Double_t eps) const
2518{
2519 if (fFormula && fFormula->HasGeneratedGradient()) {
2520 // need to zero the gradient buffer
2521 std::fill(grad, grad + fNpar, 0.);
2522 fFormula->GradientPar(x,grad);
2523 }
2524 else
2525 GradientParTempl<Double_t>(x, grad, eps);
2526}
2527
2528////////////////////////////////////////////////////////////////////////////////
2529/// Initialize parameters addresses.
2530
2531void TF1::InitArgs(const Double_t *x, const Double_t *params)
2532{
2533 if (fMethodCall) {
2534 Longptr_t args[2];
2535 args[0] = (Longptr_t)x;
2536 if (params) args[1] = (Longptr_t)params;
2537 else args[1] = (Longptr_t)GetParameters();
2538 fMethodCall->SetParamPtrs(args);
2539 }
2540}
2541
2542
2543////////////////////////////////////////////////////////////////////////////////
2544/// Create the basic function objects
2545
2547{
2548 TF1 *f1;
2550 if (!gROOT->GetListOfFunctions()->FindObject("gaus")) {
2551 f1 = new TF1("gaus", "gaus", -1, 1);
2552 f1->SetParameters(1, 0, 1);
2553 f1 = new TF1("gausn", "gausn", -1, 1);
2554 f1->SetParameters(1, 0, 1);
2555 f1 = new TF1("landau", "landau", -1, 1);
2556 f1->SetParameters(1, 0, 1);
2557 f1 = new TF1("landaun", "landaun", -1, 1);
2558 f1->SetParameters(1, 0, 1);
2559 f1 = new TF1("expo", "expo", -1, 1);
2560 f1->SetParameters(1, 1);
2561 for (Int_t i = 0; i < 10; i++) {
2562 auto f1name = TString::Format("pol%d", i);
2563 f1 = new TF1(f1name.Data(), f1name.Data(), -1, 1);
2564 f1->SetParameters(1, 1, 1, 1, 1, 1, 1, 1, 1, 1);
2565 // create also chebyshev polynomial
2566 // (note polynomial object will not be deleted)
2567 // note that these functions cannot be stored
2569 Double_t min = -1;
2570 Double_t max = 1;
2571 f1 = new TF1(TString::Format("chebyshev%d", i), pol, min, max, i + 1, 1);
2572 f1->SetParameters(1, 1, 1, 1, 1, 1, 1, 1, 1, 1);
2573 }
2574
2575 }
2576}
2577
2578////////////////////////////////////////////////////////////////////////////////
2579/// IntegralOneDim or analytical integral
2580
2582{
2583 Double_t error = 0;
2584 if (GetNumber() > 0) {
2585 Double_t result = 0.;
2586 if (gDebug) {
2587 Info("computing analytical integral for function %s with number %d", GetName(), GetNumber());
2588 }
2589 result = AnalyticalIntegral(this, a, b);
2590 // if it is a formula that havent been implemented in analytical integral a NaN is return
2591 if (!TMath::IsNaN(result)) return result;
2592 if (gDebug)
2593 Warning("analytical integral not available for %s - with number %d compute numerical integral", GetName(), GetNumber());
2594 }
2595 return IntegralOneDim(a, b, epsrel, epsrel, error);
2596}
2597
2598////////////////////////////////////////////////////////////////////////////////
2599/// Return Integral of function between a and b using the given parameter values and
2600/// relative and absolute tolerance.
2601///
2602/// The default integrator defined in ROOT::Math::IntegratorOneDimOptions::DefaultIntegrator() is used
2603/// If ROOT contains the MathMore library the default integrator is set to be
2604/// the adaptive ROOT::Math::GSLIntegrator (based on QUADPACK) or otherwise the
2605/// ROOT::Math::GaussIntegrator is used
2606/// See the reference documentation of these classes for more information about the
2607/// integration algorithms
2608/// To change integration algorithm just do :
2609/// ROOT::Math::IntegratorOneDimOptions::SetDefaultIntegrator(IntegratorName);
2610/// Valid integrator names are:
2611/// - Gauss : for ROOT::Math::GaussIntegrator
2612/// - GaussLegendre : for ROOT::Math::GaussLegendreIntegrator
2613/// - Adaptive : for ROOT::Math::GSLIntegrator adaptive method (QAG)
2614/// - AdaptiveSingular : for ROOT::Math::GSLIntegrator adaptive singular method (QAGS)
2615/// - NonAdaptive : for ROOT::Math::GSLIntegrator non adaptive (QNG)
2616///
2617/// In order to use the GSL integrators one needs to have the MathMore library installed
2618///
2619/// Note 1:
2620///
2621/// Values of the function f(x) at the interval end-points A and B are not
2622/// required. The subprogram may therefore be used when these values are
2623/// undefined.
2624///
2625/// Note 2:
2626///
2627/// Instead of TF1::Integral, you may want to use the combination of
2628/// TF1::CalcGaussLegendreSamplingPoints and TF1::IntegralFast.
2629/// See an example with the following script:
2630///
2631/// ~~~ {.cpp}
2632/// void gint() {
2633/// TF1 *g = new TF1("g","gaus",-5,5);
2634/// g->SetParameters(1,0,1);
2635/// //default gaus integration method uses 6 points
2636/// //not suitable to integrate on a large domain
2637/// double r1 = g->Integral(0,5);
2638/// double r2 = g->Integral(0,1000);
2639///
2640/// //try with user directives computing more points
2641/// Int_t np = 1000;
2642/// double *x=new double[np];
2643/// double *w=new double[np];
2644/// g->CalcGaussLegendreSamplingPoints(np,x,w,1e-15);
2645/// double r3 = g->IntegralFast(np,x,w,0,5);
2646/// double r4 = g->IntegralFast(np,x,w,0,1000);
2647/// double r5 = g->IntegralFast(np,x,w,0,10000);
2648/// double r6 = g->IntegralFast(np,x,w,0,100000);
2649/// printf("g->Integral(0,5) = %g\n",r1);
2650/// printf("g->Integral(0,1000) = %g\n",r2);
2651/// printf("g->IntegralFast(n,x,w,0,5) = %g\n",r3);
2652/// printf("g->IntegralFast(n,x,w,0,1000) = %g\n",r4);
2653/// printf("g->IntegralFast(n,x,w,0,10000) = %g\n",r5);
2654/// printf("g->IntegralFast(n,x,w,0,100000)= %g\n",r6);
2655/// delete [] x;
2656/// delete [] w;
2657/// }
2658/// ~~~
2659///
2660/// This example produces the following results:
2661///
2662/// ~~~ {.cpp}
2663/// g->Integral(0,5) = 1.25331
2664/// g->Integral(0,1000) = 1.25319
2665/// g->IntegralFast(n,x,w,0,5) = 1.25331
2666/// g->IntegralFast(n,x,w,0,1000) = 1.25331
2667/// g->IntegralFast(n,x,w,0,10000) = 1.25331
2668/// g->IntegralFast(n,x,w,0,100000)= 1.253
2669/// ~~~
2670
2672{
2673 //Double_t *parameters = GetParameters();
2674 TF1_EvalWrapper wf1(this, nullptr, fgAbsValue);
2675 Double_t result = 0;
2676 Int_t status = 0;
2681 iod.SetFunction(wf1);
2682 if (a != - TMath::Infinity() && b != TMath::Infinity())
2683 result = iod.Integral(a, b);
2684 else if (a == - TMath::Infinity() && b != TMath::Infinity())
2685 result = iod.IntegralLow(b);
2686 else if (a != - TMath::Infinity() && b == TMath::Infinity())
2687 result = iod.IntegralUp(a);
2688 else if (a == - TMath::Infinity() && b == TMath::Infinity())
2689 result = iod.Integral();
2690 error = iod.Error();
2691 status = iod.Status();
2692 } else {
2694 if (a != - TMath::Infinity() && b != TMath::Infinity())
2695 result = iod.Integral(a, b);
2696 else if (a == - TMath::Infinity() && b != TMath::Infinity())
2697 result = iod.IntegralLow(b);
2698 else if (a != - TMath::Infinity() && b == TMath::Infinity())
2699 result = iod.IntegralUp(a);
2700 else if (a == - TMath::Infinity() && b == TMath::Infinity())
2701 result = iod.Integral();
2702 error = iod.Error();
2703 status = iod.Status();
2704 }
2705 if (status != 0) {
2707 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);
2708 TString msg("\t\tFunction Parameters = {");
2709 for (int ipar = 0; ipar < GetNpar(); ++ipar) {
2710 msg += TString::Format(" %s = %f ", GetParName(ipar), GetParameter(ipar));
2711 if (ipar < GetNpar() - 1) msg += TString(",");
2712 else msg += TString("}");
2713 }
2714 Info("IntegralOneDim", "%s", msg.Data());
2715 }
2716 return result;
2717}
2718
2719////////////////////////////////////////////////////////////////////////////////
2720/// Return Error on Integral of a parametric function between a and b
2721/// due to the parameter uncertainties and their covariance matrix from the fit.
2722/// In addition to the integral limits, this method takes as input a pointer to the fitted parameter values
2723/// and a pointer the covariance matrix from the fit. These pointers should be retrieved from the
2724/// previously performed fit using the TFitResult class.
2725/// Note that to get the TFitResult, te fit should be done using the fit option `S`.
2726/// Example:
2727/// ~~~~{.cpp}
2728/// TFitResultPtr r = histo->Fit(func, "S");
2729/// func->IntegralError(x1,x2,r->GetParams(), r->GetCovarianceMatrix()->GetMatrixArray() );
2730/// ~~~~
2731///
2732/// IMPORTANT NOTE1:
2733///
2734/// A null pointer to the parameter values vector and to the covariance matrix can be passed.
2735/// In this case, when the parameter values pointer is null, the parameter values stored in this
2736/// TF1 function object are used in the integral error computation.
2737/// When the poassed pointer to the covariance matrix is null, a covariance matrix from the last fit is retrieved
2738/// from a global fitter instance when it exists. Note that the global fitter instance
2739/// esists only when ROOT is not running with multi-threading enabled (ROOT::IsImplicitMTEnabled() == True).
2740/// When the ovariance matrix from the last fit cannot be retrieved, an error message is printed and a zero value is
2741/// returned.
2742///
2743///
2744/// IMPORTANT NOTE2:
2745///
2746/// When no covariance matrix is passed and in the meantime a fit is done
2747/// using another function, the routine will signal an error and it will return zero only
2748/// when the number of fit parameter is different than the values stored in TF1 (TF1::GetNpar() ).
2749/// In the case that npar is the same, an incorrect result is returned.
2750///
2751/// IMPORTANT NOTE3:
2752///
2753/// The user must pass a pointer to the elements of the full covariance matrix
2754/// dimensioned with the right size (npar*npar), where npar is the total number of parameters (TF1::GetNpar()),
2755/// including also the fixed parameters. The covariance matrix must be retrieved from the TFitResult class as
2756/// shown above and not from TVirtualFitter::GetCovarianceMatrix() function.
2757
2759{
2760 Double_t x1[1];
2761 Double_t x2[1];
2762 x1[0] = a, x2[0] = b;
2763 return ROOT::TF1Helper::IntegralError(this, 1, x1, x2, params, covmat, epsilon);
2764}
2765
2766////////////////////////////////////////////////////////////////////////////////
2767/// Return Error on Integral of a parametric function with dimension larger than one
2768/// between a[] and b[] due to the parameters uncertainties.
2769/// For a TF1 with dimension larger than 1 (for example a TF2 or TF3)
2770/// TF1::IntegralMultiple is used for the integral calculation
2771///
2772/// In addition to the integral limits, this method takes as input a pointer to the fitted parameter values
2773/// and a pointer the covariance matrix from the fit. These pointers should be retrieved from the
2774/// previously performed fit using the TFitResult class.
2775/// Note that to get the TFitResult, te fit should be done using the fit option `S`.
2776/// Example:
2777/// ~~~~{.cpp}
2778/// TFitResultPtr r = histo2d->Fit(func2, "S");
2779/// func2->IntegralError(a,b,r->GetParams(), r->GetCovarianceMatrix()->GetMatrixArray() );
2780/// ~~~~
2781///
2782/// IMPORTANT NOTE1:
2783///
2784/// A null pointer to the parameter values vector and to the covariance matrix can be passed.
2785/// In this case, when the parameter values pointer is null, the parameter values stored in this
2786/// TF1 function object are used in the integral error computation.
2787/// When the poassed pointer to the covariance matrix is null, a covariance matrix from the last fit is retrieved
2788/// from a global fitter instance when it exists. Note that the global fitter instance
2789/// esists only when ROOT is not running with multi-threading enabled (ROOT::IsImplicitMTEnabled() == True).
2790/// When the ovariance matrix from the last fit cannot be retrieved, an error message is printed and a zero value is
2791/// returned.
2792///
2793///
2794/// IMPORTANT NOTE2:
2795///
2796/// When no covariance matrix is passed and in the meantime a fit is done
2797/// using another function, the routine will signal an error and it will return zero only
2798/// when the number of fit parameter is different than the values stored in TF1 (TF1::GetNpar() ).
2799/// In the case that npar is the same, an incorrect result is returned.
2800///
2801/// IMPORTANT NOTE3:
2802///
2803/// The user must pass a pointer to the elements of the full covariance matrix
2804/// dimensioned with the right size (npar*npar), where npar is the total number of parameters (TF1::GetNpar()),
2805/// including also the fixed parameters. The covariance matrix must be retrieved from the TFitResult class as
2806/// shown above and not from TVirtualFitter::GetCovarianceMatrix() function.
2807
2808Double_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)
2809{
2810 return ROOT::TF1Helper::IntegralError(this, n, a, b, params, covmat, epsilon);
2811}
2812
2813#ifdef INTHEFUTURE
2814////////////////////////////////////////////////////////////////////////////////
2815/// Gauss-Legendre integral, see CalcGaussLegendreSamplingPoints
2816
2818{
2819 if (!g) return 0;
2820 return IntegralFast(g->GetN(), g->GetX(), g->GetY(), a, b, params);
2821}
2822#endif
2823
2824
2825////////////////////////////////////////////////////////////////////////////////
2826/// Gauss-Legendre integral, see CalcGaussLegendreSamplingPoints
2827
2828Double_t TF1::IntegralFast(Int_t num, Double_t * /* x */, Double_t * /* w */, Double_t a, Double_t b, Double_t *params, Double_t epsilon)
2829{
2830 // Now x and w are not used!
2831
2833 if (params)
2834 wf1.SetParameters(params);
2836 gli.SetFunction(wf1);
2837 return gli.Integral(a, b);
2838
2839}
2840
2841
2842////////////////////////////////////////////////////////////////////////////////
2843/// See more general prototype below.
2844/// This interface kept for back compatibility
2845/// It is recommended to use the other interface where one can specify also epsabs and the maximum number of
2846/// points
2847
2849{
2853 if (ifail > 0) {
2854 Warning("IntegralMultiple", "failed code=%d, ", ifail);
2855 }
2856 return result;
2857}
2858
2859
2860////////////////////////////////////////////////////////////////////////////////
2861/// This function computes, to an attempted specified accuracy, the value of
2862/// the integral
2863///
2864/// \param[in] n Number of dimensions [2,15]
2865/// \param[in] a,b One-dimensional arrays of length >= N . On entry A[i], and B[i],
2866/// contain the lower and upper limits of integration, respectively.
2867/// \param[in] maxpts Maximum number of function evaluations to be allowed.
2868/// maxpts >= 2^n +2*n*(n+1) +1
2869/// if maxpts<minpts, maxpts is set to 10*minpts
2870/// \param[in] epsrel Specified relative accuracy.
2871/// \param[in] epsabs Specified absolute accuracy.
2872/// The integration algorithm will attempt to reach either the relative or the absolute accuracy.
2873/// In case the maximum function called is reached the algorithm will stop earlier without having reached
2874/// the desired accuracy
2875///
2876/// \param[out] relerr Contains, on exit, an estimation of the relative accuracy of the result.
2877/// \param[out] nfnevl number of function evaluations performed.
2878/// \param[out] ifail
2879/// \parblock
2880/// 0 Normal exit. At least minpts and at most maxpts calls to the function were performed.
2881///
2882/// 1 maxpts is too small for the specified accuracy eps. The result and relerr contain the values obtainable for the
2883/// specified value of maxpts.
2884///
2885/// 3 n<2 or n>15
2886/// \endparblock
2887///
2888/// Method:
2889///
2890/// The default method used is the Genz-Mallik adaptive multidimensional algorithm
2891/// using the class ROOT::Math::AdaptiveIntegratorMultiDim (see the reference documentation of the class)
2892///
2893/// Other methods can be used by setting ROOT::Math::IntegratorMultiDimOptions::SetDefaultIntegrator()
2894/// to different integrators.
2895/// Other possible integrators are MC integrators based on the ROOT::Math::GSLMCIntegrator class
2896/// Possible methods are : Vegas, Miser or Plain
2897/// IN case of MC integration the accuracy is determined by the number of function calls, one should be
2898/// careful not to use a too large value of maxpts
2899///
2900
2902{
2904
2905 double result = 0;
2910 //aimd.SetMinPts(minpts); // use default minpts ( n^2 + 2 * n * (n+1) +1 )
2911 result = aimd.Integral(a, b);
2912 relerr = aimd.RelError();
2913 nfnevl = aimd.NEval();
2914 ifail = aimd.Status();
2915 } else {
2916 // use default abs tolerance = relative tolerance
2918 result = imd.Integral(a, b);
2919 relerr = (result != 0) ? imd.Error() / std::abs(result) : imd.Error();
2920 nfnevl = 0;
2921 ifail = imd.Status();
2922 }
2923
2924
2925 return result;
2926}
2927
2928
2929////////////////////////////////////////////////////////////////////////////////
2930/// Return kTRUE if the function is valid
2931
2933{
2934 if (fFormula) return fFormula->IsValid();
2935 if (fMethodCall) return fMethodCall->IsValid();
2936 // function built on compiled functors are always valid by definition
2937 // (checked at compiled time)
2938 // invalid is a TF1 where the functor is null pointer and has not been saved
2939 if (!fFunctor && fSave.empty()) return kFALSE;
2940 return kTRUE;
2941}
2942
2943
2944//______________________________________________________________________________
2945
2946
2948{
2949 if (fType == EFType::kFormula) {
2950 printf("Formula based function: %s \n", GetName());
2952 fFormula->Print(option);
2953 } else if (fType > 0) {
2955 printf("Interpreted based function: %s(double *x, double *p). Ndim = %d, Npar = %d \n", GetName(), GetNdim(),
2956 GetNpar());
2957 else if (fType == EFType::kCompositionFcn) {
2958 printf("Composition based function: %s. Ndim = %d, Npar = %d \n", GetName(), GetNdim(), GetNpar());
2959 if (!fComposition)
2960 printf("fComposition not found!\n"); // this would be bad
2961 } else {
2962 if (fFunctor)
2963 printf("Compiled based function: %s based on a functor object. Ndim = %d, Npar = %d\n", GetName(),
2964 GetNdim(), GetNpar());
2965 else {
2966 printf("Function based on a list of points from a compiled based function: %s. Ndim = %d, Npar = %d, Npx "
2967 "= %zu\n",
2968 GetName(), GetNdim(), GetNpar(), fSave.size());
2969 if (fSave.empty())
2970 Warning("Print", "Function %s is based on a list of points but list is empty", GetName());
2971 }
2972 }
2973 TString opt(option);
2974 opt.ToUpper();
2975 if (opt.Contains("V")) {
2976 // print list of parameters
2977 if (fNpar > 0) {
2978 printf("List of Parameters: \n");
2979 for (int i = 0; i < fNpar; ++i)
2980 printf(" %20s = %10f \n", GetParName(i), GetParameter(i));
2981 }
2982 if (!fSave.empty()) {
2983 // print list of saved points
2984 printf("List of Saved points (N=%d): \n", int(fSave.size()));
2985 for (auto &x : fSave)
2986 printf("( %10f ) ", x);
2987 printf("\n");
2988 }
2989 }
2990 }
2991 if (fHistogram) {
2992 printf("Contained histogram\n");
2994 }
2995}
2996
2997////////////////////////////////////////////////////////////////////////////////
2998/// Paint this function with its current attributes.
2999/// The function is going to be converted in an histogram and the corresponding
3000/// histogram is painted.
3001/// The painted histogram can be retrieved calling afterwards the method TF1::GetHistogram()
3002
3004{
3005 fgCurrent = this;
3006
3007 TString opt0 = option, opt = option, optSAME;
3008 opt.ToLower();
3009
3010 if (opt.Contains("sames"))
3011 optSAME = "sames";
3012 else if (opt.Contains("same"))
3013 optSAME = "same";
3014 if (optSAME.Length())
3015 opt.ReplaceAll(optSAME, "");
3016 opt.ReplaceAll(' ', "");
3017
3019 if (gPad) {
3020 pmin = gPad->PadtoX(gPad->GetUxmin());
3021 pmax = gPad->PadtoX(gPad->GetUxmax());
3022 }
3023 if (optSAME.Length()) {
3024 // Completely outside
3025 if (xmax < pmin) return;
3026 if (xmin > pmax) return;
3027 }
3028
3029 // create an histogram using the function content (re-use it if already existing)
3031
3032 auto is_pfc = opt0.Index("PFC"); // Automatic Fill Color
3033 auto is_plc = opt0.Index("PLC"); // Automatic Line Color
3034 auto is_pmc = opt0.Index("PMC"); // Automatic Marker Color
3035 if (is_pfc != kNPOS || is_plc != kNPOS || is_pmc != kNPOS) {
3036 Int_t i = gPad->NextPaletteColor();
3037 if (is_pfc != kNPOS) { opt0.Replace(is_pfc, 3, " "); fHistogram->SetFillColor(i); }
3038 if (is_plc != kNPOS) { opt0.Replace(is_plc, 3, " "); fHistogram->SetLineColor(i); }
3039 if (is_pmc != kNPOS) { opt0.Replace(is_pmc, 3, " "); fHistogram->SetMarkerColor(i); }
3040 }
3041
3042 // set the optimal minimum and maximum
3045 if (minimum <= 0 && gPad && gPad->GetLogy()) minimum = -1111; // This can happen when switching from lin to log scale.
3046 if (gPad && gPad->GetUymin() < fHistogram->GetMinimum() &&
3047 !fHistogram->TestBit(TH1::kIsZoomed)) minimum = -1111; // This can happen after unzooming a fit.
3048 if (minimum == -1111) { // This can happen after unzooming.
3051 } else {
3052 minimum = fMinimum;
3053 // Optimize the computation of the scale in Y in case the min/max of the
3054 // function oscillate around a constant value
3055 if (minimum == -1111) {
3056 Double_t hmin;
3057 if (optSAME.Length() && gPad) hmin = gPad->GetUymin();
3058 else hmin = fHistogram->GetMinimum();
3059 if (hmin > 0) {
3060 Double_t hmax;
3062 if (optSAME.Length() && gPad) hmax = gPad->GetUymax();
3063 else hmax = fHistogram->GetMaximum();
3064 hmin -= 0.05 * (hmax - hmin);
3065 if (hmin < 0) hmin = 0;
3067 minimum = hmin;
3068 }
3069 }
3070 }
3072 }
3073 if (maximum == -1111) {
3076 } else {
3077 maximum = fMaximum;
3078 }
3080 }
3081
3082 // Draw the histogram.
3083 if (!gPad) return;
3084 if (opt.Length() == 0) {
3085 optSAME.Prepend("lf");
3086 fHistogram->Paint(optSAME.Data());
3087 } else {
3088 fHistogram->Paint(opt0.Data());
3089 }
3090}
3091
3092////////////////////////////////////////////////////////////////////////////////
3093/// Create histogram with bin content equal to function value
3094/// computed at the bin center
3095/// This histogram will be used to paint the function
3096/// A re-creation is forced and a new histogram is done if recreate=true
3097
3099{
3100 Int_t i;
3101 Double_t xv[1];
3102
3103 TH1 *histogram = nullptr;
3104
3105
3106 // Create a temporary histogram and fill each channel with the function value
3107 // Preserve axis titles
3108 TString xtitle = "";
3109 TString ytitle = "";
3110 char *semicol = (char *)strstr(GetTitle(), ";");
3111 if (semicol) {
3113 char *ctemp = new char[nxt];
3114 strlcpy(ctemp, semicol + 1, nxt);
3115 semicol = (char *)strstr(ctemp, ";");
3116 if (semicol) {
3117 *semicol = 0;
3118 ytitle = semicol + 1;
3119 }
3120 xtitle = ctemp;
3121 delete [] ctemp;
3122 }
3123 if (fHistogram) {
3124 // delete previous histograms if were done if done in different mode
3128 if (!gPad->GetLogx() && test_logx) {
3129 delete fHistogram;
3130 fHistogram = nullptr;
3131 recreate = kTRUE;
3132 }
3133 if (gPad->GetLogx() && !test_logx) {
3134 delete fHistogram;
3135 fHistogram = nullptr;
3136 recreate = kTRUE;
3137 }
3138 }
3139
3140 if (fHistogram && !recreate) {
3143 } else {
3144 // If logx, we must bin in logx and not in x
3145 // otherwise in case of several decades, one gets wrong results.
3146 if (xmin > 0 && gPad && gPad->GetLogx()) {
3147 Double_t *xbins = new Double_t[fNpx + 1];
3151 for (i = 0; i <= fNpx; i++) {
3152 xbins[i] = gPad->PadtoX(xlogmin + i * dlogx);
3153 }
3154 histogram = new TH1D("Func", GetTitle(), fNpx, xbins);
3155 histogram->SetBit(TH1::kLogX);
3156 delete [] xbins;
3157 } else {
3158 histogram = new TH1D("Func", GetTitle(), fNpx, xmin, xmax);
3159 }
3160 if (fMinimum != -1111) histogram->SetMinimum(fMinimum);
3161 if (fMaximum != -1111) histogram->SetMaximum(fMaximum);
3162 histogram->SetDirectory(nullptr);
3163 }
3165
3166 // Restore axis titles.
3167 histogram->GetXaxis()->SetTitle(xtitle.Data());
3168 histogram->GetYaxis()->SetTitle(ytitle.Data());
3169 Double_t *parameters = GetParameters();
3170
3171 InitArgs(xv, parameters);
3172 for (i = 1; i <= fNpx; i++) {
3173 xv[0] = histogram->GetBinCenter(i);
3174 histogram->SetBinContent(i, EvalPar(xv, parameters));
3175 }
3176
3177 // Copy Function attributes to histogram attributes.
3178 histogram->SetBit(TH1::kNoStats);
3179 histogram->Sumw2(kFALSE);
3180 histogram->SetLineColor(GetLineColor());
3181 histogram->SetLineStyle(GetLineStyle());
3182 histogram->SetLineWidth(GetLineWidth());
3183 histogram->SetFillColor(GetFillColor());
3184 histogram->SetFillStyle(GetFillStyle());
3185 histogram->SetMarkerColor(GetMarkerColor());
3186 histogram->SetMarkerStyle(GetMarkerStyle());
3187 histogram->SetMarkerSize(GetMarkerSize());
3188
3189 // update saved histogram in case it was deleted or if it is the first time the method is called
3190 // for example when called from TF1::GetHistogram()
3192 return histogram;
3193
3194}
3195
3196
3197////////////////////////////////////////////////////////////////////////////////
3198/// Release parameter number ipar during a fit operation.
3199/// After releasing it, the parameter
3200/// can vary freely in the fit. The parameter limits are reset to 0,0.
3201
3203{
3204 if (ipar < 0 || ipar > GetNpar() - 1) return;
3205 SetParLimits(ipar, 0, 0);
3206}
3207
3208
3209////////////////////////////////////////////////////////////////////////////////
3210/// Save values of function in array fSave
3211
3213{
3214 if (!fSave.empty())
3215 fSave.clear();
3216
3217 Double_t *parameters = GetParameters();
3218 //if (fSave != 0) {delete [] fSave; fSave = 0;}
3220 //if parent is a histogram save the function at the center of the bins
3221 if ((xmin > 0 && xmax > 0) && TMath::Abs(TMath::Log10(xmax / xmin) > TMath::Log10(fNpx))) {
3222 TH1 *h = (TH1 *)fParent;
3223 Int_t bin1 = h->GetXaxis()->FindBin(xmin);
3224 Int_t bin2 = h->GetXaxis()->FindBin(xmax);
3225 int nsave = bin2 - bin1 + 4;
3226 fSave.resize(nsave);
3227 Double_t xv[1];
3228
3229 InitArgs(xv, parameters);
3230 for (Int_t i = bin1; i <= bin2; i++) {
3231 xv[0] = h->GetXaxis()->GetBinCenter(i);
3232 fSave[i - bin1] = EvalPar(xv, parameters);
3233 }
3234 fSave[nsave - 3] = xmin;
3235 fSave[nsave - 2] = xmax;
3236 fSave[nsave - 1] = xmax;
3237 return;
3238 }
3239 }
3240
3241 Int_t npx = fNpx;
3242 if (npx <= 0)
3243 return;
3244
3245 Double_t dx = (xmax - xmin) / fNpx;
3246 if (dx <= 0) {
3247 dx = (fXmax - fXmin) / fNpx;
3248 npx--;
3249 xmin = fXmin + 0.5 * dx;
3250 xmax = fXmax - 0.5 * dx;
3251 }
3252 if (npx <= 0)
3253 return;
3254 fSave.resize(npx + 3);
3255 Double_t xv[1];
3256 InitArgs(xv, parameters);
3257 for (Int_t i = 0; i <= npx; i++) {
3258 xv[0] = xmin + dx * i;
3259 fSave[i] = EvalPar(xv, parameters);
3260 }
3261 fSave[npx + 1] = xmin;
3262 fSave[npx + 2] = xmax;
3263}
3264
3265
3266////////////////////////////////////////////////////////////////////////////////
3267/// Provide variable name for function for saving as primitive
3268/// When TH1 or TGraph stores list of functions, it applies special coding of created variable names
3269
3271{
3272 thread_local Int_t storeNumber = 0;
3273 TString funcName = GetName();
3274 const char *l = strstr(option, "#");
3275 Int_t number = ++storeNumber;
3276 if (l != nullptr)
3277 sscanf(l + 1, "%d", &number);
3278
3279 funcName += number;
3280 return gInterpreter->MapCppName(funcName);
3281}
3282
3283
3284////////////////////////////////////////////////////////////////////////////////
3285/// Save primitive as a C++ statement(s) on output stream out
3286
3287void TF1::SavePrimitive(std::ostream &out, Option_t *option /*= ""*/)
3288{
3289 // Save the function as C code independent from ROOT.
3290 if (option && strstr(option, "cc")) {
3291 out << "double " << GetName() << "(double xv) {\n";
3292 Double_t dx = (fXmax - fXmin) / (fNpx - 1);
3293 out << " double x[" << fNpx << "] = {\n";
3294 out << " ";
3295 Int_t n = 0;
3296 for (Int_t i = 0; i < fNpx; i++) {
3297 out << fXmin + dx * i;
3298 if (i < fNpx - 1)
3299 out << ", ";
3300 if (n++ == 10) {
3301 out << "\n ";
3302 n = 0;
3303 }
3304 }
3305 out << "\n";
3306 out << " };\n";
3307 out << " double y[" << fNpx << "] = {\n";
3308 out << " ";
3309 n = 0;
3310 for (Int_t i = 0; i < fNpx; i++) {
3311 out << Eval(fXmin + dx * i);
3312 if (i < fNpx - 1)
3313 out << ", ";
3314 if (n++ == 10) {
3315 out << "\n ";
3316 n = 0;
3317 }
3318 }
3319 out << "\n";
3320 out << " };\n";
3321 out << " if (xv<x[0]) return y[0];\n";
3322 out << " if (xv>x[" << fNpx - 1 << "]) return y[" << fNpx - 1 << "];\n";
3323 out << " int i, j=0;\n";
3324 out << " for (i=1; i<" << fNpx << "; i++) { if (xv < x[i]) break; j++; }\n";
3325 out << " return y[j] + (y[j + 1] - y[j]) / (x[j + 1] - x[j]) * (xv - x[j]);\n";
3326 out << "}\n";
3327 return;
3328 }
3329
3331
3332 const char *addToGlobList = fParent ? ", TF1::EAddToList::kNo" : ", TF1::EAddToList::kDefault";
3333
3334 out << " \n";
3335 if (!fType) {
3336 out << " TF1 *" << f1Name << " = new TF1(\"" << GetName() << "\", \""
3337 << TString(GetTitle()).ReplaceSpecialCppChars() << "\", " << fXmin << "," << fXmax << addToGlobList << ");\n";
3338 if (fNpx != 100)
3339 out << " " << f1Name << "->SetNpx(" << fNpx << ");\n";
3340 } else {
3341 out << " TF1 *" << f1Name << " = new TF1(\"" << "*" << GetName() << "\", " << fXmin << "," << fXmax
3342 << "," << GetNpar() << ");\n";
3343 out << " // The original function : " << GetTitle() << " had originally been created by:\n";
3344 out << " // TF1 *" << GetName() << " = new TF1(\"" << GetName() << "\", \"" << GetTitle() << "\", "
3345 << fXmin << "," << fXmax << "," << GetNpar() << ", 1" << addToGlobList << ");\n";
3346 out << " " << f1Name << "->SetRange(" << fXmin << "," << fXmax << ");\n";
3348 if (fNpx != 100)
3349 out << " " << f1Name << "->SetNpx(" << fNpx << ");\n";
3350
3352 if (fSave.empty() && (fType != EFType::kCompositionFcn)) {
3353 saved = kTRUE;
3354 Save(fXmin, fXmax, 0, 0, 0, 0);
3355 }
3356 if (!fSave.empty()) {
3357 TString vect = SavePrimitiveVector(out, f1Name, fSave.size(), fSave.data());
3358 out << " for (int n = 0; n < " << fSave.size() << "; n++)\n";
3359 out << " " << f1Name << "->SetSavedPoint(n, " << vect << "[n]);\n";
3360 }
3361
3362 if (saved)
3363 fSave.clear();
3364 }
3365
3366 if (TestBit(kNotDraw))
3367 out << " " << f1Name.Data() << "->SetBit(TF1::kNotDraw);\n";
3368
3369 SaveFillAttributes(out, f1Name, -1, 0);
3370 SaveMarkerAttributes(out, f1Name, -1, -1, -1);
3371 SaveLineAttributes(out, f1Name, -1, -1, -1);
3372
3373 if (GetChisquare() != 0) {
3374 out << " " << f1Name << "->SetChisquare(" << GetChisquare() << ");\n";
3375 out << " " << f1Name << "->SetNDF(" << GetNDF() << ");\n";
3376 }
3377
3379 for (Int_t i = 0; i < GetNpar(); i++) {
3380 out << " " << f1Name << "->SetParameter(" << i << ", " << GetParameter(i) << ");\n";
3381 out << " " << f1Name << "->SetParError(" << i << ", " << GetParError(i) << ");\n";
3383 out << " " << f1Name << "->SetParLimits(" << i << ", " << parmin << ", " << parmax << ");\n";
3384 }
3385
3386 if (fHistogram && !strstr(option, "same")) {
3387 GetXaxis()->SaveAttributes(out, f1Name, "->GetXaxis()");
3388 GetYaxis()->SaveAttributes(out, f1Name, "->GetYaxis()");
3389 }
3390
3392}
3393
3394////////////////////////////////////////////////////////////////////////////////
3395/// Static function setting the current function.
3396/// the current function may be accessed in static C-like functions
3397/// when fitting or painting a function.
3398
3400{
3401 fgCurrent = f1;
3402}
3403
3404////////////////////////////////////////////////////////////////////////////////
3405/// Set the result from the fit
3406/// parameter values, errors, chi2, etc...
3407/// Optionally a pointer to a vector (with size fNpar) of the parameter indices in the FitResult can be passed
3408/// This is useful in the case of a combined fit with different functions, and the FitResult contains the global result
3409/// By default it is assume that indpar = {0,1,2,....,fNpar-1}.
3410
3412{
3413 Int_t npar = GetNpar();
3414 if (result.IsEmpty()) {
3415 Warning("SetFitResult", "Empty Fit result - nothing is set in TF1");
3416 return;
3417 }
3418 if (indpar == nullptr && npar != (int) result.NPar()) {
3419 Error("SetFitResult", "Invalid Fit result passed - number of parameter is %d , different than TF1::GetNpar() = %d", npar, result.NPar());
3420 return;
3421 }
3422 if (result.Chi2() > 0)
3423 SetChisquare(result.Chi2());
3424 else
3425 SetChisquare(result.MinFcnValue());
3426
3427 SetNDF(result.Ndf());
3428 SetNumberFitPoints(result.Ndf() + result.NFreeParameters());
3429
3430
3431 for (Int_t i = 0; i < npar; ++i) {
3432 Int_t ipar = (indpar != nullptr) ? indpar[i] : i;
3433 if (ipar < 0) continue;
3434 GetParameters()[i] = result.Parameter(ipar);
3435 // in case errors are not present do not set them
3436 if (ipar < (int) result.Errors().size())
3437 fParErrors[i] = result.Error(ipar);
3438 }
3439 //invalidate cached integral since parameters have changed
3440 Update();
3441
3442}
3443
3444
3445////////////////////////////////////////////////////////////////////////////////
3446/// Set the maximum value along Y for this function
3447/// In case the function is already drawn, set also the maximum in the
3448/// helper histogram
3449
3451{
3452 fMaximum = maximum;
3454 if (gPad) gPad->Modified();
3455}
3456
3457
3458////////////////////////////////////////////////////////////////////////////////
3459/// Set the minimum value along Y for this function
3460/// In case the function is already drawn, set also the minimum in the
3461/// helper histogram
3462
3464{
3465 fMinimum = minimum;
3467 if (gPad) gPad->Modified();
3468}
3469
3470
3471////////////////////////////////////////////////////////////////////////////////
3472/// Set the number of degrees of freedom
3473/// ndf should be the number of points used in a fit - the number of free parameters
3474
3476{
3477 fNDF = ndf;
3478}
3479
3480
3481////////////////////////////////////////////////////////////////////////////////
3482/// Set the number of points used to draw the function
3483///
3484/// The default number of points along x is 100 for 1-d functions and 30 for 2-d/3-d functions
3485/// You can increase this value to get a better resolution when drawing
3486/// pictures with sharp peaks or to get a better result when using TF1::GetRandom
3487/// the minimum number of points is 4, the maximum is 10000000 for 1-d and 10000 for 2-d/3-d functions
3488
3490{
3491 const Int_t minPx = 4;
3492 Int_t maxPx = 10000000;
3493 if (GetNdim() > 1) maxPx = 10000;
3494 if (npx >= minPx && npx <= maxPx) {
3495 fNpx = npx;
3496 } else {
3497 if (npx < minPx) fNpx = minPx;
3498 if (npx > maxPx) fNpx = maxPx;
3499 Warning("SetNpx", "Number of points must be >=%d && <= %d, fNpx set to %d", minPx, maxPx, fNpx);
3500 }
3501 Update();
3502}
3503////////////////////////////////////////////////////////////////////////////////
3504/// Set name of parameter number ipar
3505
3506void TF1::SetParName(Int_t ipar, const char *name)
3507{
3508 if (fFormula) {
3509 if (ipar < 0 || ipar >= GetNpar()) return;
3510 fFormula->SetParName(ipar, name);
3511 } else
3512 fParams->SetParName(ipar, name);
3513}
3514
3515////////////////////////////////////////////////////////////////////////////////
3516/// Set up to 10 parameter names.
3517/// Empty strings will be skipped, meaning that the corresponding name will not be changed.
3518
3519void TF1::SetParNames(const char *name0, const char *name1, const char *name2, const char *name3, const char *name4,
3520 const char *name5, const char *name6, const char *name7, const char *name8, const char *name9, const char *name10)
3521{
3522 // Note: this is not made a variadic template method because it would
3523 // presumably break the context menu in the TBrowser. Also, probably this
3524 // method should not be virtual, because if the user wants to change
3525 // parameter name setting behavior, the SetParName() method can be
3526 // overridden.
3527 if (fFormula)
3529 else
3530 fParams->SetParNames(name0, name1, name2, name3, name4, name5, name6, name7, name8, name9, name10);
3531}
3532////////////////////////////////////////////////////////////////////////////////
3533/// Set error for parameter number ipar
3534
3536{
3537 if (ipar < 0 || ipar > GetNpar() - 1) return;
3538 fParErrors[ipar] = error;
3539}
3540
3541
3542////////////////////////////////////////////////////////////////////////////////
3543/// Set errors for all active parameters
3544/// when calling this function, the array errors must have at least fNpar values
3545
3547{
3548 if (!errors) return;
3549 for (Int_t i = 0; i < GetNpar(); i++) fParErrors[i] = errors[i];
3550}
3551
3552
3553////////////////////////////////////////////////////////////////////////////////
3554/// Set lower and upper limits for parameter ipar.
3555/// The specified limits will be used in a fit operation.
3556/// Note that when this function is a pre-defined function (e.g. gaus)
3557/// one needs to use the fit option "B" to have the limits used in the fit.
3558/// See TH1::Fit(TF1*, Option_t *, Option_t *, Double_t, Double_t) for the fitting documentation
3559/// and the [fitting options](\ref HFitOpt)
3560///
3561/// To fix a parameter, use TF1::FixParameter
3562
3564{
3565 Int_t npar = GetNpar();
3566 if (ipar < 0 || ipar > npar - 1) return;
3567 if (int(fParMin.size()) != npar) {
3568 fParMin.resize(npar);
3569 }
3570 if (int(fParMax.size()) != npar) {
3571 fParMax.resize(npar);
3572 }
3573 fParMin[ipar] = parmin;
3574 fParMax[ipar] = parmax;
3575}
3576
3577
3578////////////////////////////////////////////////////////////////////////////////
3579/// Initialize the upper and lower bounds to draw the function.
3580///
3581/// The function range is also used in an histogram fit operation
3582/// when the option "R" is specified.
3583
3585{
3586 fXmin = xmin;
3587 fXmax = xmax;
3589 fComposition->SetRange(xmin, xmax); // automatically updates sub-functions
3590 }
3591 Update();
3592}
3593
3594
3595////////////////////////////////////////////////////////////////////////////////
3596/// Restore value of function saved at point
3597
3599{
3600 if (fSave.empty()) {
3601 fSave.resize(fNpx + 3);
3602 }
3603 if (point < 0 || point >= int(fSave.size())) return;
3604 fSave[point] = value;
3605}
3606
3607
3608////////////////////////////////////////////////////////////////////////////////
3609/// Set function title
3610/// if title has the form "fffffff;xxxx;yyyy", it is assumed that
3611/// the function title is "fffffff" and "xxxx" and "yyyy" are the
3612/// titles for the X and Y axis respectively.
3613
3614void TF1::SetTitle(const char *title)
3615{
3616 if (!title) return;
3617 fTitle = title;
3618 if (!fHistogram) return;
3619 fHistogram->SetTitle(title);
3620 if (gPad) gPad->Modified();
3621}
3622
3623
3624////////////////////////////////////////////////////////////////////////////////
3625/// Stream a class object.
3626
3628{
3629 if (b.IsReading()) {
3630 UInt_t R__s, R__c;
3631 Version_t v = b.ReadVersion(&R__s, &R__c);
3632 // process new version with new TFormula class which is contained in TF1
3633 //printf("reading TF1....- version %d..\n",v);
3634
3635 if (v > 7) {
3636 // new classes with new TFormula
3637 // need to register the objects
3638 b.ReadClassBuffer(TF1::Class(), this, v, R__s, R__c);
3639 if (!TestBit(kNotGlobal)) {
3641 gROOT->GetListOfFunctions()->Add(this);
3642 }
3643 return;
3644 } else {
3646 //printf("Reading TF1 as v5::TF1Data- version %d \n",v);
3647 fold.Streamer(b, v, R__s, R__c, TF1::Class());
3648 // convert old TF1 to new one
3649 ((TF1v5Convert *)this)->Convert(fold);
3650 }
3651 }
3652
3653 // Writing
3654 else {
3655 Int_t saved = 0;
3656 // save not-formula functions as array of points
3657 if (fType > 0 && fSave.empty() && fType != EFType::kCompositionFcn) {
3658 saved = 1;
3659 Save(fXmin, fXmax, 0, 0, 0, 0);
3660 }
3661 b.WriteClassBuffer(TF1::Class(), this);
3662
3663 // clear vector contents
3664 if (saved) {
3665 fSave.clear();
3666 }
3667 }
3668}
3669
3670
3671////////////////////////////////////////////////////////////////////////////////
3672/// Called by functions such as SetRange, SetNpx, SetParameters
3673/// to force the deletion of the associated histogram or Integral
3674
3676{
3677 if (fHistogram) {
3681 fHistogram->GetXaxis()->TAttAxis::Copy(attx);
3682 fHistogram->GetYaxis()->TAttAxis::Copy(atty);
3683
3684 delete fHistogram;
3685 fHistogram = nullptr;
3686 GetHistogram();
3687
3690 attx.Copy(*(fHistogram->GetXaxis()));
3691 atty.Copy(*(fHistogram->GetYaxis()));
3692 }
3693 if (!fIntegral.empty()) {
3694 fIntegral.clear();
3695 fAlpha.clear();
3696 fBeta.clear();
3697 fGamma.clear();
3698 }
3699 if (fNormalized) {
3700 // need to compute the integral of the not-normalized function
3701 fNormalized = false;
3703 fNormalized = true;
3704 } else
3705 fNormIntegral = 0;
3706
3707 // std::vector<double>x(fNdim);
3708 // if ((fType == 1) && !fFunctor->Empty()) (*fFunctor)x.data(), (Double_t*)fParams);
3710 // double-check that the parameters are correct
3711 fComposition->SetParameters(GetParameters());
3712
3713 fComposition->Update(); // should not be necessary, but just to be safe
3714 }
3715}
3716
3717////////////////////////////////////////////////////////////////////////////////
3718/// Static function to set the global flag to reject points
3719/// the fgRejectPoint global flag is tested by all fit functions
3720/// if TRUE the point is not included in the fit.
3721/// This flag can be set by a user in a fitting function.
3722/// The fgRejectPoint flag is reset by the TH1 and TGraph fitting functions.
3723
3728
3729
3730////////////////////////////////////////////////////////////////////////////////
3731/// See TF1::RejectPoint above
3732
3734{
3735 return fgRejectPoint;
3736}
3737
3738////////////////////////////////////////////////////////////////////////////////
3739/// Return nth moment of function between a and b
3740///
3741/// See TF1::Integral() for parameter definitions
3742
3744{
3745 // wrapped function in interface for integral calculation
3746 // using abs value of integral
3747
3748 TF1_EvalWrapper func(this, params, kTRUE, n);
3749
3751
3752 giod.SetFunction(func);
3753 giod.SetRelTolerance(epsilon);
3754
3755 Double_t norm = giod.Integral(a, b);
3756 if (norm == 0) {
3757 Error("Moment", "Integral zero over range");
3758 return 0;
3759 }
3760
3761 // calculate now integral of x^n f(x)
3762 // wrapped the member function EvalNum in interface required by integrator using the functor class
3764 giod.SetFunction(xnfunc);
3765
3766 Double_t res = giod.Integral(a, b) / norm;
3767
3768 return res;
3769}
3770
3771
3772////////////////////////////////////////////////////////////////////////////////
3773/// Return nth central moment of function between a and b
3774/// (i.e the n-th moment around the mean value)
3775///
3776/// See TF1::Integral() for parameter definitions
3777///
3778/// \author Gene Van Buren <gene@bnl.gov>
3779
3781{
3782 TF1_EvalWrapper func(this, params, kTRUE, n);
3783
3785
3786 giod.SetFunction(func);
3787 giod.SetRelTolerance(epsilon);
3788
3789 Double_t norm = giod.Integral(a, b);
3790 if (norm == 0) {
3791 Error("Moment", "Integral zero over range");
3792 return 0;
3793 }
3794
3795 // calculate now integral of xf(x)
3796 // wrapped the member function EvalFirstMom in interface required by integrator using the functor class
3798 giod.SetFunction(xfunc);
3799
3800 // estimate of mean value
3801 Double_t xbar = giod.Integral(a, b) / norm;
3802
3803 // use different mean value in function wrapper
3804 func.fX0 = xbar;
3806 giod.SetFunction(xnfunc);
3807
3808 Double_t res = giod.Integral(a, b) / norm;
3809 return res;
3810}
3811
3812
3813//______________________________________________________________________________
3814// some useful static utility functions to compute sampling points for IntegralFast
3815////////////////////////////////////////////////////////////////////////////////
3816/// Type safe interface (static method)
3817/// The number of sampling points are taken from the TGraph
3818
3819#ifdef INTHEFUTURE
3821{
3822 if (!g) return;
3823 CalcGaussLegendreSamplingPoints(g->GetN(), g->GetX(), g->GetY(), eps);
3824}
3825
3826
3827////////////////////////////////////////////////////////////////////////////////
3828/// Type safe interface (static method)
3829/// A TGraph is created with new with num points and the pointer to the
3830/// graph is returned by the function. It is the responsibility of the
3831/// user to delete the object.
3832/// if num is invalid (<=0) NULL is returned
3833
3835{
3836 if (num <= 0)
3837 return 0;
3838
3839 TGraph *g = new TGraph(num);
3840 CalcGaussLegendreSamplingPoints(g->GetN(), g->GetX(), g->GetY(), eps);
3841 return g;
3842}
3843#endif
3844
3845
3846////////////////////////////////////////////////////////////////////////////////
3847/// Type: unsafe but fast interface filling the arrays x and w (static method)
3848///
3849/// Given the number of sampling points this routine fills the arrays x and w
3850/// of length num, containing the abscissa and weight of the Gauss-Legendre
3851/// n-point quadrature formula.
3852///
3853/// Gauss-Legendre:
3854/** \f[
3855 W(x)=1 -1<x<1 \\
3856 (j+1)P_{j+1} = (2j+1)xP_j-jP_{j-1}
3857 \f]
3858**/
3859/// num is the number of sampling points (>0)
3860/// x and w are arrays of size num
3861/// eps is the relative precision
3862///
3863/// If num<=0 or eps<=0 no action is done.
3864///
3865/// Reference: Numerical Recipes in C, Second Edition
3866
3868{
3869 // This function is just kept like this for backward compatibility!
3870
3872 gli.GetWeightVectors(x, w);
3873
3874
3875}
3876
3877
3878/** \class TF1Parameters
3879TF1 Parameters class
3880*/
3881
3882////////////////////////////////////////////////////////////////////////////////
3883/// Returns the parameter number given a name
3884/// not very efficient but list of parameters is typically small
3885/// could use a map if needed
3886
3888{
3889 for (unsigned int i = 0; i < fParNames.size(); ++i) {
3890 if (fParNames[i] == std::string(name)) return i;
3891 }
3892 return -1;
3893}
Double_t AnalyticalIntegral(TF1 *f, Double_t a, Double_t b)
@ kMouseMotion
Definition Buttons.h:23
@ kHand
Definition GuiTypes.h:375
#define d(i)
Definition RSha256.hxx:102
#define b(i)
Definition RSha256.hxx:100
#define f(i)
Definition RSha256.hxx:104
#define g(i)
Definition RSha256.hxx:105
#define a(i)
Definition RSha256.hxx:99
#define h(i)
Definition RSha256.hxx:106
#define e(i)
Definition RSha256.hxx:103
cudaEvent_t event
bool Bool_t
Boolean (0=false, 1=true) (bool)
Definition RtypesCore.h:78
int Int_t
Signed integer 4 bytes (int)
Definition RtypesCore.h:60
long Longptr_t
Integer large enough to hold a pointer (platform-dependent)
Definition RtypesCore.h:90
short Version_t
Class version identifier (short)
Definition RtypesCore.h:80
unsigned int UInt_t
Unsigned integer 4 bytes (unsigned int)
Definition RtypesCore.h:61
constexpr Bool_t kFALSE
Definition RtypesCore.h:109
double Double_t
Double 8 bytes.
Definition RtypesCore.h:74
constexpr Ssiz_t kNPOS
The equivalent of std::string::npos for the ROOT class TString.
Definition RtypesCore.h:132
constexpr Bool_t kTRUE
Definition RtypesCore.h:108
const char Option_t
Option string (const char)
Definition RtypesCore.h:81
#define BIT(n)
Definition Rtypes.h:90
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:130
bool R__SetClonesArrayTF1Updater(TF1Updater_t func)
TF1::EAddToList GetGlobalListOption(Option_t *opt)
Definition TF1.cxx:671
int R__RegisterTF1UpdaterTrigger
Definition TF1.cxx:149
void(*)(Int_t nobjects, TObject **from, TObject **to) TF1Updater_t
Definition TF1.cxx:66
static Double_t gErrorTF1
Definition TF1.cxx:64
static void R__v5TF1Updater(Int_t nobjects, TObject **from, TObject **to)
Definition TF1.cxx:138
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 TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void data
Option_t Option_t SetLineWidth
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t hmin
Option_t Option_t SetFillStyle
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t hmax
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h Atom_t Int_t ULong_t ULong_t unsigned char prop_list Atom_t Atom_t target
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t np
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t r
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t result
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void on
Option_t Option_t SetLineColor
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void value
Option_t Option_t TPoint TPoint const char x2
Option_t Option_t TPoint TPoint const char x1
char name[80]
Definition TGX11.cxx:142
float xmin
float ymin
float xmax
float ymax
#define gInterpreter
Int_t gDebug
Global variable setting the debug level. Set to 0 to disable, increase it in steps of 1 to increase t...
Definition TROOT.cxx:792
R__EXTERN TVirtualMutex * gROOTMutex
Definition TROOT.h:63
#define gROOT
Definition TROOT.h:417
R__EXTERN TRandom * gRandom
Definition TRandom.h:73
R__EXTERN TStyle * gStyle
Definition TStyle.h:442
#define R__LOCKGUARD(mutex)
#define gPad
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:44
Class for adaptive quadrature integration in multi-dimensions using rectangular regions.
User class for performing function minimization.
Class for finding the root of a one dimensional function using the Brent algorithm.
static ROOT::Math::Minimizer * CreateMinimizer(const std::string &minimizerType="", const std::string &algoType="")
static method to create the corresponding Minimizer given the string Supported Minimizers types are: ...
Definition Factory.cxx:63
Functor1D class for one-dimensional functions.
Definition Functor.h:97
User class for performing function integration.
User class for performing function integration.
Interface (abstract class) for generic functions objects of one-dimension Provides a method to evalua...
Definition IFunction.h:157
static IntegrationMultiDim::Type DefaultIntegratorType()
User class for performing multidimensional integration.
static IntegrationOneDim::Type DefaultIntegratorType()
User Class for performing numerical integration of a function in one dimension.
Definition Integrator.h:94
static std::string GetName(IntegrationOneDim::Type)
static function to get a string from the enumeration
static const std::string & DefaultMinimizerType()
static const std::string & DefaultMinimizerAlgo()
Abstract Minimizer class, defining the interface for the various minimizer (like Minuit2,...
Definition Minimizer.h:124
Param Functor class for Multidimensional functions.
User class for calculating the derivatives of a function.
Template class to wrap any C++ callable object which takes one argument i.e.
Template class to wrap any C++ callable object implementing operator() (const double * x) in a multi-...
Class to Wrap a ROOT Function class (like TF1) in a IParamFunction interface of one dimensions to be ...
Definition WrappedTF1.h:39
virtual Double_t * GetParameters() const
Definition TFormula.h:244
virtual Int_t GetNdim() const
Definition TFormula.h:238
virtual Int_t GetNpar() const
Definition TFormula.h:239
virtual TString GetExpFormula(Option_t *option="") const
Reconstruct the formula expression from the internal TFormula member variables.
Array of doubles (64 bits per element).
Definition TArrayD.h:27
const Double_t * GetArray() const
Definition TArrayD.h:43
Manages histogram axis attributes.
Definition TAttAxis.h:19
Fill Area Attributes class.
Definition TAttFill.h:21
virtual Color_t GetFillColor() const
Return the fill area color.
Definition TAttFill.h:32
void Copy(TAttFill &attfill) const
Copy this fill attributes to a new TAttFill.
Definition TAttFill.cxx:203
virtual Style_t GetFillStyle() const
Return the fill area style.
Definition TAttFill.h:33
virtual void SetFillColor(Color_t fcolor)
Set the fill area color.
Definition TAttFill.h:40
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:240
Line Attributes class.
Definition TAttLine.h:21
virtual Color_t GetLineColor() const
Return the line color.
Definition TAttLine.h:36
virtual void SetLineStyle(Style_t lstyle)
Set the line style.
Definition TAttLine.h:46
virtual Width_t GetLineWidth() const
Return the line width.
Definition TAttLine.h:38
virtual void SetLineColor(Color_t lcolor)
Set the line color.
Definition TAttLine.h:44
virtual Style_t GetLineStyle() const
Return the line style.
Definition TAttLine.h:37
void Copy(TAttLine &attline) const
Copy this line attributes to a new TAttLine.
Definition TAttLine.cxx:176
virtual void SaveLineAttributes(std::ostream &out, const char *name, Int_t coldef=1, Int_t stydef=1, Int_t widdef=1)
Save line attributes as C++ statement(s) on output stream out.
Definition TAttLine.cxx:289
Marker Attributes class.
Definition TAttMarker.h:22
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:35
virtual Color_t GetMarkerColor() const
Return the marker color.
Definition TAttMarker.h:34
virtual Size_t GetMarkerSize() const
Return the marker size.
Definition TAttMarker.h:36
void Copy(TAttMarker &attmarker) const
Copy this marker attributes to a new TAttMarker.
virtual void SetMarkerColor(Color_t mcolor=1)
Set the marker color.
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:5111
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:3887
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:182
std::unique_ptr< TF1FunctorPointer > fFunctor
! Functor object to wrap any C++ callable object
Definition TF1.h:236
virtual Double_t GetMinimumX(Double_t xmin=0, Double_t xmax=0, Double_t epsilon=1.E-10, Int_t maxiter=100, Bool_t logx=false) const
Returns the X value corresponding to the minimum value of the function on the (xmin,...
Definition TF1.cxx:1874
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:1747
virtual Double_t GetXmax() const
Definition TF1.h:525
virtual void ReleaseParameter(Int_t ipar)
Release parameter number ipar during a fit operation.
Definition TF1.cxx:3202
virtual void SetParError(Int_t ipar, Double_t error)
Set error for parameter number ipar.
Definition TF1.cxx:3535
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:3724
EAddToList
Add to list behavior.
Definition TF1.h:189
virtual Double_t Derivative(Double_t x, Double_t *params=nullptr, Double_t epsilon=0.001) const
Returns the first derivative of the function at point x, computed by Richardson's extrapolation metho...
Definition TF1.cxx:1121
virtual Int_t GetNumber() const
Definition TF1.h:463
virtual Int_t GetNDF() const
Return the number of degrees of freedom in the fit the fNDF parameter has been previously computed du...
Definition TF1.cxx:1940
std::vector< Double_t > fParErrors
Array of errors of the fNpar parameters.
Definition TF1.h:223
Int_t fNdim
Function dimension.
Definition TF1.h:215
static void CalcGaussLegendreSamplingPoints(Int_t num, Double_t *x, Double_t *w, Double_t eps=3.0e-11)
Type safe interface (static method) The number of sampling points are taken from the TGraph.
Definition TF1.cxx:3867
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:1635
virtual void GetParLimits(Int_t ipar, Double_t &parmin, Double_t &parmax) const
Return limits for parameter ipar.
Definition TF1.cxx:1991
Int_t fNpar
Number of parameters.
Definition TF1.h:214
TAxis * GetYaxis() const
Get y axis of the function.
Definition TF1.cxx:2460
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:3475
virtual Double_t GetParError(Int_t ipar) const
Return value of parameter number ipar.
Definition TF1.cxx:1981
static TClass * Class()
static std::atomic< Bool_t > fgAddToGlobList
Definition TF1.h:275
virtual Double_t IntegralError(Double_t a, Double_t b, const Double_t *params=nullptr, const Double_t *covmat=nullptr, Double_t epsilon=1.E-2)
Return Error on Integral of a parametric function between a and b due to the parameter uncertainties ...
Definition TF1.cxx:2758
virtual void SetChisquare(Double_t chi2)
Definition TF1.h:581
virtual Double_t IntegralFast(Int_t num, Double_t *x, Double_t *w, Double_t a, Double_t b, Double_t *params=nullptr, Double_t epsilon=1e-12)
Gauss-Legendre integral, see CalcGaussLegendreSamplingPoints.
Definition TF1.cxx:2828
Double_t fNormIntegral
Integral of the function before being normalized.
Definition TF1.h:235
Double_t GetChisquare() const
Return the Chisquare after fitting. See ROOT::Fit::FitResult::Chi2()
Definition TF1.h:409
virtual void SetMaximum(Double_t maximum=-1111)
Set the maximum value along Y for this function In case the function is already drawn,...
Definition TF1.cxx:3450
void Print(Option_t *option="") const override
This method must be overridden when a class wants to print itself.
Definition TF1.cxx:2947
virtual TH1 * CreateHistogram()
Definition TF1.h:414
Double_t fXmin
Lower bounds for the range.
Definition TF1.h:212
std::unique_ptr< TMethodCall > fMethodCall
! Pointer to MethodCall in case of interpreted function
Definition TF1.h:233
virtual void Update()
Called by functions such as SetRange, SetNpx, SetParameters to force the deletion of the associated h...
Definition TF1.cxx:3675
virtual Double_t GetProb() const
Return the fit probability.
Definition TF1.cxx:2006
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:2043
TAxis * GetZaxis() const
Get z axis of the function. (In case this object is a TF2 or TF3)
Definition TF1.cxx:2471
virtual Double_t GetRandom(TRandom *rng=nullptr, Option_t *opt=nullptr)
Return a random number following this function shape.
Definition TF1.cxx:2241
virtual void SetRange(Double_t xmin, Double_t xmax)
Initialize the upper and lower bounds to draw the function.
Definition TF1.cxx:3584
virtual Int_t GetNpar() const
Definition TF1.h:446
std::vector< Double_t > fBeta
! Array beta. is approximated by x = alpha +beta*r *gamma*r**2
Definition TF1.h:229
Double_t EvalUncertainty(Double_t x, const TMatrixDSym *covMatrix=nullptr) const
Evaluate the uncertainty of the function at location x due to the parameter uncertainties.
Definition TF1.cxx:1568
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:3270
Int_t fNDF
Number of degrees of freedom in the fit.
Definition TF1.h:219
TH1 * fHistogram
! Pointer to histogram used for visualisation
Definition TF1.h:232
std::unique_ptr< TF1AbsComposition > fComposition
Pointer to composition (NSUM or CONV)
Definition TF1.h:239
virtual void SetParErrors(const Double_t *errors)
Set errors for all active parameters when calling this function, the array errors must have at least ...
Definition TF1.cxx:3546
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:3098
Int_t fNpfits
Number of points used in the fit.
Definition TF1.h:218
virtual Double_t Derivative2(Double_t x, Double_t *params=nullptr, Double_t epsilon=0.001) const
Returns the second derivative of the function at point x, computed by Richardson's extrapolation meth...
Definition TF1.cxx:1186
static void SetCurrent(TF1 *f1)
Static function setting the current function.
Definition TF1.cxx:3399
std::vector< Double_t > fAlpha
! Array alpha. for each bin in x the deconvolution r of fIntegral
Definition TF1.h:228
virtual Double_t Integral(Double_t a, Double_t b, Double_t epsrel=1.e-12)
IntegralOneDim or analytical integral.
Definition TF1.cxx:2581
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:3614
std::unique_ptr< TFormula > fFormula
Pointer to TFormula in case when user define formula.
Definition TF1.h:237
virtual void SetParNames(const char *name0="", const char *name1="", const char *name2="", const char *name3="", const char *name4="", const char *name5="", const char *name6="", const char *name7="", const char *name8="", const char *name9="", const char *name10="")
Set up to 10 parameter names.
Definition TF1.cxx:3519
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:224
static void InitStandardFunctions()
Create the basic function objects.
Definition TF1.cxx:2546
Double_t fMaximum
Maximum value for plotting.
Definition TF1.h:222
virtual void SetNpx(Int_t npx=100)
Set the number of points used to draw the function.
Definition TF1.cxx:3489
virtual Double_t * GetParameters() const
Definition TF1.h:485
Double_t fMinimum
Minimum value for plotting.
Definition TF1.h:221
int TermCoeffLength(TString &term)
Definition TF1.cxx:926
static Bool_t fgRejectPoint
Definition TF1.h:274
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:3627
virtual void SetNumberFitPoints(Int_t npfits)
Definition TF1.h:593
double EvalParVec(const Double_t *data, const Double_t *params)
void Paint(Option_t *option="") override
Paint this function with its current attributes.
Definition TF1.cxx:3003
TF1 & operator=(const TF1 &rhs)
Operator =.
Definition TF1.cxx:944
virtual Int_t GetNumberFreeParameters() const
Return the number of free parameters.
Definition TF1.cxx:1951
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:3743
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:3780
Double_t fChisquare
Function fit chisquare.
Definition TF1.h:220
@ kNotGlobal
Definition TF1.h:296
@ kNotDraw
Definition TF1.h:297
virtual void InitArgs(const Double_t *x, const Double_t *params)
Initialize parameters addresses.
Definition TF1.cxx:2531
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:2901
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:217
Bool_t fNormalized
Normalization option (false by default)
Definition TF1.h:234
void Draw(Option_t *option="") override
Draw this function with its current attributes.
Definition TF1.cxx: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:3463
virtual void GetRange(Double_t *xmin, Double_t *xmax) const
Return range of a generic N-D function.
Definition TF1.cxx:2330
void Browse(TBrowser *b) override
Browse.
Definition TF1.cxx:995
virtual const char * GetParName(Int_t ipar) const
Definition TF1.h:494
~TF1() override
TF1 default destructor.
Definition TF1.cxx:955
static TF1 * fgCurrent
Definition TF1.h:276
virtual Double_t EvalPar(const Double_t *x, const Double_t *params=nullptr)
Evaluate function with given coordinates and parameters.
Definition TF1.cxx:1499
Int_t fNpx
Number of points used for the graphical representation.
Definition TF1.h:216
virtual void SetParLimits(Int_t ipar, Double_t parmin, Double_t parmax)
Set lower and upper limits for parameter ipar.
Definition TF1.cxx:3563
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:1914
static TF1 * GetCurrent()
Static function returning the current function being processed.
Definition TF1.cxx:1620
virtual void SetParName(Int_t ipar, const char *name)
Set name of parameter number ipar.
Definition TF1.cxx:3506
char * GetObjectInfo(Int_t px, Int_t py) const override
Redefines TObject::GetObjectInfo.
Definition TF1.cxx:1969
void ExecuteEvent(Int_t event, Int_t px, Int_t py) override
Execute action corresponding to one event.
Definition TF1.cxx:1587
virtual Double_t GetSave(const Double_t *x)
Get value corresponding to X in array of fSave values.
Definition TF1.cxx:2393
static std::atomic< Bool_t > fgAbsValue
Definition TF1.h:273
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:225
void SavePrimitive(std::ostream &out, Option_t *option="") override
Save primitive as a C++ statement(s) on output stream out.
Definition TF1.cxx:3287
virtual Bool_t IsValid() const
Return kTRUE if the function is valid.
Definition TF1.cxx:2932
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:226
static Bool_t RejectedPoint()
See TF1::RejectPoint above.
Definition TF1.cxx:3733
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:230
TObject * fParent
! Parent object hooking this function (if one)
Definition TF1.h:231
virtual Double_t GetMinMaxNDim(Double_t *x, Bool_t findmax, Double_t epsilon=0, Int_t maxiter=0) const
Find the minimum of a function of whatever dimension.
Definition TF1.cxx:1774
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:2130
virtual void SetParameters(const Double_t *params)
Definition TF1.h:618
virtual TObject * DrawIntegral(Option_t *option="al")
Draw integral of this function.
Definition TF1.cxx:1415
std::vector< Double_t > fIntegral
! Integral of function binned on fNpx bins
Definition TF1.h:227
virtual TObject * DrawDerivative(Option_t *option="al")
Draw derivative of this function.
Definition TF1.cxx: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:1665
std::unique_ptr< TF1Parameters > fParams
Pointer to Function parameters object (exists only for not-formula functions)
Definition TF1.h:238
virtual void SetParameter(Int_t param, Double_t value)
Definition TF1.h:608
virtual Double_t Derivative3(Double_t x, Double_t *params=nullptr, Double_t epsilon=0.001) const
Returns the third derivative of the function at point x, computed by Richardson's extrapolation metho...
Definition TF1.cxx: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:3212
TObject * Clone(const char *newname=nullptr) const override
Make a complete copy of the underlying object.
Definition TF1.cxx:1072
EFType
Definition TF1.h:203
@ kCompositionFcn
Definition TF1.h:209
@ kFormula
Formula functions which can be stored,.
Definition TF1.h:204
@ kPtrScalarFreeFcn
Pointer to scalar free function,.
Definition TF1.h:205
@ kTemplScalar
TemplScalar functors evaluating on scalar parameters.
Definition TF1.h:208
@ kTemplVec
Vectorized free functions or TemplScalar functors evaluating on vectorized parameters,...
Definition TF1.h:207
@ kInterpreted
Interpreted functions constructed by name,.
Definition TF1.h:206
virtual Double_t GradientPar(Int_t ipar, const Double_t *x, Double_t eps=0.01) const
Compute the gradient (derivative) wrt a parameter ipar.
Definition TF1.cxx:2494
virtual void SetSavedPoint(Int_t point, Double_t value)
Restore value of function saved at point.
Definition TF1.cxx:3598
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:1608
Double_t fXmax
Upper bounds for the range.
Definition TF1.h:213
virtual Double_t GetMaximumX(Double_t xmin=0, Double_t xmax=0, Double_t epsilon=1.E-10, Int_t maxiter=100, Bool_t logx=false) const
Returns the X value corresponding to the maximum value of the function.
Definition TF1.cxx:1706
TClass * IsA() const override
Definition TF1.h:694
virtual Int_t GetNdim() const
Definition TF1.h:450
virtual Double_t GetXmin() const
Definition TF1.h:521
virtual Bool_t AddToGlobalList(Bool_t on=kTRUE)
Add to global list of functions (gROOT->GetListOfFunctions() ) return previous status (true if the fu...
Definition TF1.cxx: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:2671
virtual Double_t GetParameter(Int_t ipar) const
Definition TF1.h:477
virtual void SetFitResult(const ROOT::Fit::FitResult &result, const Int_t *indpar=nullptr)
Set the result from the fit parameter values, errors, chi2, etc... Optionally a pointer to a vector (...
Definition TF1.cxx:3411
TAxis * GetXaxis() const
Get x axis of the function.
Definition TF1.cxx:2449
The Formula class.
Definition TFormula.h:89
TString fFormula
String representing the formula expression.
Definition TFormula.h:147
A TGraph is an object made of two arrays X and Y with npoints each.
Definition TGraph.h:41
void Draw(Option_t *chopt="") override
Draw this graph with its current attributes.
Definition TGraph.cxx:859
1-D histogram with a double per channel (see TH1 documentation)
Definition TH1.h:926
TH1 is the base class of all histogram classes in ROOT.
Definition TH1.h:109
virtual void SetDirectory(TDirectory *dir)
By default, when a histogram is created, it is added to the list of histogram objects in the current ...
Definition TH1.cxx:9170
Int_t DistancetoPrimitive(Int_t px, Int_t py) override
Compute distance from point px,py to a line.
Definition TH1.cxx:2952
void SetTitle(const char *title) override
Change/set the title.
Definition TH1.cxx:6932
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:7230
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:8778
virtual void SetMaximum(Double_t maximum=-1111)
Definition TH1.h:652
TAxis * GetYaxis()
Definition TH1.h:572
virtual void SetMinimum(Double_t minimum=-1111)
Definition TH1.h:653
void Paint(Option_t *option="") override
Control routine to paint any kind of histograms.
Definition TH1.cxx:6417
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:3385
TObject * Clone(const char *newname="") const override
Make a complete copy of the underlying object.
Definition TH1.cxx:2882
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:8868
Method or function calling interface.
Definition TMethodCall.h:37
The TNamed class is the base class for all named ROOT classes.
Definition TNamed.h:29
TObject * Clone(const char *newname="") const override
Make a clone of an object using the Streamer facility.
Definition TNamed.cxx:73
void SavePrimitiveNameTitle(std::ostream &out, const char *variable_name)
Save object name and title into the output stream "out".
Definition TNamed.cxx:135
void Copy(TObject &named) const override
Copy this to obj.
Definition TNamed.cxx:93
virtual void SetTitle(const char *title="")
Set the title of the TNamed.
Definition TNamed.cxx:173
const char * GetName() const override
Returns name of object.
Definition TNamed.h:49
const char * GetTitle() const override
Returns title of object.
Definition TNamed.h:50
TString fTitle
Definition TNamed.h:33
TString fName
Definition TNamed.h:32
An array of TObjects.
Definition TObjArray.h:31
Collectable string class.
Definition TObjString.h:28
Mother of all ROOT objects.
Definition TObject.h:42
R__ALWAYS_INLINE Bool_t TestBit(UInt_t f) const
Definition TObject.h:204
virtual void RecursiveRemove(TObject *obj)
Recursively remove this object from a list.
Definition TObject.cxx:683
virtual void Warning(const char *method, const char *msgfmt,...) const
Issue warning message.
Definition TObject.cxx:1082
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:886
virtual Bool_t InheritsFrom(const char *classname) const
Returns kTRUE if object inherits from class "classname".
Definition TObject.cxx:548
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition TObject.cxx:1096
void MakeZombie()
Definition TObject.h:55
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:844
static TString SavePrimitiveVector(std::ostream &out, const char *prefix, Int_t len, Double_t *arr, Int_t flag=0)
Save array in the output stream "out" as vector.
Definition TObject.cxx:795
@ kCanDelete
if object in a list can be deleted
Definition TObject.h:71
virtual void Info(const char *method, const char *msgfmt,...) const
Issue info message.
Definition TObject.cxx:1070
This is the base class for the ROOT Random number generators.
Definition TRandom.h:28
Double_t Rndm() override
Machine independent random number generator.
Definition TRandom.cxx:558
virtual Double_t Uniform(Double_t x1=1)
Returns a uniform deviate on the interval (0, x1).
Definition TRandom.cxx:681
Basic string class.
Definition TString.h:137
void ToLower()
Change string to lower-case.
Definition TString.cxx:1190
TString & ReplaceSpecialCppChars()
Find special characters which are typically used in printf() calls and replace them by appropriate es...
Definition TString.cxx:1122
const char * Data() const
Definition TString.h:385
TString & ReplaceAll(const TString &s1, const TString &s2)
Definition TString.h:714
void ToUpper()
Change string to upper case.
Definition TString.cxx:1203
Bool_t IsNull() const
Definition TString.h:423
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:2460
Bool_t Contains(const char *pat, ECaseCompare cmp=kExact) const
Definition TString.h:642
Color_t GetFuncColor() const
Definition TStyle.h:221
Width_t GetFuncWidth() const
Definition TStyle.h:223
Style_t GetFuncStyle() const
Definition TStyle.h:222
Element * GetMatrixArray()
Definition TVectorT.h:78
small helper class to store/restore gPad context in TPad methods
Definition TVirtualPad.h:61
@ kGAUSS
simple Gauss integration method with fixed rule
@ kADAPTIVE
adaptive multi-dimensional integration
Double_t y[n]
Definition legend1.C:17
Double_t x[n]
Definition legend1.C:17
const Int_t n
Definition legend1.C:16
TGraphErrors * gr
Definition legend1.C:25
TH1F * h1
Definition legend1.C:5
TF1 * f1
Definition legend1.C:11
Namespace for new Math classes and functions.
double IntegralError(TF1 *func, Int_t ndim, const double *a, const double *b, const double *params, const double *covmat, double epsilon)
Definition TF1Helper.cxx:39
Bool_t IsNaN(Double_t x)
Definition TMath.h:905
Short_t Max(Short_t a, Short_t b)
Returns the largest of a and b.
Definition TMathBase.h:249
Double_t Prob(Double_t chi2, Int_t ndf)
Computation of the probability for a certain Chi-squared (chi2) and number of degrees of freedom (ndf...
Definition TMath.cxx:637
Double_t QuietNaN()
Returns a quiet NaN as defined by IEEE 754.
Definition TMath.h:915
Double_t Sqrt(Double_t x)
Returns the square root of x.
Definition TMath.h:675
LongDouble_t Power(LongDouble_t x, LongDouble_t y)
Returns x raised to the power y.
Definition TMath.h:734
Short_t Min(Short_t a, Short_t b)
Returns the smallest of a and b.
Definition TMathBase.h:197
Bool_t AreEqualRel(Double_t af, Double_t bf, Double_t relPrec)
Comparing floating points.
Definition TMath.h:429
Double_t SignalingNaN()
Returns a signaling NaN as defined by IEEE 754.
Definition TMath.h:923
Long64_t BinarySearch(Long64_t n, const T *array, T value)
Binary search in an array of n values to locate value.
Definition TMathBase.h:329
Double_t Log10(Double_t x)
Returns the common (base-10) logarithm of x.
Definition TMath.h:775
Short_t Abs(Short_t d)
Returns the absolute value of parameter Short_t d.
Definition TMathBase.h:122
Double_t Infinity()
Returns an infinity as defined by the IEEE standard.
Definition TMath.h:930
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