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