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