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