24 #include "RConfigure.h"
51 TF1Parameters(Int_t npar) :
52 fParameters(std::vector<Double_t>(npar)),
53 fParNames(std::vector<std::string>(npar))
55 for (
int i = 0; i < npar; ++i) {
56 fParNames[i] = std::string(TString::Format(
"p%d", i).Data());
60 TF1Parameters(
const TF1Parameters &rhs) :
61 fParameters(rhs.fParameters),
62 fParNames(rhs.fParNames)
65 TF1Parameters &operator=(
const TF1Parameters &rhs)
67 if (&rhs ==
this)
return *
this;
68 fParameters = rhs.fParameters;
69 fParNames = rhs.fParNames;
72 virtual ~TF1Parameters() {}
75 Double_t GetParameter(Int_t iparam)
const
77 return (CheckIndex(iparam)) ? fParameters[iparam] : 0;
79 Double_t GetParameter(
const char *name)
const
81 return GetParameter(GetParNumber(name));
83 const Double_t *GetParameters()
const
85 return fParameters.data();
87 const std::vector<double> &ParamsVec()
const
92 Int_t GetParNumber(
const char *name)
const;
94 const char *GetParName(Int_t iparam)
const
96 return (CheckIndex(iparam)) ? fParNames[iparam].c_str() :
"";
101 void SetParameter(Int_t iparam, Double_t value)
103 if (!CheckIndex(iparam))
return;
104 fParameters[iparam] = value;
106 void SetParameters(
const Double_t *params)
108 std::copy(params, params + fParameters.size(), fParameters.begin());
110 void SetParameters(Double_t p0, Double_t p1, Double_t p2 = 0, Double_t p3 = 0, Double_t p4 = 0,
111 Double_t p5 = 0, Double_t p6 = 0, Double_t p7 = 0, Double_t p8 = 0,
112 Double_t p9 = 0, Double_t p10 = 0);
114 void SetParameter(
const char *name, Double_t value)
116 SetParameter(GetParNumber(name), value);
118 void SetParName(Int_t iparam,
const char *name)
120 if (!CheckIndex(iparam))
return;
121 fParNames[iparam] = std::string(name);
123 void SetParNames(
const char *name0 =
"p0",
const char *name1 =
"p1",
const char *name2 =
"p2",
124 const char *name3 =
"p3",
const char *name4 =
"p4",
const char *name5 =
"p5",
125 const char *name6 =
"p6",
const char *name7 =
"p7",
const char *name8 =
"p8",
126 const char *name9 =
"p9",
const char *name10 =
"p10");
130 ClassDef(TF1Parameters, 1)
133 bool CheckIndex(Int_t i)
const
135 return (i >= 0 && i <
int(fParameters.size()));
138 std::vector<Double_t> fParameters;
139 std::vector<std::string> fParNames;
148 static void Build(TF1 *f, Func func);
152 struct TF1Builder<Func *> {
153 static void Build(TF1 *f, Func *func);
159 struct GetFunctorType {
162 template<
typename F,
typename T>
163 struct GetFunctorType<T(F::*)(const T *, const double *)> {
167 template<
typename F,
typename T>
168 struct GetFunctorType<T(F::*)(const T *, const double *) const> {
172 template<
typename F,
typename T>
173 struct GetFunctorType<T(F::*)(T *, double *)> {
177 template<
typename F,
typename T>
178 struct GetFunctorType<T(F::*)(T *, double *) const> {
184 template<
typename T,
typename F>
185 auto GetTheRightOp(T(F::*opPtr)(
const T *,
const double *)) -> decltype(opPtr)
190 template<
typename T,
typename F>
191 auto GetTheRightOp(T(F::*opPtr)(
const T *,
const double *)
const) -> decltype(opPtr)
196 template<
typename T,
typename F>
197 auto GetTheRightOp(T(F::*opPtr)(T *,
double *)) -> decltype(opPtr)
202 template<
typename T,
typename F>
203 auto GetTheRightOp(T(F::*opPtr)(T *,
double *)
const) -> decltype(opPtr)
211 class TF1 :
public TNamed,
public TAttLine,
public TAttFill,
public TAttMarker {
214 friend struct ROOT::Internal::TF1Builder;
218 enum class EAddToList {
226 struct TF1FunctorPointer {
227 virtual ~TF1FunctorPointer() {}
228 virtual TF1FunctorPointer * Clone()
const = 0;
241 Double_t fXmin{-1111};
242 Double_t fXmax{-1111};
246 EFType fType{EFType::kTemplScalar};
249 Double_t fChisquare{};
250 Double_t fMinimum{-1111};
251 Double_t fMaximum{-1111};
252 std::vector<Double_t> fParErrors;
253 std::vector<Double_t> fParMin;
254 std::vector<Double_t> fParMax;
255 std::vector<Double_t> fSave;
256 std::vector<Double_t> fIntegral;
257 std::vector<Double_t> fAlpha;
258 std::vector<Double_t> fBeta;
259 std::vector<Double_t> fGamma;
260 TObject *fParent{
nullptr};
261 TH1 *fHistogram{
nullptr};
262 TMethodCall *fMethodCall{
nullptr};
263 Bool_t fNormalized{
false};
264 Double_t fNormIntegral{};
265 TF1FunctorPointer *fFunctor{
nullptr};
266 TFormula *fFormula{
nullptr};
267 TF1Parameters *fParams{
nullptr};
268 std::unique_ptr<TF1AbsComposition> fComposition;
269 TF1AbsComposition *fComposition_ptr{
nullptr};
272 TF1(EFType functionType,
const char *name, Double_t xmin, Double_t xmax, Int_t npar, Int_t ndim, EAddToList addToGlobList, TF1Parameters *params =
nullptr, TF1FunctorPointer * functor =
nullptr):
273 TNamed(name, name), TAttLine(), TAttFill(), TAttMarker(), fXmin(xmin), fXmax(xmax), fNpar(npar), fNdim(ndim),
274 fType(functionType), fParErrors(npar), fParMin(npar), fParMax(npar), fFunctor(functor), fParams(params)
276 DoInitialize(addToGlobList);
281 void DefineNSUMTerm(TObjArray *newFuncs, TObjArray *coeffNames,
282 TString &fullFormula,
283 TString &formula,
int termStart,
int termEnd,
284 Double_t xmin, Double_t xmax);
285 int TermCoeffLength(TString &term);
290 struct TF1FunctorPointerImpl: TF1FunctorPointer {
291 TF1FunctorPointerImpl(
const ROOT::Math::ParamFunctorTempl<T> &func): fImpl(func) {};
292 TF1FunctorPointerImpl(
const std::function<T(
const T *f,
const Double_t *param)> &func) : fImpl(func){};
293 virtual ~TF1FunctorPointerImpl() {}
294 virtual TF1FunctorPointer * Clone()
const {
return new TF1FunctorPointerImpl<T>(fImpl); }
295 ROOT::Math::ParamFunctorTempl<T> fImpl;
301 static std::atomic<Bool_t> fgAbsValue;
302 static Bool_t fgRejectPoint;
303 static std::atomic<Bool_t> fgAddToGlobList;
304 static TF1 *fgCurrent;
308 void DoInitialize(EAddToList addToGlobList);
310 void IntegrateForNormalization();
312 virtual Double_t GetMinMaxNDim(Double_t *x , Bool_t findmax, Double_t epsilon = 0, Int_t maxiter = 0)
const;
313 virtual void GetRange(Double_t *xmin, Double_t *xmax)
const;
314 virtual TH1 *DoCreateHistogram(Double_t xmin, Double_t xmax, Bool_t recreate = kFALSE);
320 kNotGlobal = BIT(10),
325 TF1(
const char *name,
const char *formula, Double_t xmin = 0, Double_t xmax = 1, EAddToList addToGlobList = EAddToList::kDefault,
bool vectorize =
false);
326 TF1(
const char *name,
const char *formula, Double_t xmin, Double_t xmax, Option_t * option);
327 TF1(
const char *name, Double_t xmin, Double_t xmax, Int_t npar, Int_t ndim = 1, EAddToList addToGlobList = EAddToList::kDefault);
328 TF1(
const char *name, Double_t (*fcn)(Double_t *, Double_t *), Double_t xmin = 0, Double_t xmax = 1, Int_t npar = 0, Int_t ndim = 1, EAddToList addToGlobList = EAddToList::kDefault);
329 TF1(
const char *name, Double_t (*fcn)(
const Double_t *,
const Double_t *), Double_t xmin = 0, Double_t xmax = 1, Int_t npar = 0, Int_t ndim = 1, EAddToList addToGlobList = EAddToList::kDefault);
332 TF1(
const char *name, std::function<T(
const T *data,
const Double_t *param)> &fcn, Double_t xmin = 0, Double_t xmax = 1, Int_t npar = 0, Int_t ndim = 1, EAddToList addToGlobList = EAddToList::kDefault):
333 TF1(EFType::kTemplScalar, name, xmin, xmax, npar, ndim, addToGlobList, new TF1Parameters(npar), new TF1FunctorPointerImpl<T>(fcn))
335 fType = std::is_same<T, double>::value ? TF1::EFType::kTemplScalar : TF1::EFType::kTemplVec;
351 TF1(
const char *name, T(*fcn)(
const T *,
const Double_t *), Double_t xmin = 0, Double_t xmax = 1, Int_t npar = 0, Int_t ndim = 1, EAddToList addToGlobList = EAddToList::kDefault):
352 TF1(EFType::kTemplVec, name, xmin, xmax, npar, ndim, addToGlobList, new TF1Parameters(npar), new TF1FunctorPointerImpl<T>(fcn))
356 TF1(
const char *name, ROOT::Math::ParamFunctor f, Double_t xmin = 0, Double_t xmax = 1, Int_t npar = 0, Int_t ndim = 1, EAddToList addToGlobList = EAddToList::kDefault);
366 template <
typename Func>
367 TF1(
const char *name, Func f, Double_t xmin, Double_t xmax, Int_t npar, Int_t ndim = 1, EAddToList addToGlobList = EAddToList::kDefault) :
368 TF1(EFType::kTemplScalar, name, xmin, xmax, npar, ndim, addToGlobList)
371 ROOT::Internal::TF1Builder<Func>::Build(
this, f);
375 template <
typename Func>
376 TF1(
const char *name, Func f, Double_t xmin, Double_t xmax, Int_t npar,
const char *, EAddToList addToGlobList = EAddToList::kDefault) :
377 TF1(EFType::kTemplScalar, name, xmin, xmax, npar, 1, addToGlobList, new TF1Parameters(npar))
379 ROOT::Internal::TF1Builder<Func>::Build(
this, f);
391 template <
class PtrObj,
typename MemFn>
392 TF1(
const char *name,
const PtrObj &p, MemFn memFn, Double_t xmin, Double_t xmax, Int_t npar, Int_t ndim = 1, EAddToList addToGlobList = EAddToList::kDefault) :
393 TF1(EFType::kTemplScalar, name, xmin, xmax, npar, ndim, addToGlobList, new TF1Parameters(npar), new TF1FunctorPointerImpl<double>(ROOT::Math::ParamFunctor(p, memFn)))
397 template <
class PtrObj,
typename MemFn>
398 TF1(
const char *name,
const PtrObj &p, MemFn memFn, Double_t xmin, Double_t xmax, Int_t npar,
const char *,
const char *, EAddToList addToGlobList = EAddToList::kDefault) :
399 TF1(EFType::kTemplScalar, name, xmin, xmax, npar, 1, addToGlobList, new TF1Parameters(npar), new TF1FunctorPointerImpl<double>(ROOT::Math::ParamFunctor(p, memFn)))
403 TF1 &operator=(
const TF1 &rhs);
405 virtual void AddParameter(
const TString &name, Double_t value)
407 if (fFormula) fFormula->AddParameter(name, value);
412 virtual Bool_t AddToGlobalList(Bool_t on = kTRUE);
413 static Bool_t DefaultAddToGlobalList(Bool_t on = kTRUE);
414 virtual void Browse(TBrowser *b);
415 virtual void Copy(TObject &f1)
const;
416 virtual Double_t Derivative(Double_t x, Double_t *params = 0, Double_t epsilon = 0.001)
const;
417 virtual Double_t Derivative2(Double_t x, Double_t *params = 0, Double_t epsilon = 0.001)
const;
418 virtual Double_t Derivative3(Double_t x, Double_t *params = 0, Double_t epsilon = 0.001)
const;
419 static Double_t DerivativeError();
420 virtual Int_t DistancetoPrimitive(Int_t px, Int_t py);
421 virtual void Draw(Option_t *option =
"");
422 virtual TF1 *DrawCopy(Option_t *option =
"")
const;
423 virtual TObject *DrawDerivative(Option_t *option =
"al");
424 virtual TObject *DrawIntegral(Option_t *option =
"al");
425 virtual void DrawF1(Double_t xmin, Double_t xmax, Option_t *option =
"");
426 virtual Double_t Eval(Double_t x, Double_t y = 0, Double_t z = 0, Double_t t = 0)
const;
428 virtual Double_t EvalPar(
const Double_t *x,
const Double_t *params = 0);
429 template <
class T> T EvalPar(
const T *x,
const Double_t *params = 0);
430 virtual Double_t operator()(Double_t x, Double_t y = 0, Double_t z = 0, Double_t t = 0)
const;
431 template <
class T> T operator()(
const T *x,
const Double_t *params =
nullptr);
432 virtual void ExecuteEvent(Int_t event, Int_t px, Int_t py);
433 virtual void FixParameter(Int_t ipar, Double_t value);
436 return (fType == EFType::kTemplVec) || (fType == EFType::kFormula && fFormula && fFormula->IsVectorized());
438 Double_t GetChisquare()
const
442 virtual TH1 *GetHistogram()
const;
443 virtual TH1 *CreateHistogram()
445 return DoCreateHistogram(fXmin, fXmax);
447 virtual TFormula *GetFormula()
451 virtual const TFormula *GetFormula()
const
455 virtual TString GetExpFormula(Option_t *option =
"")
const
457 return (fFormula) ? fFormula->GetExpFormula(option) :
"";
459 virtual const TObject *GetLinearPart(Int_t i)
const
461 return (fFormula) ? fFormula->GetLinearPart(i) :
nullptr;
463 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;
464 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;
465 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;
466 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;
467 virtual Double_t GetMaximumStored()
const
471 virtual Double_t GetMinimumStored()
const
475 virtual Int_t GetNpar()
const
479 virtual Int_t GetNdim()
const
483 virtual Int_t GetNDF()
const;
484 virtual Int_t GetNpx()
const
488 TMethodCall *GetMethodCall()
const
492 virtual Int_t GetNumber()
const
494 return (fFormula) ? fFormula->GetNumber() : 0;
496 virtual Int_t GetNumberFreeParameters()
const;
497 virtual Int_t GetNumberFitPoints()
const
501 virtual char *GetObjectInfo(Int_t px, Int_t py)
const;
502 TObject *GetParent()
const
506 virtual Double_t GetParameter(Int_t ipar)
const
508 return (fFormula) ? fFormula->GetParameter(ipar) : fParams->GetParameter(ipar);
510 virtual Double_t GetParameter(
const TString &name)
const
512 return (fFormula) ? fFormula->GetParameter(name) : fParams->GetParameter(name);
514 virtual Double_t *GetParameters()
const
516 return (fFormula) ? fFormula->GetParameters() :
const_cast<Double_t *
>(fParams->GetParameters());
518 virtual void GetParameters(Double_t *params)
520 if (fFormula) fFormula->GetParameters(params);
521 else std::copy(fParams->ParamsVec().begin(), fParams->ParamsVec().end(), params);
523 virtual const char *GetParName(Int_t ipar)
const
525 return (fFormula) ? fFormula->GetParName(ipar) : fParams->GetParName(ipar);
527 virtual Int_t GetParNumber(
const char *name)
const
529 return (fFormula) ? fFormula->GetParNumber(name) : fParams->GetParNumber(name);
531 virtual Double_t GetParError(Int_t ipar)
const;
532 virtual const Double_t *GetParErrors()
const
534 return fParErrors.data();
536 virtual void GetParLimits(Int_t ipar, Double_t &parmin, Double_t &parmax)
const;
537 virtual Double_t GetProb()
const;
538 virtual Int_t GetQuantiles(Int_t nprobSum, Double_t *q,
const Double_t *probSum);
539 virtual Double_t GetRandom();
540 virtual Double_t GetRandom(Double_t xmin, Double_t xmax);
541 virtual void GetRange(Double_t &xmin, Double_t &xmax)
const;
542 virtual void GetRange(Double_t &xmin, Double_t &ymin, Double_t &xmax, Double_t &ymax)
const;
543 virtual void GetRange(Double_t &xmin, Double_t &ymin, Double_t &zmin, Double_t &xmax, Double_t &ymax, Double_t &zmax)
const;
544 virtual Double_t GetSave(
const Double_t *x);
545 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;
546 virtual Double_t GetXmin()
const
550 virtual Double_t GetXmax()
const
554 TAxis *GetXaxis()
const ;
555 TAxis *GetYaxis()
const ;
556 TAxis *GetZaxis()
const ;
557 virtual Double_t GetVariable(
const TString &name)
559 return (fFormula) ? fFormula->GetVariable(name) : 0;
561 virtual Double_t GradientPar(Int_t ipar,
const Double_t *x, Double_t eps = 0.01);
563 T GradientPar(Int_t ipar,
const T *x, Double_t eps = 0.01);
565 T GradientParTempl(Int_t ipar,
const T *x, Double_t eps = 0.01);
567 virtual void GradientPar(
const Double_t *x, Double_t *grad, Double_t eps = 0.01);
569 void GradientPar(
const T *x, T *grad, Double_t eps = 0.01);
571 void GradientParTempl(
const T *x, T *grad, Double_t eps = 0.01);
573 virtual void InitArgs(
const Double_t *x,
const Double_t *params);
574 static void InitStandardFunctions();
575 virtual Double_t Integral(Double_t a, Double_t b, Double_t epsrel = 1.e-12);
576 virtual Double_t IntegralOneDim(Double_t a, Double_t b, Double_t epsrel, Double_t epsabs, Double_t &err);
577 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);
578 virtual Double_t IntegralError(Int_t n,
const Double_t *a,
const Double_t *b,
const Double_t *params = 0,
const Double_t *covmat = 0, Double_t epsilon = 1.E-2);
580 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);
581 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);
582 virtual Double_t IntegralMultiple(Int_t n,
const Double_t *a,
const Double_t *b, Int_t , Int_t maxpts, Double_t epsrel, Double_t &relerr, Int_t &nfnevl, Int_t &ifail)
584 return IntegralMultiple(n, a, b, maxpts, epsrel, epsrel, relerr, nfnevl, ifail);
586 virtual Double_t IntegralMultiple(Int_t n,
const Double_t *a,
const Double_t *b, Double_t epsrel, Double_t &relerr);
587 virtual Bool_t IsEvalNormalized()
const
592 virtual Bool_t IsInside(
const Double_t *x)
const
594 return !((x[0] < fXmin) || (x[0] > fXmax));
596 virtual Bool_t IsLinear()
const
598 return (fFormula) ? fFormula->IsLinear() :
false;
600 virtual Bool_t IsValid()
const;
601 virtual void Print(Option_t *option =
"")
const;
602 virtual void Paint(Option_t *option =
"");
603 virtual void ReleaseParameter(Int_t ipar);
604 virtual void Save(Double_t xmin, Double_t xmax, Double_t ymin, Double_t ymax, Double_t zmin, Double_t zmax);
605 virtual void SavePrimitive(std::ostream &out, Option_t *option =
"");
606 virtual void SetChisquare(Double_t chi2)
610 virtual void SetFitResult(
const ROOT::Fit::FitResult &result,
const Int_t *indpar = 0);
611 template <
class PtrObj,
typename MemFn>
612 void SetFunction(PtrObj &p, MemFn memFn);
613 template <
typename Func>
614 void SetFunction(Func f);
615 virtual void SetMaximum(Double_t maximum = -1111);
616 virtual void SetMinimum(Double_t minimum = -1111);
617 virtual void SetNDF(Int_t ndf);
618 virtual void SetNumberFitPoints(Int_t npfits)
622 virtual void SetNormalized(Bool_t flag)
627 virtual void SetNpx(Int_t npx = 100);
628 virtual void SetParameter(Int_t param, Double_t value)
630 (fFormula) ? fFormula->SetParameter(param, value) : fParams->SetParameter(param, value);
633 virtual void SetParameter(
const TString &name, Double_t value)
635 (fFormula) ? fFormula->SetParameter(name, value) : fParams->SetParameter(name, value);
638 virtual void SetParameters(
const Double_t *params)
640 (fFormula) ? fFormula->SetParameters(params) : fParams->SetParameters(params);
643 virtual void SetParameters(Double_t p0, Double_t p1, Double_t p2 = 0, Double_t p3 = 0, Double_t p4 = 0,
644 Double_t p5 = 0, Double_t p6 = 0, Double_t p7 = 0, Double_t p8 = 0,
645 Double_t p9 = 0, Double_t p10 = 0)
647 if (fFormula) fFormula->SetParameters(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10);
648 else fParams->SetParameters(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10);
651 virtual void SetParName(Int_t ipar,
const char *name);
652 virtual void SetParNames(
const char *name0 =
"p0",
const char *name1 =
"p1",
const char *name2 =
"p2",
653 const char *name3 =
"p3",
const char *name4 =
"p4",
const char *name5 =
"p5",
654 const char *name6 =
"p6",
const char *name7 =
"p7",
const char *name8 =
"p8",
655 const char *name9 =
"p9",
const char *name10 =
"p10");
656 virtual void SetParError(Int_t ipar, Double_t error);
657 virtual void SetParErrors(
const Double_t *errors);
658 virtual void SetParLimits(Int_t ipar, Double_t parmin, Double_t parmax);
659 virtual void SetParent(TObject *p = 0)
663 virtual void SetRange(Double_t xmin, Double_t xmax);
664 virtual void SetRange(Double_t xmin, Double_t ymin, Double_t xmax, Double_t ymax);
665 virtual void SetRange(Double_t xmin, Double_t ymin, Double_t zmin, Double_t xmax, Double_t ymax, Double_t zmax);
666 virtual void SetSavedPoint(Int_t point, Double_t value);
667 virtual void SetTitle(
const char *title =
"");
668 virtual void SetVectorized(Bool_t vectorized)
670 if (fType == EFType::kFormula && fFormula)
671 fFormula->SetVectorized(vectorized);
673 Warning(
"SetVectorized",
"Can only set vectorized flag on formula-based TF1");
675 virtual void Update();
677 static TF1 *GetCurrent();
678 static void AbsValue(Bool_t reject = kTRUE);
679 static void RejectPoint(Bool_t reject = kTRUE);
680 static Bool_t RejectedPoint();
681 static void SetCurrent(TF1 *f1);
684 virtual Double_t Moment(Double_t n, Double_t a, Double_t b,
const Double_t *params = 0, Double_t epsilon = 0.000001);
685 virtual Double_t CentralMoment(Double_t n, Double_t a, Double_t b,
const Double_t *params = 0, Double_t epsilon = 0.000001);
686 virtual Double_t Mean(Double_t a, Double_t b,
const Double_t *params = 0, Double_t epsilon = 0.000001)
688 return Moment(1, a, b, params, epsilon);
690 virtual Double_t Variance(Double_t a, Double_t b,
const Double_t *params = 0, Double_t epsilon = 0.000001)
692 return CentralMoment(2, a, b, params, epsilon);
698 static void CalcGaussLegendreSamplingPoints(Int_t num, Double_t *x, Double_t *w, Double_t eps = 3.0e-11);
702 T EvalParTempl(
const T *data,
const Double_t *params = 0);
704 #ifdef R__HAS_VECCORE
705 inline double EvalParVec(
const Double_t *data,
const Double_t *params);
715 void TF1Builder<Func>::Build(TF1 *f, Func func)
717 using Fnc_t =
typename ROOT::Internal::GetFunctorType<decltype(ROOT::Internal::GetTheRightOp(&Func::operator()))>::type;
718 f->fType = std::is_same<Fnc_t, double>::value? TF1::EFType::kTemplScalar : TF1::EFType::kTemplVec;
719 f->fFunctor =
new TF1::TF1FunctorPointerImpl<Fnc_t>(ROOT::Math::ParamFunctorTempl<Fnc_t>(func));
720 f->fParams =
new TF1Parameters(f->fNpar);
724 void TF1Builder<Func *>::Build(TF1 *f, Func *func)
726 using Fnc_t =
typename ROOT::Internal::GetFunctorType<decltype(ROOT::Internal::GetTheRightOp(&Func::operator()))>::type;
727 f->fType = std::is_same<Fnc_t, double>::value? TF1::EFType::kTemplScalar : TF1::EFType::kTemplVec;
728 f->fFunctor =
new TF1::TF1FunctorPointerImpl<Fnc_t>(ROOT::Math::ParamFunctorTempl<Fnc_t>(func));
729 f->fParams =
new TF1Parameters(f->fNpar);
735 struct TF1Builder<const char *> {
736 static void Build(TF1 *f,
const char *formula)
738 f->fType = TF1::EFType::kFormula;
739 f->fFormula =
new TFormula(
"tf1lambda", formula, f->fNdim, f->fNpar,
false);
740 TString formulaExpression(formula);
741 Ssiz_t first = formulaExpression.Index(
"return") + 7;
742 Ssiz_t last = formulaExpression.Last(
';');
743 TString title = formulaExpression(first, last - first);
750 inline Double_t TF1::operator()(Double_t x, Double_t y, Double_t z, Double_t t)
const
752 return Eval(x, y, z, t);
756 inline T TF1::operator()(
const T *x,
const Double_t *params)
758 return EvalPar(x, params);
764 T TF1::EvalPar(
const T *x,
const Double_t *params)
766 if (fType == EFType::kTemplVec || fType == EFType::kTemplScalar) {
767 return EvalParTempl(x, params);
768 }
else if (fType == EFType::kFormula) {
769 return fFormula->EvalPar(x, params);
771 return TF1::EvalPar((
double *)x, params);
789 inline T TF1::EvalParTempl(
const T *data,
const Double_t *params)
791 assert(fType == EFType::kTemplScalar || fType == EFType::kTemplVec);
792 if (!params) params = (Double_t *)fParams->GetParameters();
794 return ((TF1FunctorPointerImpl<T> *)fFunctor)->fImpl(data, params);
798 return TMath::SignalingNaN();
801 #ifdef R__HAS_VECCORE
803 inline double TF1::EvalParVec(
const Double_t *data,
const Double_t *params)
805 assert(fType == EFType::kTemplVec);
806 std::vector<ROOT::Double_v> d(fNdim);
809 for(
auto i=0; i<fNdim; i++) {
810 d[i] = ROOT::Double_v(data[i]);
814 res = ((TF1FunctorPointerImpl<ROOT::Double_v> *) fFunctor)->fImpl(d.data(), params);
817 return TMath::SignalingNaN();
819 return vecCore::Get<ROOT::Double_v>(res, 0);
823 inline void TF1::SetRange(Double_t xmin, Double_t, Double_t xmax, Double_t)
825 TF1::SetRange(xmin, xmax);
827 inline void TF1::SetRange(Double_t xmin, Double_t, Double_t, Double_t xmax, Double_t, Double_t)
829 TF1::SetRange(xmin, xmax);
832 template <
typename Func>
833 void TF1::SetFunction(Func f)
836 fType = EFType::kPtrScalarFreeFcn;
837 fFunctor =
new TF1::TF1FunctorPointerImpl<double>(ROOT::Math::ParamFunctor(f));
839 template <
class PtrObj,
typename MemFn>
840 void TF1::SetFunction(PtrObj &p, MemFn memFn)
843 fType = EFType::kPtrScalarFreeFcn;
844 fFunctor =
new TF1::TF1FunctorPointerImpl<double>(ROOT::Math::ParamFunctor(p, memFn));
848 inline T TF1::GradientPar(Int_t ipar,
const T *x, Double_t eps)
850 if (fType == EFType::kTemplVec || fType == EFType::kTemplScalar) {
851 return GradientParTempl<T>(ipar, x, eps);
853 return GradientParTempl<Double_t>(ipar, (
const Double_t *)x, eps);
857 inline T TF1::GradientParTempl(Int_t ipar,
const T *x, Double_t eps)
862 if (eps < 1e-10 || eps > 1) {
863 Warning(
"Derivative",
"parameter esp=%g out of allowed range[1e-10,1], reset to 0.01", eps);
867 TF1 *func = (TF1 *)
this;
868 Double_t *parameters = GetParameters();
871 std::vector<Double_t> parametersCopy(parameters, parameters + GetNpar());
872 parameters = parametersCopy.data();
875 T f1, f2, g1, g2, d0, d2;
877 ((TF1 *)
this)->GetParLimits(ipar, al, bl);
878 if (al * bl != 0 && al >= bl) {
884 if (func->GetParError(ipar) != 0)
885 h = eps * func->GetParError(ipar);
890 Double_t par0 = parameters[ipar];
892 parameters[ipar] = par0 + h;
893 f1 = func->EvalPar(x, parameters);
894 parameters[ipar] = par0 - h;
895 f2 = func->EvalPar(x, parameters);
896 parameters[ipar] = par0 + h / 2;
897 g1 = func->EvalPar(x, parameters);
898 parameters[ipar] = par0 - h / 2;
899 g2 = func->EvalPar(x, parameters);
906 T grad = h2 * (4 * d2 - d0) / 3.;
909 parameters[ipar] = par0;
915 inline void TF1::GradientPar(
const T *x, T *grad, Double_t eps)
917 if (fType == EFType::kTemplVec || fType == EFType::kTemplScalar) {
918 GradientParTempl<T>(x, grad, eps);
920 GradientParTempl<Double_t>((
const Double_t *)x, (Double_t *)grad, eps);
924 inline
void TF1::GradientParTempl(const T *x, T *grad, Double_t eps)
926 if (eps < 1e-10 || eps > 1) {
927 Warning(
"Derivative",
"parameter esp=%g out of allowed range[1e-10,1], reset to 0.01", eps);
931 for (Int_t ipar = 0; ipar < GetNpar(); ipar++) {
932 grad[ipar] = GradientParTempl<T>(ipar, x, eps);