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