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