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