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