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