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/// IntegralOneDim or analytical integral
2555
2557{
2558 Double_t error = 0;
2559 if (GetNumber() > 0) {
2560 Double_t result = 0.;
2561 if (gDebug) {
2562 Info("computing analytical integral for function %s with number %d", GetName(), GetNumber());
2563 }
2564 result = AnalyticalIntegral(this, a, b);
2565 // if it is a formula that havent been implemented in analytical integral a NaN is return
2566 if (!TMath::IsNaN(result)) return result;
2567 if (gDebug)
2568 Warning("analytical integral not available for %s - with number %d compute numerical integral", GetName(), GetNumber());
2569 }
2570 return IntegralOneDim(a, b, epsrel, epsrel, error);
2571}
2572
2573////////////////////////////////////////////////////////////////////////////////
2574/// Return Integral of function between a and b using the given parameter values and
2575/// relative and absolute tolerance.
2576///
2577/// The default integrator defined in ROOT::Math::IntegratorOneDimOptions::DefaultIntegrator() is used
2578/// If ROOT contains the MathMore library the default integrator is set to be
2579/// the adaptive ROOT::Math::GSLIntegrator (based on QUADPACK) or otherwise the
2580/// ROOT::Math::GaussIntegrator is used
2581/// See the reference documentation of these classes for more information about the
2582/// integration algorithms
2583/// To change integration algorithm just do :
2584/// ROOT::Math::IntegratorOneDimOptions::SetDefaultIntegrator(IntegratorName);
2585/// Valid integrator names are:
2586/// - Gauss : for ROOT::Math::GaussIntegrator
2587/// - GaussLegendre : for ROOT::Math::GaussLegendreIntegrator
2588/// - Adaptive : for ROOT::Math::GSLIntegrator adaptive method (QAG)
2589/// - AdaptiveSingular : for ROOT::Math::GSLIntegrator adaptive singular method (QAGS)
2590/// - NonAdaptive : for ROOT::Math::GSLIntegrator non adaptive (QNG)
2591///
2592/// In order to use the GSL integrators one needs to have the MathMore library installed
2593///
2594/// Note 1:
2595///
2596/// Values of the function f(x) at the interval end-points A and B are not
2597/// required. The subprogram may therefore be used when these values are
2598/// undefined.
2599///
2600/// Note 2:
2601///
2602/// Instead of TF1::Integral, you may want to use the combination of
2603/// TF1::CalcGaussLegendreSamplingPoints and TF1::IntegralFast.
2604/// See an example with the following script:
2605///
2606/// ~~~ {.cpp}
2607/// void gint() {
2608/// TF1 *g = new TF1("g","gaus",-5,5);
2609/// g->SetParameters(1,0,1);
2610/// //default gaus integration method uses 6 points
2611/// //not suitable to integrate on a large domain
2612/// double r1 = g->Integral(0,5);
2613/// double r2 = g->Integral(0,1000);
2614///
2615/// //try with user directives computing more points
2616/// Int_t np = 1000;
2617/// double *x=new double[np];
2618/// double *w=new double[np];
2619/// g->CalcGaussLegendreSamplingPoints(np,x,w,1e-15);
2620/// double r3 = g->IntegralFast(np,x,w,0,5);
2621/// double r4 = g->IntegralFast(np,x,w,0,1000);
2622/// double r5 = g->IntegralFast(np,x,w,0,10000);
2623/// double r6 = g->IntegralFast(np,x,w,0,100000);
2624/// printf("g->Integral(0,5) = %g\n",r1);
2625/// printf("g->Integral(0,1000) = %g\n",r2);
2626/// printf("g->IntegralFast(n,x,w,0,5) = %g\n",r3);
2627/// printf("g->IntegralFast(n,x,w,0,1000) = %g\n",r4);
2628/// printf("g->IntegralFast(n,x,w,0,10000) = %g\n",r5);
2629/// printf("g->IntegralFast(n,x,w,0,100000)= %g\n",r6);
2630/// delete [] x;
2631/// delete [] w;
2632/// }
2633/// ~~~
2634///
2635/// This example produces the following results:
2636///
2637/// ~~~ {.cpp}
2638/// g->Integral(0,5) = 1.25331
2639/// g->Integral(0,1000) = 1.25319
2640/// g->IntegralFast(n,x,w,0,5) = 1.25331
2641/// g->IntegralFast(n,x,w,0,1000) = 1.25331
2642/// g->IntegralFast(n,x,w,0,10000) = 1.25331
2643/// g->IntegralFast(n,x,w,0,100000)= 1.253
2644/// ~~~
2645
2647{
2648 //Double_t *parameters = GetParameters();
2649 TF1_EvalWrapper wf1(this, nullptr, fgAbsValue);
2650 Double_t result = 0;
2651 Int_t status = 0;
2656 iod.SetFunction(wf1);
2657 if (a != - TMath::Infinity() && b != TMath::Infinity())
2658 result = iod.Integral(a, b);
2659 else if (a == - TMath::Infinity() && b != TMath::Infinity())
2660 result = iod.IntegralLow(b);
2661 else if (a != - TMath::Infinity() && b == TMath::Infinity())
2662 result = iod.IntegralUp(a);
2663 else if (a == - TMath::Infinity() && b == TMath::Infinity())
2664 result = iod.Integral();
2665 error = iod.Error();
2666 status = iod.Status();
2667 } else {
2669 if (a != - TMath::Infinity() && b != TMath::Infinity())
2670 result = iod.Integral(a, b);
2671 else if (a == - TMath::Infinity() && b != TMath::Infinity())
2672 result = iod.IntegralLow(b);
2673 else if (a != - TMath::Infinity() && b == TMath::Infinity())
2674 result = iod.IntegralUp(a);
2675 else if (a == - TMath::Infinity() && b == TMath::Infinity())
2676 result = iod.Integral();
2677 error = iod.Error();
2678 status = iod.Status();
2679 }
2680 if (status != 0) {
2682 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);
2683 TString msg("\t\tFunction Parameters = {");
2684 for (int ipar = 0; ipar < GetNpar(); ++ipar) {
2685 msg += TString::Format(" %s = %f ", GetParName(ipar), GetParameter(ipar));
2686 if (ipar < GetNpar() - 1) msg += TString(",");
2687 else msg += TString("}");
2688 }
2689 Info("IntegralOneDim", "%s", msg.Data());
2690 }
2691 return result;
2692}
2693
2694////////////////////////////////////////////////////////////////////////////////
2695/// Return Error on Integral of a parametric function between a and b
2696/// due to the parameter uncertainties and their covariance matrix from the fit.
2697/// In addition to the integral limits, this method takes as input a pointer to the fitted parameter values
2698/// and a pointer the covariance matrix from the fit. These pointers should be retrieved from the
2699/// previously performed fit using the TFitResult class.
2700/// Note that to get the TFitResult, te fit should be done using the fit option `S`.
2701/// Example:
2702/// ~~~~{.cpp}
2703/// TFitResultPtr r = histo->Fit(func, "S");
2704/// func->IntegralError(x1,x2,r->GetParams(), r->GetCovarianceMatrix()->GetMatrixArray() );
2705/// ~~~~
2706///
2707/// IMPORTANT NOTE1:
2708///
2709/// A null pointer to the parameter values vector and to the covariance matrix can be passed.
2710/// In this case, when the parameter values pointer is null, the parameter values stored in this
2711/// TF1 function object are used in the integral error computation.
2712/// When the poassed pointer to the covariance matrix is null, a covariance matrix from the last fit is retrieved
2713/// from a global fitter instance when it exists. Note that the global fitter instance
2714/// esists only when ROOT is not running with multi-threading enabled (ROOT::IsImplicitMTEnabled() == True).
2715/// When the ovariance matrix from the last fit cannot be retrieved, an error message is printed and a zero value is
2716/// returned.
2717///
2718///
2719/// IMPORTANT NOTE2:
2720///
2721/// When no covariance matrix is passed and in the meantime a fit is done
2722/// using another function, the routine will signal an error and it will return zero only
2723/// when the number of fit parameter is different than the values stored in TF1 (TF1::GetNpar() ).
2724/// In the case that npar is the same, an incorrect result is returned.
2725///
2726/// IMPORTANT NOTE3:
2727///
2728/// The user must pass a pointer to the elements of the full covariance matrix
2729/// dimensioned with the right size (npar*npar), where npar is the total number of parameters (TF1::GetNpar()),
2730/// including also the fixed parameters. The covariance matrix must be retrieved from the TFitResult class as
2731/// shown above and not from TVirtualFitter::GetCovarianceMatrix() function.
2732
2734{
2735 Double_t x1[1];
2736 Double_t x2[1];
2737 x1[0] = a, x2[0] = b;
2738 return ROOT::TF1Helper::IntegralError(this, 1, x1, x2, params, covmat, epsilon);
2739}
2740
2741////////////////////////////////////////////////////////////////////////////////
2742/// Return Error on Integral of a parametric function with dimension larger than one
2743/// between a[] and b[] due to the parameters uncertainties.
2744/// For a TF1 with dimension larger than 1 (for example a TF2 or TF3)
2745/// TF1::IntegralMultiple is used for the integral calculation
2746///
2747/// In addition to the integral limits, this method takes as input a pointer to the fitted parameter values
2748/// and a pointer the covariance matrix from the fit. These pointers should be retrieved from the
2749/// previously performed fit using the TFitResult class.
2750/// Note that to get the TFitResult, te fit should be done using the fit option `S`.
2751/// Example:
2752/// ~~~~{.cpp}
2753/// TFitResultPtr r = histo2d->Fit(func2, "S");
2754/// func2->IntegralError(a,b,r->GetParams(), r->GetCovarianceMatrix()->GetMatrixArray() );
2755/// ~~~~
2756///
2757/// IMPORTANT NOTE1:
2758///
2759/// A null pointer to the parameter values vector and to the covariance matrix can be passed.
2760/// In this case, when the parameter values pointer is null, the parameter values stored in this
2761/// TF1 function object are used in the integral error computation.
2762/// When the poassed pointer to the covariance matrix is null, a covariance matrix from the last fit is retrieved
2763/// from a global fitter instance when it exists. Note that the global fitter instance
2764/// esists only when ROOT is not running with multi-threading enabled (ROOT::IsImplicitMTEnabled() == True).
2765/// When the ovariance matrix from the last fit cannot be retrieved, an error message is printed and a zero value is
2766/// returned.
2767///
2768///
2769/// IMPORTANT NOTE2:
2770///
2771/// When no covariance matrix is passed and in the meantime a fit is done
2772/// using another function, the routine will signal an error and it will return zero only
2773/// when the number of fit parameter is different than the values stored in TF1 (TF1::GetNpar() ).
2774/// In the case that npar is the same, an incorrect result is returned.
2775///
2776/// IMPORTANT NOTE3:
2777///
2778/// The user must pass a pointer to the elements of the full covariance matrix
2779/// dimensioned with the right size (npar*npar), where npar is the total number of parameters (TF1::GetNpar()),
2780/// including also the fixed parameters. The covariance matrix must be retrieved from the TFitResult class as
2781/// shown above and not from TVirtualFitter::GetCovarianceMatrix() function.
2782
2783Double_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)
2784{
2785 return ROOT::TF1Helper::IntegralError(this, n, a, b, params, covmat, epsilon);
2786}
2787
2788#ifdef INTHEFUTURE
2789////////////////////////////////////////////////////////////////////////////////
2790/// Gauss-Legendre integral, see CalcGaussLegendreSamplingPoints
2791
2793{
2794 if (!g) return 0;
2795 return IntegralFast(g->GetN(), g->GetX(), g->GetY(), a, b, params);
2796}
2797#endif
2798
2799
2800////////////////////////////////////////////////////////////////////////////////
2801/// Gauss-Legendre integral, see CalcGaussLegendreSamplingPoints
2802
2803Double_t TF1::IntegralFast(Int_t num, Double_t * /* x */, Double_t * /* w */, Double_t a, Double_t b, Double_t *params, Double_t epsilon)
2804{
2805 // Now x and w are not used!
2806
2808 if (params)
2809 wf1.SetParameters(params);
2811 gli.SetFunction(wf1);
2812 return gli.Integral(a, b);
2813
2814}
2815
2816
2817////////////////////////////////////////////////////////////////////////////////
2818/// See more general prototype below.
2819/// This interface kept for back compatibility
2820/// It is recommended to use the other interface where one can specify also epsabs and the maximum number of
2821/// points
2822
2824{
2828 if (ifail > 0) {
2829 Warning("IntegralMultiple", "failed code=%d, ", ifail);
2830 }
2831 return result;
2832}
2833
2834
2835////////////////////////////////////////////////////////////////////////////////
2836/// This function computes, to an attempted specified accuracy, the value of
2837/// the integral
2838///
2839/// \param[in] n Number of dimensions [2,15]
2840/// \param[in] a,b One-dimensional arrays of length >= N . On entry A[i], and B[i],
2841/// contain the lower and upper limits of integration, respectively.
2842/// \param[in] maxpts Maximum number of function evaluations to be allowed.
2843/// maxpts >= 2^n +2*n*(n+1) +1
2844/// if maxpts<minpts, maxpts is set to 10*minpts
2845/// \param[in] epsrel Specified relative accuracy.
2846/// \param[in] epsabs Specified absolute accuracy.
2847/// The integration algorithm will attempt to reach either the relative or the absolute accuracy.
2848/// In case the maximum function called is reached the algorithm will stop earlier without having reached
2849/// the desired accuracy
2850///
2851/// \param[out] relerr Contains, on exit, an estimation of the relative accuracy of the result.
2852/// \param[out] nfnevl number of function evaluations performed.
2853/// \param[out] ifail
2854/// \parblock
2855/// 0 Normal exit. At least minpts and at most maxpts calls to the function were performed.
2856///
2857/// 1 maxpts is too small for the specified accuracy eps. The result and relerr contain the values obtainable for the
2858/// specified value of maxpts.
2859///
2860/// 3 n<2 or n>15
2861/// \endparblock
2862///
2863/// Method:
2864///
2865/// The default method used is the Genz-Mallik adaptive multidimensional algorithm
2866/// using the class ROOT::Math::AdaptiveIntegratorMultiDim (see the reference documentation of the class)
2867///
2868/// Other methods can be used by setting ROOT::Math::IntegratorMultiDimOptions::SetDefaultIntegrator()
2869/// to different integrators.
2870/// Other possible integrators are MC integrators based on the ROOT::Math::GSLMCIntegrator class
2871/// Possible methods are : Vegas, Miser or Plain
2872/// IN case of MC integration the accuracy is determined by the number of function calls, one should be
2873/// careful not to use a too large value of maxpts
2874///
2875
2877{
2879
2880 double result = 0;
2885 //aimd.SetMinPts(minpts); // use default minpts ( n^2 + 2 * n * (n+1) +1 )
2886 result = aimd.Integral(a, b);
2887 relerr = aimd.RelError();
2888 nfnevl = aimd.NEval();
2889 ifail = aimd.Status();
2890 } else {
2891 // use default abs tolerance = relative tolerance
2893 result = imd.Integral(a, b);
2894 relerr = (result != 0) ? imd.Error() / std::abs(result) : imd.Error();
2895 nfnevl = 0;
2896 ifail = imd.Status();
2897 }
2898
2899
2900 return result;
2901}
2902
2903
2904////////////////////////////////////////////////////////////////////////////////
2905/// Return kTRUE if the function is valid
2906
2908{
2909 if (fFormula) return fFormula->IsValid();
2910 if (fMethodCall) return fMethodCall->IsValid();
2911 // function built on compiled functors are always valid by definition
2912 // (checked at compiled time)
2913 // invalid is a TF1 where the functor is null pointer and has not been saved
2914 if (!fFunctor && fSave.empty()) return kFALSE;
2915 return kTRUE;
2916}
2917
2918
2919//______________________________________________________________________________
2920
2921
2923{
2924 if (fType == EFType::kFormula) {
2925 printf("Formula based function: %s \n", GetName());
2927 fFormula->Print(option);
2928 } else if (fType > 0) {
2930 printf("Interpreted based function: %s(double *x, double *p). Ndim = %d, Npar = %d \n", GetName(), GetNdim(),
2931 GetNpar());
2932 else if (fType == EFType::kCompositionFcn) {
2933 printf("Composition based function: %s. Ndim = %d, Npar = %d \n", GetName(), GetNdim(), GetNpar());
2934 if (!fComposition)
2935 printf("fComposition not found!\n"); // this would be bad
2936 } else {
2937 if (fFunctor)
2938 printf("Compiled based function: %s based on a functor object. Ndim = %d, Npar = %d\n", GetName(),
2939 GetNdim(), GetNpar());
2940 else {
2941 printf("Function based on a list of points from a compiled based function: %s. Ndim = %d, Npar = %d, Npx "
2942 "= %zu\n",
2943 GetName(), GetNdim(), GetNpar(), fSave.size());
2944 if (fSave.empty())
2945 Warning("Print", "Function %s is based on a list of points but list is empty", GetName());
2946 }
2947 }
2948 TString opt(option);
2949 opt.ToUpper();
2950 if (opt.Contains("V")) {
2951 // print list of parameters
2952 if (fNpar > 0) {
2953 printf("List of Parameters: \n");
2954 for (int i = 0; i < fNpar; ++i)
2955 printf(" %20s = %10f \n", GetParName(i), GetParameter(i));
2956 }
2957 if (!fSave.empty()) {
2958 // print list of saved points
2959 printf("List of Saved points (N=%d): \n", int(fSave.size()));
2960 for (auto &x : fSave)
2961 printf("( %10f ) ", x);
2962 printf("\n");
2963 }
2964 }
2965 }
2966 if (fHistogram) {
2967 printf("Contained histogram\n");
2969 }
2970}
2971
2972////////////////////////////////////////////////////////////////////////////////
2973/// Paint this function with its current attributes.
2974/// The function is going to be converted in an histogram and the corresponding
2975/// histogram is painted.
2976/// The painted histogram can be retrieved calling afterwards the method TF1::GetHistogram()
2977
2979{
2980 fgCurrent = this;
2981
2982 TString opt0 = option, opt = option, optSAME;
2983 opt.ToLower();
2984
2985 if (opt.Contains("sames"))
2986 optSAME = "sames";
2987 else if (opt.Contains("same"))
2988 optSAME = "same";
2989 if (optSAME.Length())
2990 opt.ReplaceAll(optSAME, "");
2991 opt.ReplaceAll(' ', "");
2992
2994 if (gPad) {
2995 pmin = gPad->PadtoX(gPad->GetUxmin());
2996 pmax = gPad->PadtoX(gPad->GetUxmax());
2997 }
2998 if (optSAME.Length()) {
2999 // Completely outside
3000 if (xmax < pmin) return;
3001 if (xmin > pmax) return;
3002 }
3003
3004 // create an histogram using the function content (re-use it if already existing)
3006
3007 auto is_pfc = opt0.Index("PFC"); // Automatic Fill Color
3008 auto is_plc = opt0.Index("PLC"); // Automatic Line Color
3009 auto is_pmc = opt0.Index("PMC"); // Automatic Marker Color
3010 if (is_pfc != kNPOS || is_plc != kNPOS || is_pmc != kNPOS) {
3011 Int_t i = gPad->NextPaletteColor();
3012 if (is_pfc != kNPOS) { opt0.Replace(is_pfc, 3, " "); fHistogram->SetFillColor(i); }
3013 if (is_plc != kNPOS) { opt0.Replace(is_plc, 3, " "); fHistogram->SetLineColor(i); }
3014 if (is_pmc != kNPOS) { opt0.Replace(is_pmc, 3, " "); fHistogram->SetMarkerColor(i); }
3015 }
3016
3017 // set the optimal minimum and maximum
3020 if (minimum <= 0 && gPad && gPad->GetLogy()) minimum = -1111; // This can happen when switching from lin to log scale.
3021 if (gPad && gPad->GetUymin() < fHistogram->GetMinimum() &&
3022 !fHistogram->TestBit(TH1::kIsZoomed)) minimum = -1111; // This can happen after unzooming a fit.
3023 if (minimum == -1111) { // This can happen after unzooming.
3026 } else {
3027 minimum = fMinimum;
3028 // Optimize the computation of the scale in Y in case the min/max of the
3029 // function oscillate around a constant value
3030 if (minimum == -1111) {
3031 Double_t hmin;
3032 if (optSAME.Length() && gPad) hmin = gPad->GetUymin();
3033 else hmin = fHistogram->GetMinimum();
3034 if (hmin > 0) {
3035 Double_t hmax;
3037 if (optSAME.Length() && gPad) hmax = gPad->GetUymax();
3038 else hmax = fHistogram->GetMaximum();
3039 hmin -= 0.05 * (hmax - hmin);
3040 if (hmin < 0) hmin = 0;
3042 minimum = hmin;
3043 }
3044 }
3045 }
3047 }
3048 if (maximum == -1111) {
3051 } else {
3052 maximum = fMaximum;
3053 }
3055 }
3056
3057 // Draw the histogram.
3058 if (!gPad) return;
3059 if (opt.Length() == 0) {
3060 optSAME.Prepend("lf");
3061 fHistogram->Paint(optSAME.Data());
3062 } else {
3063 fHistogram->Paint(opt0.Data());
3064 }
3065}
3066
3067////////////////////////////////////////////////////////////////////////////////
3068/// Create histogram with bin content equal to function value
3069/// computed at the bin center
3070/// This histogram will be used to paint the function
3071/// A re-creation is forced and a new histogram is done if recreate=true
3072
3074{
3075 Int_t i;
3076 Double_t xv[1];
3077
3078 TH1 *histogram = nullptr;
3079
3080
3081 // Create a temporary histogram and fill each channel with the function value
3082 // Preserve axis titles
3083 TString xtitle = "";
3084 TString ytitle = "";
3085 char *semicol = (char *)strstr(GetTitle(), ";");
3086 if (semicol) {
3088 char *ctemp = new char[nxt];
3089 strlcpy(ctemp, semicol + 1, nxt);
3090 semicol = (char *)strstr(ctemp, ";");
3091 if (semicol) {
3092 *semicol = 0;
3093 ytitle = semicol + 1;
3094 }
3095 xtitle = ctemp;
3096 delete [] ctemp;
3097 }
3098 if (fHistogram) {
3099 // delete previous histograms if were done if done in different mode
3103 if (!gPad->GetLogx() && test_logx) {
3104 delete fHistogram;
3105 fHistogram = nullptr;
3106 recreate = kTRUE;
3107 }
3108 if (gPad->GetLogx() && !test_logx) {
3109 delete fHistogram;
3110 fHistogram = nullptr;
3111 recreate = kTRUE;
3112 }
3113 }
3114
3115 if (fHistogram && !recreate) {
3118 } else {
3119 // If logx, we must bin in logx and not in x
3120 // otherwise in case of several decades, one gets wrong results.
3121 if (xmin > 0 && gPad && gPad->GetLogx()) {
3122 Double_t *xbins = new Double_t[fNpx + 1];
3126 for (i = 0; i <= fNpx; i++) {
3127 xbins[i] = gPad->PadtoX(xlogmin + i * dlogx);
3128 }
3129 histogram = new TH1D("Func", GetTitle(), fNpx, xbins);
3130 histogram->SetBit(TH1::kLogX);
3131 delete [] xbins;
3132 } else {
3133 histogram = new TH1D("Func", GetTitle(), fNpx, xmin, xmax);
3134 }
3135 if (fMinimum != -1111) histogram->SetMinimum(fMinimum);
3136 if (fMaximum != -1111) histogram->SetMaximum(fMaximum);
3137 histogram->SetDirectory(nullptr);
3138 }
3140
3141 // Restore axis titles.
3142 histogram->GetXaxis()->SetTitle(xtitle.Data());
3143 histogram->GetYaxis()->SetTitle(ytitle.Data());
3144 Double_t *parameters = GetParameters();
3145
3146 InitArgs(xv, parameters);
3147 for (i = 1; i <= fNpx; i++) {
3148 xv[0] = histogram->GetBinCenter(i);
3149 histogram->SetBinContent(i, EvalPar(xv, parameters));
3150 }
3151
3152 // Copy Function attributes to histogram attributes.
3153 histogram->SetBit(TH1::kNoStats);
3154 histogram->Sumw2(kFALSE);
3155 histogram->SetLineColor(GetLineColor());
3156 histogram->SetLineStyle(GetLineStyle());
3157 histogram->SetLineWidth(GetLineWidth());
3158 histogram->SetFillColor(GetFillColor());
3159 histogram->SetFillStyle(GetFillStyle());
3160 histogram->SetMarkerColor(GetMarkerColor());
3161 histogram->SetMarkerStyle(GetMarkerStyle());
3162 histogram->SetMarkerSize(GetMarkerSize());
3163
3164 // update saved histogram in case it was deleted or if it is the first time the method is called
3165 // for example when called from TF1::GetHistogram()
3167 return histogram;
3168
3169}
3170
3171
3172////////////////////////////////////////////////////////////////////////////////
3173/// Release parameter number ipar during a fit operation.
3174/// After releasing it, the parameter
3175/// can vary freely in the fit. The parameter limits are reset to 0,0.
3176
3178{
3179 if (ipar < 0 || ipar > GetNpar() - 1) return;
3180 SetParLimits(ipar, 0, 0);
3181}
3182
3183
3184////////////////////////////////////////////////////////////////////////////////
3185/// Save values of function in array fSave
3186
3188{
3189 if (!fSave.empty())
3190 fSave.clear();
3191
3192 Double_t *parameters = GetParameters();
3193 //if (fSave != 0) {delete [] fSave; fSave = 0;}
3195 //if parent is a histogram save the function at the center of the bins
3196 if ((xmin > 0 && xmax > 0) && TMath::Abs(TMath::Log10(xmax / xmin) > TMath::Log10(fNpx))) {
3197 TH1 *h = (TH1 *)fParent;
3198 Int_t bin1 = h->GetXaxis()->FindBin(xmin);
3199 Int_t bin2 = h->GetXaxis()->FindBin(xmax);
3200 int nsave = bin2 - bin1 + 4;
3201 fSave.resize(nsave);
3202 Double_t xv[1];
3203
3204 InitArgs(xv, parameters);
3205 for (Int_t i = bin1; i <= bin2; i++) {
3206 xv[0] = h->GetXaxis()->GetBinCenter(i);
3207 fSave[i - bin1] = EvalPar(xv, parameters);
3208 }
3209 fSave[nsave - 3] = xmin;
3210 fSave[nsave - 2] = xmax;
3211 fSave[nsave - 1] = xmax;
3212 return;
3213 }
3214 }
3215
3216 Int_t npx = fNpx;
3217 if (npx <= 0)
3218 return;
3219
3220 Double_t dx = (xmax - xmin) / fNpx;
3221 if (dx <= 0) {
3222 dx = (fXmax - fXmin) / fNpx;
3223 npx--;
3224 xmin = fXmin + 0.5 * dx;
3225 xmax = fXmax - 0.5 * dx;
3226 }
3227 if (npx <= 0)
3228 return;
3229 fSave.resize(npx + 3);
3230 Double_t xv[1];
3231 InitArgs(xv, parameters);
3232 for (Int_t i = 0; i <= npx; i++) {
3233 xv[0] = xmin + dx * i;
3234 fSave[i] = EvalPar(xv, parameters);
3235 }
3236 fSave[npx + 1] = xmin;
3237 fSave[npx + 2] = xmax;
3238}
3239
3240
3241////////////////////////////////////////////////////////////////////////////////
3242/// Provide variable name for function for saving as primitive
3243/// When TH1 or TGraph stores list of functions, it applies special coding of created variable names
3244
3246{
3247 thread_local Int_t storeNumber = 0;
3249 const char *l = strstr(option, "#");
3250 Int_t number = ++storeNumber;
3251 if (l != nullptr)
3252 sscanf(l + 1, "%d", &number);
3253
3254 funcName += number;
3255 return gInterpreter->MapCppName(funcName);
3256}
3257
3258
3259////////////////////////////////////////////////////////////////////////////////
3260/// Save primitive as a C++ statement(s) on output stream out
3261
3262void TF1::SavePrimitive(std::ostream &out, Option_t *option /*= ""*/)
3263{
3264 // Save the function as C code independent from ROOT.
3265 if (option && strstr(option, "cc")) {
3266 out << "double " << GetName() << "(double xv) {\n";
3267 Double_t dx = (fXmax - fXmin) / (fNpx - 1);
3268 out << " double x[" << fNpx << "] = {\n";
3269 out << " ";
3270 Int_t n = 0;
3271 for (Int_t i = 0; i < fNpx; i++) {
3272 out << fXmin + dx * i;
3273 if (i < fNpx - 1)
3274 out << ", ";
3275 if (n++ == 10) {
3276 out << "\n ";
3277 n = 0;
3278 }
3279 }
3280 out << "\n";
3281 out << " };\n";
3282 out << " double y[" << fNpx << "] = {\n";
3283 out << " ";
3284 n = 0;
3285 for (Int_t i = 0; i < fNpx; i++) {
3286 out << Eval(fXmin + dx * i);
3287 if (i < fNpx - 1)
3288 out << ", ";
3289 if (n++ == 10) {
3290 out << "\n ";
3291 n = 0;
3292 }
3293 }
3294 out << "\n";
3295 out << " };\n";
3296 out << " if (xv<x[0]) return y[0];\n";
3297 out << " if (xv>x[" << fNpx - 1 << "]) return y[" << fNpx - 1 << "];\n";
3298 out << " int i, j=0;\n";
3299 out << " for (i=1; i<" << fNpx << "; i++) { if (xv < x[i]) break; j++; }\n";
3300 out << " return y[j] + (y[j + 1] - y[j]) / (x[j + 1] - x[j]) * (xv - x[j]);\n";
3301 out << "}\n";
3302 return;
3303 }
3304
3306
3307 const char *addToGlobList = fParent ? ", TF1::EAddToList::kNo" : ", TF1::EAddToList::kDefault";
3308
3309 out << " \n";
3310 if (!fType) {
3311 out << " TF1 *" << f1Name << " = new TF1(\"" << GetName() << "\", \""
3312 << TString(GetTitle()).ReplaceSpecialCppChars() << "\", " << fXmin << "," << fXmax << addToGlobList << ");\n";
3313 if (fNpx != 100)
3314 out << " " << f1Name << "->SetNpx(" << fNpx << ");\n";
3315 } else {
3316 out << " TF1 *" << f1Name << " = new TF1(\"" << "*" << GetName() << "\", " << fXmin << "," << fXmax
3317 << "," << GetNpar() << ");\n";
3318 out << " // The original function : " << GetTitle() << " had originally been created by:\n";
3319 out << " // TF1 *" << GetName() << " = new TF1(\"" << GetName() << "\", \"" << GetTitle() << "\", "
3320 << fXmin << "," << fXmax << "," << GetNpar() << ", 1" << addToGlobList << ");\n";
3321 out << " " << f1Name << "->SetRange(" << fXmin << "," << fXmax << ");\n";
3323 if (fNpx != 100)
3324 out << " " << f1Name << "->SetNpx(" << fNpx << ");\n";
3325
3327 if (fSave.empty() && (fType != EFType::kCompositionFcn)) {
3328 saved = kTRUE;
3329 Save(fXmin, fXmax, 0, 0, 0, 0);
3330 }
3331 if (!fSave.empty()) {
3332 TString vect = SavePrimitiveVector(out, f1Name, fSave.size(), fSave.data());
3333 out << " for (int n = 0; n < " << fSave.size() << "; n++)\n";
3334 out << " " << f1Name << "->SetSavedPoint(n, " << vect << "[n]);\n";
3335 }
3336
3337 if (saved)
3338 fSave.clear();
3339 }
3340
3341 if (TestBit(kNotDraw))
3342 out << " " << f1Name.Data() << "->SetBit(TF1::kNotDraw);\n";
3343
3344 SaveFillAttributes(out, f1Name, -1, 0);
3345 SaveMarkerAttributes(out, f1Name, -1, -1, -1);
3346 SaveLineAttributes(out, f1Name, -1, -1, -1);
3347
3348 if (GetChisquare() != 0) {
3349 out << " " << f1Name << "->SetChisquare(" << GetChisquare() << ");\n";
3350 out << " " << f1Name << "->SetNDF(" << GetNDF() << ");\n";
3351 }
3352
3354 for (Int_t i = 0; i < GetNpar(); i++) {
3355 out << " " << f1Name << "->SetParameter(" << i << ", " << GetParameter(i) << ");\n";
3356 out << " " << f1Name << "->SetParError(" << i << ", " << GetParError(i) << ");\n";
3358 out << " " << f1Name << "->SetParLimits(" << i << ", " << parmin << ", " << parmax << ");\n";
3359 }
3360
3361 if (fHistogram && !strstr(option, "same")) {
3362 GetXaxis()->SaveAttributes(out, f1Name, "->GetXaxis()");
3363 GetYaxis()->SaveAttributes(out, f1Name, "->GetYaxis()");
3364 }
3365
3367}
3368
3369////////////////////////////////////////////////////////////////////////////////
3370/// Static function setting the current function.
3371/// the current function may be accessed in static C-like functions
3372/// when fitting or painting a function.
3373
3375{
3376 fgCurrent = f1;
3377}
3378
3379////////////////////////////////////////////////////////////////////////////////
3380/// Set the result from the fit
3381/// parameter values, errors, chi2, etc...
3382/// Optionally a pointer to a vector (with size fNpar) of the parameter indices in the FitResult can be passed
3383/// This is useful in the case of a combined fit with different functions, and the FitResult contains the global result
3384/// By default it is assume that indpar = {0,1,2,....,fNpar-1}.
3385
3387{
3388 Int_t npar = GetNpar();
3389 if (result.IsEmpty()) {
3390 Warning("SetFitResult", "Empty Fit result - nothing is set in TF1");
3391 return;
3392 }
3393 if (indpar == nullptr && npar != (int) result.NPar()) {
3394 Error("SetFitResult", "Invalid Fit result passed - number of parameter is %d , different than TF1::GetNpar() = %d", npar, result.NPar());
3395 return;
3396 }
3397 if (result.Chi2() > 0)
3398 SetChisquare(result.Chi2());
3399 else
3400 SetChisquare(result.MinFcnValue());
3401
3402 SetNDF(result.Ndf());
3403 SetNumberFitPoints(result.Ndf() + result.NFreeParameters());
3404
3405
3406 for (Int_t i = 0; i < npar; ++i) {
3407 Int_t ipar = (indpar != nullptr) ? indpar[i] : i;
3408 if (ipar < 0) continue;
3409 GetParameters()[i] = result.Parameter(ipar);
3410 // in case errors are not present do not set them
3411 if (ipar < (int) result.Errors().size())
3412 fParErrors[i] = result.Error(ipar);
3413 }
3414 //invalidate cached integral since parameters have changed
3415 Update();
3416
3417}
3418
3419
3420////////////////////////////////////////////////////////////////////////////////
3421/// Set the maximum value along Y for this function
3422/// In case the function is already drawn, set also the maximum in the
3423/// helper histogram
3424
3426{
3427 fMaximum = maximum;
3429 if (gPad) gPad->Modified();
3430}
3431
3432
3433////////////////////////////////////////////////////////////////////////////////
3434/// Set the minimum value along Y for this function
3435/// In case the function is already drawn, set also the minimum in the
3436/// helper histogram
3437
3439{
3440 fMinimum = minimum;
3442 if (gPad) gPad->Modified();
3443}
3444
3445
3446////////////////////////////////////////////////////////////////////////////////
3447/// Set the number of degrees of freedom
3448/// ndf should be the number of points used in a fit - the number of free parameters
3449
3451{
3452 fNDF = ndf;
3453}
3454
3455
3456////////////////////////////////////////////////////////////////////////////////
3457/// Set the number of points used to draw the function
3458///
3459/// The default number of points along x is 100 for 1-d functions and 30 for 2-d/3-d functions
3460/// You can increase this value to get a better resolution when drawing
3461/// pictures with sharp peaks or to get a better result when using TF1::GetRandom
3462/// the minimum number of points is 4, the maximum is 10000000 for 1-d and 10000 for 2-d/3-d functions
3463
3465{
3466 const Int_t minPx = 4;
3467 Int_t maxPx = 10000000;
3468 if (GetNdim() > 1) maxPx = 10000;
3469 if (npx >= minPx && npx <= maxPx) {
3470 fNpx = npx;
3471 } else {
3472 if (npx < minPx) fNpx = minPx;
3473 if (npx > maxPx) fNpx = maxPx;
3474 Warning("SetNpx", "Number of points must be >=%d && <= %d, fNpx set to %d", minPx, maxPx, fNpx);
3475 }
3476 Update();
3477}
3478////////////////////////////////////////////////////////////////////////////////
3479/// Set name of parameter number ipar
3480
3481void TF1::SetParName(Int_t ipar, const char *name)
3482{
3483 if (fFormula) {
3484 if (ipar < 0 || ipar >= GetNpar()) return;
3485 fFormula->SetParName(ipar, name);
3486 } else
3487 fParams->SetParName(ipar, name);
3488}
3489
3490////////////////////////////////////////////////////////////////////////////////
3491/// Set up to 10 parameter names.
3492/// Empty strings will be skipped, meaning that the corresponding name will not be changed.
3493
3494void TF1::SetParNames(const char *name0, const char *name1, const char *name2, const char *name3, const char *name4,
3495 const char *name5, const char *name6, const char *name7, const char *name8, const char *name9, const char *name10)
3496{
3497 // Note: this is not made a variadic template method because it would
3498 // presumably break the context menu in the TBrowser. Also, probably this
3499 // method should not be virtual, because if the user wants to change
3500 // parameter name setting behavior, the SetParName() method can be
3501 // overridden.
3502 if (fFormula)
3504 else
3505 fParams->SetParNames(name0, name1, name2, name3, name4, name5, name6, name7, name8, name9, name10);
3506}
3507////////////////////////////////////////////////////////////////////////////////
3508/// Set error for parameter number ipar
3509
3511{
3512 if (ipar < 0 || ipar > GetNpar() - 1) return;
3513 fParErrors[ipar] = error;
3514}
3515
3516
3517////////////////////////////////////////////////////////////////////////////////
3518/// Set errors for all active parameters
3519/// when calling this function, the array errors must have at least fNpar values
3520
3522{
3523 if (!errors) return;
3524 for (Int_t i = 0; i < GetNpar(); i++) fParErrors[i] = errors[i];
3525}
3526
3527
3528////////////////////////////////////////////////////////////////////////////////
3529/// Set lower and upper limits for parameter ipar.
3530/// The specified limits will be used in a fit operation.
3531/// Note that when this function is a pre-defined function (e.g. gaus)
3532/// one needs to use the fit option "B" to have the limits used in the fit.
3533/// See TH1::Fit(TF1*, Option_t *, Option_t *, Double_t, Double_t) for the fitting documentation
3534/// and the [fitting options](\ref HFitOpt)
3535///
3536/// To fix a parameter, use TF1::FixParameter
3537
3539{
3540 Int_t npar = GetNpar();
3541 if (ipar < 0 || ipar > npar - 1) return;
3542 if (int(fParMin.size()) != npar) {
3543 fParMin.resize(npar);
3544 }
3545 if (int(fParMax.size()) != npar) {
3546 fParMax.resize(npar);
3547 }
3548 fParMin[ipar] = parmin;
3549 fParMax[ipar] = parmax;
3550}
3551
3552
3553////////////////////////////////////////////////////////////////////////////////
3554/// Initialize the upper and lower bounds to draw the function.
3555///
3556/// The function range is also used in an histogram fit operation
3557/// when the option "R" is specified.
3558
3560{
3561 fXmin = xmin;
3562 fXmax = xmax;
3564 fComposition->SetRange(xmin, xmax); // automatically updates sub-functions
3565 }
3566 Update();
3567}
3568
3569
3570////////////////////////////////////////////////////////////////////////////////
3571/// Restore value of function saved at point
3572
3574{
3575 if (fSave.empty()) {
3576 fSave.resize(fNpx + 3);
3577 }
3578 if (point < 0 || point >= int(fSave.size())) return;
3579 fSave[point] = value;
3580}
3581
3582
3583////////////////////////////////////////////////////////////////////////////////
3584/// Set function title
3585/// if title has the form "fffffff;xxxx;yyyy", it is assumed that
3586/// the function title is "fffffff" and "xxxx" and "yyyy" are the
3587/// titles for the X and Y axis respectively.
3588
3589void TF1::SetTitle(const char *title)
3590{
3591 if (!title) return;
3592 fTitle = title;
3593 if (!fHistogram) return;
3594 fHistogram->SetTitle(title);
3595 if (gPad) gPad->Modified();
3596}
3597
3598
3599////////////////////////////////////////////////////////////////////////////////
3600/// Stream a class object.
3601
3603{
3604 if (b.IsReading()) {
3605 UInt_t R__s, R__c;
3606 Version_t v = b.ReadVersion(&R__s, &R__c);
3607 // process new version with new TFormula class which is contained in TF1
3608 //printf("reading TF1....- version %d..\n",v);
3609
3610 if (v > 7) {
3611 // new classes with new TFormula
3612 // need to register the objects
3613 b.ReadClassBuffer(TF1::Class(), this, v, R__s, R__c);
3614 if (!TestBit(kNotGlobal)) {
3616 gROOT->GetListOfFunctions()->Add(this);
3617 }
3618 return;
3619 } else {
3621 //printf("Reading TF1 as v5::TF1Data- version %d \n",v);
3622 fold.Streamer(b, v, R__s, R__c, TF1::Class());
3623 // convert old TF1 to new one
3624 ((TF1v5Convert *)this)->Convert(fold);
3625 }
3626 }
3627
3628 // Writing
3629 else {
3630 Int_t saved = 0;
3631 // save not-formula functions as array of points
3632 if (fType > 0 && fSave.empty() && fType != EFType::kCompositionFcn) {
3633 saved = 1;
3634 Save(fXmin, fXmax, 0, 0, 0, 0);
3635 }
3636 b.WriteClassBuffer(TF1::Class(), this);
3637
3638 // clear vector contents
3639 if (saved) {
3640 fSave.clear();
3641 }
3642 }
3643}
3644
3645
3646////////////////////////////////////////////////////////////////////////////////
3647/// Called by functions such as SetRange, SetNpx, SetParameters
3648/// to force the deletion of the associated histogram or Integral
3649
3651{
3652 if (fHistogram) {
3656 fHistogram->GetXaxis()->TAttAxis::Copy(attx);
3657 fHistogram->GetYaxis()->TAttAxis::Copy(atty);
3658
3659 delete fHistogram;
3660 fHistogram = nullptr;
3661 GetHistogram();
3662
3665 attx.Copy(*(fHistogram->GetXaxis()));
3666 atty.Copy(*(fHistogram->GetYaxis()));
3667 }
3668 if (!fIntegral.empty()) {
3669 fIntegral.clear();
3670 fAlpha.clear();
3671 fBeta.clear();
3672 fGamma.clear();
3673 }
3674 if (fNormalized) {
3675 // need to compute the integral of the not-normalized function
3676 fNormalized = false;
3678 fNormalized = true;
3679 } else
3680 fNormIntegral = 0;
3681
3682 // std::vector<double>x(fNdim);
3683 // if ((fType == 1) && !fFunctor->Empty()) (*fFunctor)x.data(), (Double_t*)fParams);
3685 // double-check that the parameters are correct
3686 fComposition->SetParameters(GetParameters());
3687
3688 fComposition->Update(); // should not be necessary, but just to be safe
3689 }
3690}
3691
3692////////////////////////////////////////////////////////////////////////////////
3693/// Static function to set the global flag to reject points
3694/// the fgRejectPoint global flag is tested by all fit functions
3695/// if TRUE the point is not included in the fit.
3696/// This flag can be set by a user in a fitting function.
3697/// The fgRejectPoint flag is reset by the TH1 and TGraph fitting functions.
3698
3703
3704
3705////////////////////////////////////////////////////////////////////////////////
3706/// See TF1::RejectPoint above
3707
3709{
3710 return fgRejectPoint;
3711}
3712
3713////////////////////////////////////////////////////////////////////////////////
3714/// Return nth moment of function between a and b
3715///
3716/// See TF1::Integral() for parameter definitions
3717
3719{
3720 // wrapped function in interface for integral calculation
3721 // using abs value of integral
3722
3723 TF1_EvalWrapper func(this, params, kTRUE, n);
3724
3726
3727 giod.SetFunction(func);
3728 giod.SetRelTolerance(epsilon);
3729
3730 Double_t norm = giod.Integral(a, b);
3731 if (norm == 0) {
3732 Error("Moment", "Integral zero over range");
3733 return 0;
3734 }
3735
3736 // calculate now integral of x^n f(x)
3737 // wrapped the member function EvalNum in interface required by integrator using the functor class
3739 giod.SetFunction(xnfunc);
3740
3741 Double_t res = giod.Integral(a, b) / norm;
3742
3743 return res;
3744}
3745
3746
3747////////////////////////////////////////////////////////////////////////////////
3748/// Return nth central moment of function between a and b
3749/// (i.e the n-th moment around the mean value)
3750///
3751/// See TF1::Integral() for parameter definitions
3752///
3753/// \author Gene Van Buren <gene@bnl.gov>
3754
3756{
3757 TF1_EvalWrapper func(this, params, kTRUE, n);
3758
3760
3761 giod.SetFunction(func);
3762 giod.SetRelTolerance(epsilon);
3763
3764 Double_t norm = giod.Integral(a, b);
3765 if (norm == 0) {
3766 Error("Moment", "Integral zero over range");
3767 return 0;
3768 }
3769
3770 // calculate now integral of xf(x)
3771 // wrapped the member function EvalFirstMom in interface required by integrator using the functor class
3773 giod.SetFunction(xfunc);
3774
3775 // estimate of mean value
3776 Double_t xbar = giod.Integral(a, b) / norm;
3777
3778 // use different mean value in function wrapper
3779 func.fX0 = xbar;
3781 giod.SetFunction(xnfunc);
3782
3783 Double_t res = giod.Integral(a, b) / norm;
3784 return res;
3785}
3786
3787
3788//______________________________________________________________________________
3789// some useful static utility functions to compute sampling points for IntegralFast
3790////////////////////////////////////////////////////////////////////////////////
3791/// Type safe interface (static method)
3792/// The number of sampling points are taken from the TGraph
3793
3794#ifdef INTHEFUTURE
3796{
3797 if (!g) return;
3798 CalcGaussLegendreSamplingPoints(g->GetN(), g->GetX(), g->GetY(), eps);
3799}
3800
3801
3802////////////////////////////////////////////////////////////////////////////////
3803/// Type safe interface (static method)
3804/// A TGraph is created with new with num points and the pointer to the
3805/// graph is returned by the function. It is the responsibility of the
3806/// user to delete the object.
3807/// if num is invalid (<=0) NULL is returned
3808
3810{
3811 if (num <= 0)
3812 return 0;
3813
3814 TGraph *g = new TGraph(num);
3815 CalcGaussLegendreSamplingPoints(g->GetN(), g->GetX(), g->GetY(), eps);
3816 return g;
3817}
3818#endif
3819
3820
3821////////////////////////////////////////////////////////////////////////////////
3822/// Type: unsafe but fast interface filling the arrays x and w (static method)
3823///
3824/// Given the number of sampling points this routine fills the arrays x and w
3825/// of length num, containing the abscissa and weight of the Gauss-Legendre
3826/// n-point quadrature formula.
3827///
3828/// Gauss-Legendre:
3829/** \f[
3830 W(x)=1 -1<x<1 \\
3831 (j+1)P_{j+1} = (2j+1)xP_j-jP_{j-1}
3832 \f]
3833**/
3834/// num is the number of sampling points (>0)
3835/// x and w are arrays of size num
3836/// eps is the relative precision
3837///
3838/// If num<=0 or eps<=0 no action is done.
3839///
3840/// Reference: Numerical Recipes in C, Second Edition
3841
3843{
3844 // This function is just kept like this for backward compatibility!
3845
3847 gli.GetWeightVectors(x, w);
3848
3849
3850}
3851
3852
3853/** \class TF1Parameters
3854TF1 Parameters class
3855*/
3856
3857////////////////////////////////////////////////////////////////////////////////
3858/// Returns the parameter number given a name
3859/// not very efficient but list of parameters is typically small
3860/// could use a map if needed
3861
3863{
3864 for (unsigned int i = 0; i < fParNames.size(); ++i) {
3865 if (fParNames[i] == std::string(name)) return i;
3866 }
3867 return -1;
3868}
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:47
Class for adaptive quadrature integration in multi-dimensions using rectangular regions.
User class for performing function minimization.
Class for finding the root of a one dimensional function using the Brent algorithm.
static ROOT::Math::Minimizer * CreateMinimizer(const std::string &minimizerType="", const std::string &algoType="")
static method to create the corresponding Minimizer given the string Supported Minimizers types are: ...
Definition Factory.cxx:63
Functor1D class for one-dimensional functions.
Definition Functor.h:97
User class for performing function integration.
User class for performing function integration.
Interface (abstract class) for generic functions objects of one-dimension Provides a method to evalua...
Definition IFunction.h:170
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:714
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:3862
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:3177
virtual void SetParError(Int_t ipar, Double_t error)
Set error for parameter number ipar.
Definition TF1.cxx:3510
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:3699
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:3842
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:3450
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:2733
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:2803
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:3425
void Print(Option_t *option="") const override
This method must be overridden when a class wants to print itself.
Definition TF1.cxx:2922
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:3650
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:3559
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:3245
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:3521
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:3073
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:3374
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:2556
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:3589
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:3494
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:3464
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:3602
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:2978
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:3718
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:3755
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:2876
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:3438
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:3538
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:3481
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:3262
virtual Bool_t IsValid() const
Return kTRUE if the function is valid.
Definition TF1.cxx:2907
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:3708
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:3187
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:3573
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:2646
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:3386
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:832
1-D histogram with a double per channel (see TH1 documentation)
Definition TH1.h:927
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:8965
Int_t DistancetoPrimitive(Int_t px, Int_t py) override
Compute distance from point px,py to a line.
Definition TH1.cxx:2794
void SetTitle(const char *title) override
Change/set the title.
Definition TH1.cxx:6753
virtual Double_t GetMinimumStored() const
Definition TH1.h:538
static TClass * Class()
@ kLogX
X-axis in log scale.
Definition TH1.h:407
@ kNoStats
Don't draw stats box.
Definition TH1.h:404
@ kIsZoomed
Bit set when zooming on Y axis.
Definition TH1.h:408
TAxis * GetXaxis()
Definition TH1.h:572
void Print(Option_t *option="") const override
Print some global quantities for this histogram.
Definition TH1.cxx:7044
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:8573
virtual void SetMaximum(Double_t maximum=-1111)
Definition TH1.h:653
TAxis * GetYaxis()
Definition TH1.h:573
virtual void SetMinimum(Double_t minimum=-1111)
Definition TH1.h:654
void Paint(Option_t *option="") override
Control routine to paint any kind of histograms.
Definition TH1.cxx:6241
virtual Double_t GetMaximumStored() const
Definition TH1.h:534
void ExecuteEvent(Int_t event, Int_t px, Int_t py) override
Execute action corresponding to one event.
Definition TH1.cxx:3211
TObject * Clone(const char *newname="") const override
Make a complete copy of the underlying object.
Definition TH1.cxx:2723
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:8663
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
static TString SavePrimitiveVector(std::ostream &out, const char *prefix, Int_t len, Double_t *arr, Bool_t empty_line=kFALSE)
Save array in the output stream "out" as vector.
Definition TObject.cxx:788
virtual void Warning(const char *method, const char *msgfmt,...) const
Issue warning message.
Definition TObject.cxx:1057
virtual void AppendPad(Option_t *option="")
Append graphics object to current pad.
Definition TObject.cxx:203
void SetBit(UInt_t f, Bool_t set)
Set or unset the user status bits as specified in f.
Definition TObject.cxx:864
virtual Bool_t InheritsFrom(const char *classname) const
Returns kTRUE if object inherits from class "classname".
Definition TObject.cxx:543
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition TObject.cxx:1071
void MakeZombie()
Definition TObject.h:53
static void SavePrimitiveDraw(std::ostream &out, const char *variable_name, Option_t *option=nullptr)
Save invocation of primitive Draw() method Skipped if option contains "nodraw" string.
Definition TObject.cxx:822
@ kCanDelete
if object in a list can be deleted
Definition TObject.h:68
virtual void Info(const char *method, const char *msgfmt,...) const
Issue info message.
Definition TObject.cxx:1045
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:712
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:640
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:251
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:199
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:348
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:124
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