// @(#)root/hist:$Id$
// Author: Rene Brun   18/08/95

/*************************************************************************
 * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/
// ---------------------------------- F1.h

#ifndef ROOT_TF1
#define ROOT_TF1



//////////////////////////////////////////////////////////////////////////
//                                                                      //
// TF1                                                                  //
//                                                                      //
// The Parametric 1-D function                                          //
//                                                                      //
//////////////////////////////////////////////////////////////////////////

#include "RConfigure.h"

#ifndef ROOT_TFormula
#include "TFormula.h"
#endif
#ifndef ROOT_TAttLine
#include "TAttLine.h"
#endif
#ifndef ROOT_TAttFill
#include "TAttFill.h"
#endif
#ifndef ROOT_TAttMarker
#include "TAttMarker.h"
#endif

#ifndef ROOT_Math_ParamFunctor
#include "Math/ParamFunctor.h"
#endif

class TF1;
class TH1;
class TAxis;
class TMethodCall;

namespace ROOT {
   namespace Fit {
      class FitResult;
   }
}

class TF1Parameters {
public:
   TF1Parameters() {} // needed for the I/O
   TF1Parameters(Int_t npar) :
      fParameters(std::vector<Double_t>(npar) ),
      fParNames(std::vector<std::string>(npar) )
   {
      for (int i = 0; i < npar; ++i ){
         fParNames[i] = std::string(TString::Format("p%d",i).Data() );
      }
   }
   // copy constructor
   TF1Parameters(const TF1Parameters & rhs) :
      fParameters(rhs.fParameters),
      fParNames(rhs.fParNames)
   {}
   // assignment
   TF1Parameters & operator=(const TF1Parameters & rhs) {
      if (&rhs == this) return *this;
      fParameters = rhs.fParameters;
      fParNames = rhs.fParNames;
      return *this;
   }
   virtual ~TF1Parameters() {}

   // getter methods
   Double_t GetParameter(Int_t iparam) const {
      return (CheckIndex(iparam)) ? fParameters[iparam] : 0;
   }
   Double_t GetParameter(const char * name) const {
      return GetParameter(GetParNumber(name) );
   }
   const Double_t *GetParameters() const {
      return fParameters.data();
   }
   const std::vector<double> & ParamsVec() const { return fParameters; }
   
   Int_t GetParNumber(const char * name) const;

   const char *GetParName(Int_t iparam) const {
      return (CheckIndex(iparam)) ? fParNames[iparam].c_str() : "";
   }


   // setter methods
   void   SetParameter(Int_t iparam, Double_t value) {
      if (!CheckIndex(iparam)) return;
      fParameters[iparam] = value;
   }
   void  SetParameters(const Double_t *params) {
      std::copy(params, params + fParameters.size(), fParameters.begin() );
   }
   void  SetParameters(Double_t p0,Double_t p1,Double_t p2=0,Double_t p3=0,Double_t p4=0,
                               Double_t p5=0,Double_t p6=0,Double_t p7=0,Double_t p8=0,
                               Double_t p9=0,Double_t p10=0);

   void   SetParameter(const char *name, Double_t value) {
      SetParameter(GetParNumber(name),value);
   }
   void   SetParName(Int_t iparam, const char * name) {
      if (!CheckIndex(iparam)) return;
      fParNames[iparam] = std::string(name);
   }
   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");



   ClassDef(TF1Parameters,1)   // The Parameters of a parameteric function
private:

   bool CheckIndex(Int_t i) const {
      return (i >= 0 && i < int(fParameters.size()) );
   }

   std::vector<Double_t> fParameters;    // parameter values
   std::vector<std::string> fParNames;   // parameter names
};


class TF1 : public TNamed, public TAttLine, public TAttFill, public TAttMarker {

protected:
   Double_t    fXmin;        //Lower bounds for the range
   Double_t    fXmax;        //Upper bounds for the range
   Int_t       fNpar;        //Number of parameters
   Int_t       fNdim;        //Function dimension
   Int_t       fNpx;         //Number of points used for the graphical representation
   Int_t       fType;        //(=0 for standard functions, 1 if pointer to function)
   Int_t       fNpfits;      //Number of points used in the fit
   Int_t       fNDF;         //Number of degrees of freedom in the fit
   Double_t    fChisquare;   //Function fit chisquare
   Double_t    fMinimum;     //Minimum value for plotting
   Double_t    fMaximum;     //Maximum value for plotting
   std::vector<Double_t>    fParErrors;  //Array of errors of the fNpar parameters
   std::vector<Double_t>    fParMin;     //Array of lower limits of the fNpar parameters
   std::vector<Double_t>    fParMax;     //Array of upper limits of the fNpar parameters
   std::vector<Double_t>    fSave;       //Array of fNsave function values
   std::vector<Double_t>    fIntegral;   //!Integral of function binned on fNpx bins
   std::vector<Double_t>    fAlpha;      //!Array alpha. for each bin in x the deconvolution r of fIntegral
   std::vector<Double_t>    fBeta;       //!Array beta.  is approximated by x = alpha +beta*r *gamma*r**2
   std::vector<Double_t>    fGamma;      //!Array gamma.
   TObject     *fParent;     //!Parent object hooking this function (if one)
   TH1         *fHistogram;  //!Pointer to histogram used for visualisation
   TMethodCall *fMethodCall; //!Pointer to MethodCall in case of interpreted function
   Bool_t      fNormalized;  //Normalization option (false by default)
   Double_t    fNormIntegral;//Integral of the function before being normalized
   ROOT::Math::ParamFunctor fFunctor;   //! Functor object to wrap any C++ callable object
   TFormula    *fFormula;    //Pointer to TFormula in case when user define formula
   TF1Parameters *fParams;   //Pointer to Function parameters object (exusts only for not-formula functions)

   static Bool_t fgAbsValue;  //use absolute value of function when computing integral
   static Bool_t fgRejectPoint;  //True if point must be rejected in a fit
   static Bool_t fgAddToGlobList; //True if we want to register the function in the global list
   static TF1   *fgCurrent;   //pointer to current function being processed


   //void CreateFromFunctor(const char *name, Int_t npar, Int_t ndim = 1);
   void DoInitialize();

   void IntegrateForNormalization();

   virtual Double_t GetMinMaxNDim(Double_t * x , Bool_t findmax, Double_t epsilon = 0, Int_t maxiter = 0) const;
   virtual void GetRange(Double_t * xmin, Double_t * xmax) const;
   virtual TH1 *DoCreateHistogram(Double_t xmin, Double_t xmax, Bool_t recreate = kFALSE);

   enum {
       kNotGlobal   = BIT(10)  // don't register in global list of functions
   };

public:
    // TF1 status bits
    enum {
       kNotDraw     = BIT(9)  // don't draw the function when in a TH1
    };

   TF1();
   TF1(const char *name, const char *formula, Double_t xmin=0, Double_t xmax = 1);
   TF1(const char *name, Double_t xmin, Double_t xmax, Int_t npar,Int_t ndim = 1);
#ifndef __CINT__
   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);
   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);
#endif

   // Constructors using functors (compiled mode only)
   TF1(const char *name, ROOT::Math::ParamFunctor f, Double_t xmin = 0, Double_t xmax = 1, Int_t npar = 0,Int_t ndim = 1);

   // Template constructors from any  C++ callable object,  defining  the operator() (double * , double *)
   // and returning a double.
   // The class name is not needed when using compile code, while it is required when using
   // interpreted code via the specialized constructor with void *.
   // An instance of the C++ function class or its pointer can both be used. The former is reccomended when using
   // C++ compiled code, but if CINT compatibility is needed, then a pointer to the function class must be used.
   // xmin and xmax specify the plotting range,  npar is the number of parameters.
   // See the tutorial math/exampleFunctor.C for an example of using this constructor
   template <typename Func>
   TF1(const char *name, Func f, Double_t xmin, Double_t xmax, Int_t npar,Int_t ndim = 1 ) :
      TNamed(name,name), TAttLine(), TAttFill(), TAttMarker(),
      fXmin(xmin), fXmax(xmax),
      fNpar(npar), fNdim(ndim),
      fNpx(100), fType(1),
      fNpfits(0), fNDF(0), fChisquare(0),
      fMinimum(-1111), fMaximum(-1111),
      fParErrors(std::vector<Double_t>(npar)),
      fParMin(std::vector<Double_t>(npar)),
      fParMax(std::vector<Double_t>(npar)),
      fParent(0), fHistogram(0),
      fMethodCall(0),
      fNormalized(false), fNormIntegral(0),
      fFunctor(ROOT::Math::ParamFunctor(f)),
      fFormula(0),
      fParams(new TF1Parameters(npar) )
   {
      DoInitialize();
   }
   // backward compatible interface
   template <typename Func>
   TF1(const char *name, Func f, Double_t xmin, Double_t xmax, Int_t npar, const char *   ) :
      TNamed(name,name), TAttLine(), TAttFill(), TAttMarker(),
      fXmin(xmin), fXmax(xmax),
      fNpar(npar), fNdim(1),
      fNpx(100), fType(1),
      fNpfits(0), fNDF(0), fChisquare(0),
      fMinimum(-1111), fMaximum(-1111),
      fParErrors(std::vector<Double_t>(npar)),
      fParMin(std::vector<Double_t>(npar)),
      fParMax(std::vector<Double_t>(npar)),
      fParent(0), fHistogram(0),
      fMethodCall(0),
      fNormalized(false), fNormIntegral(0),
      fFunctor(ROOT::Math::ParamFunctor(f)),
      fFormula(0),
      fParams(new TF1Parameters(npar) )
   {
      DoInitialize();
   }


   // Template constructors from a pointer to any C++ class of type PtrObj with a specific member function of type
   // MemFn.
   // The member function must have the signature of  (double * , double *) and returning a double.
   // The class name and the method name are not needed when using compile code
   // (the member function pointer is used in this case), while they are required when using interpreted
   // code via the specialized constructor with void *.
   // xmin and xmax specify the plotting range,  npar is the number of parameters.
   // See the tutorial math/exampleFunctor.C for an example of using this constructor
   template <class PtrObj, typename MemFn>
   TF1(const char *name, const  PtrObj& p, MemFn memFn, Double_t xmin, Double_t xmax, Int_t npar,Int_t ndim = 1) :
      TNamed(name,name), TAttLine(), TAttFill(), TAttMarker(),
      fXmin(xmin), fXmax(xmax),
      fNpar(npar), fNdim(ndim),
      fNpx(100), fType(1),
      fNpfits(0), fNDF(0), fChisquare(0),
      fMinimum(-1111), fMaximum(-1111),
      fParErrors(std::vector<Double_t>(npar)),
      fParMin(std::vector<Double_t>(npar)),
      fParMax(std::vector<Double_t>(npar)),
      fParent(0), fHistogram(0),
      fMethodCall(0),
      fNormalized(false), fNormIntegral(0),
      fFunctor   ( ROOT::Math::ParamFunctor(p,memFn) ),
      fFormula(0),
      fParams(new TF1Parameters(npar) )
   {
      DoInitialize();
   }
   // backward compatible interface
   template <class PtrObj, typename MemFn>
   TF1(const char *name, const  PtrObj& p, MemFn memFn, Double_t xmin, Double_t xmax, Int_t npar,const char * , const char * ) :
      TNamed(name,name), TAttLine(), TAttFill(), TAttMarker(),
      fXmin(xmin), fXmax(xmax),
      fNpar(npar), fNdim(1),
      fNpx(100), fType(1),
      fNpfits(0), fNDF(0), fChisquare(0),
      fMinimum(-1111), fMaximum(-1111),
      fParErrors(std::vector<Double_t>(npar)),
      fParMin(std::vector<Double_t>(npar)),
      fParMax(std::vector<Double_t>(npar)),
      fParent(0), fHistogram(0),
      fMethodCall(0),
      fNormalized(false), fNormIntegral(0),
      fFunctor   ( ROOT::Math::ParamFunctor(p,memFn) ),
      fFormula(0),
      fParams(new TF1Parameters(npar) )
   {
      DoInitialize();
   }

   TF1(const TF1 &f1);
   TF1& operator=(const TF1 &rhs);
   virtual   ~TF1();
   virtual void     AddParameter(const TString &name, Double_t value) { if (fFormula) fFormula->AddParameter(name,value); }
   //virtual void     AddParameters(const pair<TString,Double_t> *pairs, Int_t size) { fFormula->AddParameters(pairs,size); }
   // virtual void     AddVariable(const TString &name, Double_t value = 0) { if (fFormula) fFormula->AddVariable(name,value); }
   // virtual void     AddVariables(const TString *vars, Int_t size) { if (fFormula) fFormula->AddVariables(vars,size); }
   virtual Bool_t   AddToGlobalList(Bool_t on = kTRUE);
   virtual void     Browse(TBrowser *b);
   virtual void     Copy(TObject &f1) const;
   virtual Double_t Derivative (Double_t x, Double_t *params=0, Double_t epsilon=0.001) const;
   virtual Double_t Derivative2(Double_t x, Double_t *params=0, Double_t epsilon=0.001) const;
   virtual Double_t Derivative3(Double_t x, Double_t *params=0, Double_t epsilon=0.001) const;
   static  Double_t DerivativeError();
   virtual Int_t    DistancetoPrimitive(Int_t px, Int_t py);
   virtual void     Draw(Option_t *option="");
   virtual TF1     *DrawCopy(Option_t *option="") const;
   virtual TObject *DrawDerivative(Option_t *option="al"); // *MENU*
   virtual TObject *DrawIntegral(Option_t *option="al");   // *MENU*
   virtual void     DrawF1(Double_t xmin, Double_t xmax, Option_t *option="");
   virtual Double_t Eval(Double_t x, Double_t y=0, Double_t z=0, Double_t t=0) const;
   virtual Double_t EvalPar(const Double_t *x, const Double_t *params=0);
   // for using TF1 as a callable object (functor)
   virtual Double_t operator()(Double_t x, Double_t y=0, Double_t z = 0, Double_t t = 0) const;
   virtual Double_t operator()(const Double_t *x, const Double_t *params=0);
   virtual void     ExecuteEvent(Int_t event, Int_t px, Int_t py);
   virtual void     FixParameter(Int_t ipar, Double_t value);
       Double_t     GetChisquare() const {return fChisquare;}
   virtual TH1     *GetHistogram() const;
   virtual TH1     *CreateHistogram() { return DoCreateHistogram(fXmin, fXmax); }
   virtual TFormula *GetFormula() { return fFormula;}
   virtual const TFormula *GetFormula() const { return fFormula;}
   virtual TString  GetExpFormula(Option_t *option="") const { return (fFormula) ? fFormula->GetExpFormula(option) : ""; }
   virtual const TObject *GetLinearPart(Int_t i) const { return (fFormula) ? fFormula->GetLinearPart(i) : nullptr;}
   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;
   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;
   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;
   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;
   virtual Double_t GetMaximumStored() const {return fMaximum;}
   virtual Double_t GetMinimumStored() const {return fMinimum;}
   virtual Int_t    GetNpar() const { return fNpar;}
   virtual Int_t    GetNdim() const { return fNdim;}
   virtual Int_t    GetNDF() const;
   virtual Int_t    GetNpx() const {return fNpx;}
    TMethodCall    *GetMethodCall() const {return fMethodCall;}
   virtual Int_t    GetNumber() const { return (fFormula) ? fFormula->GetNumber() : 0;}
   virtual Int_t    GetNumberFreeParameters() const;
   virtual Int_t    GetNumberFitPoints() const {return fNpfits;}
   virtual char    *GetObjectInfo(Int_t px, Int_t py) const;
        TObject    *GetParent() const {return fParent;}
   virtual Double_t GetParameter(Int_t ipar) const {
      return (fFormula) ? fFormula->GetParameter(ipar) : fParams->GetParameter(ipar);
   }
   virtual Double_t GetParameter(const TString &name)  const {
      return (fFormula) ? fFormula->GetParameter(name) : fParams->GetParameter(name);
   }
   virtual Double_t *GetParameters() const {
      return (fFormula) ? fFormula->GetParameters() : const_cast<Double_t*>(fParams->GetParameters());
   }
   virtual void     GetParameters(Double_t *params) { if (fFormula) fFormula->GetParameters(params);
                                                      else std::copy(fParams->ParamsVec().begin(), fParams->ParamsVec().end(), params); }
   virtual const char *GetParName(Int_t ipar) const {
      return (fFormula) ? fFormula->GetParName(ipar) : fParams->GetParName(ipar);
   }
   virtual Int_t    GetParNumber(const char* name) const {
      return (fFormula) ? fFormula->GetParNumber(name) : fParams->GetParNumber(name);
   }
   virtual Double_t GetParError(Int_t ipar) const;
   virtual const Double_t *GetParErrors() const {return fParErrors.data();}
   virtual void     GetParLimits(Int_t ipar, Double_t &parmin, Double_t &parmax) const;
   virtual Double_t GetProb() const;
   virtual Int_t    GetQuantiles(Int_t nprobSum, Double_t *q, const Double_t *probSum);
   virtual Double_t GetRandom();
   virtual Double_t GetRandom(Double_t xmin, Double_t xmax);
   virtual void     GetRange(Double_t &xmin, Double_t &xmax) const;
   virtual void     GetRange(Double_t &xmin, Double_t &ymin, Double_t &xmax, Double_t &ymax) const;
   virtual void     GetRange(Double_t &xmin, Double_t &ymin, Double_t &zmin, Double_t &xmax, Double_t &ymax, Double_t &zmax) const;
   virtual Double_t GetSave(const Double_t *x);
   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;
   virtual Double_t GetXmin() const {return fXmin;}
   virtual Double_t GetXmax() const {return fXmax;}
   TAxis           *GetXaxis() const ;
   TAxis           *GetYaxis() const ;
   TAxis           *GetZaxis() const ;
   virtual Double_t GetVariable(const TString &name) { return (fFormula) ? fFormula->GetVariable(name) : 0;}
   virtual Double_t GradientPar(Int_t ipar, const Double_t *x, Double_t eps=0.01);
   virtual void     GradientPar(const Double_t *x, Double_t *grad, Double_t eps=0.01);
   virtual void     InitArgs(const Double_t *x, const Double_t *params);
   static  void     InitStandardFunctions();
   virtual Double_t Integral(Double_t a, Double_t b, Double_t epsrel=1.e-12);
   virtual Double_t IntegralOneDim(Double_t a, Double_t b, Double_t epsrel, Double_t epsabs, Double_t &err);
   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);
   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);
   //virtual Double_t IntegralFast(const TGraph *g, Double_t a, Double_t b, Double_t *params=0);
   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);
   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);
   // for backward compatibility
   virtual Double_t IntegralMultiple(Int_t n, const Double_t *a, const Double_t *b, Int_t /*minpts*/, Int_t maxpts, Double_t epsrel, Double_t &relerr,Int_t &nfnevl, Int_t &ifail) {
      return  IntegralMultiple(n,a,b,maxpts, epsrel, epsrel, relerr, nfnevl, ifail);
   }
   virtual Double_t IntegralMultiple(Int_t n, const Double_t *a, const Double_t *b, Double_t epsrel, Double_t &relerr);
   virtual Bool_t   IsEvalNormalized() const { return fNormalized; }
   /// return kTRUE if the point is inside the function range
   virtual Bool_t   IsInside(const Double_t *x) const { return !(  ( x[0] < fXmin) || ( x[0] > fXmax ) ); }
   virtual Bool_t   IsLinear() const { return (fFormula) ? fFormula->IsLinear() : false;}
   virtual Bool_t   IsValid() const;
   virtual void     Print(Option_t *option="") const;
   virtual void     Paint(Option_t *option="");
   virtual void     ReleaseParameter(Int_t ipar);
   virtual void     Save(Double_t xmin, Double_t xmax, Double_t ymin, Double_t ymax, Double_t zmin, Double_t zmax);
   virtual void     SavePrimitive(std::ostream &out, Option_t *option = "");
   virtual void     SetChisquare(Double_t chi2) {fChisquare = chi2;}
   virtual void     SetFitResult(const ROOT::Fit::FitResult & result, const Int_t * indpar = 0);
   template <class PtrObj, typename MemFn>
   void SetFunction( PtrObj& p, MemFn memFn );
   template <typename Func>
   void SetFunction( Func f );
   virtual void     SetMaximum(Double_t maximum=-1111); // *MENU*
   virtual void     SetMinimum(Double_t minimum=-1111); // *MENU*
   virtual void     SetNDF(Int_t ndf);
   virtual void     SetNumberFitPoints(Int_t npfits) {fNpfits = npfits;}
   virtual void     SetNormalized(Bool_t flag) { fNormalized = flag; Update(); }
   virtual void     SetNpx(Int_t npx=100); // *MENU*
   virtual void     SetParameter(Int_t param, Double_t value) {
      (fFormula) ? fFormula->SetParameter(param,value) : fParams->SetParameter(param,value);
      Update();
   }
   virtual void     SetParameter(const TString &name, Double_t value) {
      (fFormula) ? fFormula->SetParameter(name,value) : fParams->SetParameter(name,value);
      Update();
   }
   virtual void     SetParameters(const Double_t *params) {
      (fFormula) ? fFormula->SetParameters(params) : fParams->SetParameters(params);
      Update(); 
   }
   virtual void     SetParameters(Double_t p0,Double_t p1,Double_t p2=0,Double_t p3=0,Double_t p4=0,
                                     Double_t p5=0,Double_t p6=0,Double_t p7=0,Double_t p8=0,
                                     Double_t p9=0,Double_t p10=0) {
      if (fFormula) fFormula->SetParameters(p0,p1,p2,p3,p4,p5,p6,p7,p8,p9,p10);
      else          fParams->SetParameters(p0,p1,p2,p3,p4,p5,p6,p7,p8,p9,p10);
      Update();
   } // *MENU*
   virtual void     SetParName(Int_t ipar, const char *name);
   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"); // *MENU*
   virtual void     SetParError(Int_t ipar, Double_t error);
   virtual void     SetParErrors(const Double_t *errors);
   virtual void     SetParLimits(Int_t ipar, Double_t parmin, Double_t parmax);
   virtual void     SetParent(TObject *p=0) {fParent = p;}
   virtual void     SetRange(Double_t xmin, Double_t xmax); // *MENU*
   virtual void     SetRange(Double_t xmin, Double_t ymin,  Double_t xmax, Double_t ymax);
   virtual void     SetRange(Double_t xmin, Double_t ymin, Double_t zmin,  Double_t xmax, Double_t ymax, Double_t zmax);
   virtual void     SetSavedPoint(Int_t point, Double_t value);
   virtual void     SetTitle(const char *title=""); // *MENU*
   virtual void     Update();

   static  TF1     *GetCurrent();
   static  void     AbsValue(Bool_t reject=kTRUE);
   static  void     RejectPoint(Bool_t reject=kTRUE);
   static  Bool_t   RejectedPoint();
   static  void     SetCurrent(TF1 *f1);

   //Moments
   virtual Double_t Moment(Double_t n, Double_t a, Double_t b, const Double_t *params=0, Double_t epsilon=0.000001);
   virtual Double_t CentralMoment(Double_t n, Double_t a, Double_t b, const Double_t *params=0, Double_t epsilon=0.000001);
   virtual Double_t Mean(Double_t a, Double_t b, const Double_t *params=0, Double_t epsilon=0.000001) {return Moment(1,a,b,params,epsilon);}
   virtual Double_t Variance(Double_t a, Double_t b, const Double_t *params=0, Double_t epsilon=0.000001) {return CentralMoment(2,a,b,params,epsilon);}

   //some useful static utility functions to compute sampling points for Integral
   //static  void     CalcGaussLegendreSamplingPoints(TGraph *g, Double_t eps=3.0e-11);
   //static  TGraph  *CalcGaussLegendreSamplingPoints(Int_t num=21, Double_t eps=3.0e-11);
   static  void     CalcGaussLegendreSamplingPoints(Int_t num, Double_t *x, Double_t *w, Double_t eps=3.0e-11);

   ClassDef(TF1,9)  //The Parametric 1-D function
};

inline Double_t TF1::operator()(Double_t x, Double_t y, Double_t z, Double_t t) const
   { return Eval(x,y,z,t); }
inline Double_t TF1::operator()(const Double_t *x, const Double_t *params)
   {

      if (fMethodCall) InitArgs(x,params);
      return EvalPar(x,params);
   }


inline void TF1::SetRange(Double_t xmin, Double_t,  Double_t xmax, Double_t)
   { TF1::SetRange(xmin, xmax); }
inline void TF1::SetRange(Double_t xmin, Double_t, Double_t,  Double_t xmax, Double_t, Double_t)
   { TF1::SetRange(xmin, xmax); }

template <typename Func>
void TF1::SetFunction( Func f )    {
   // set function from a generic C++ callable object
   fType = 1;
   fFunctor = ROOT::Math::ParamFunctor(f);
}
template <class PtrObj, typename MemFn>
void TF1::SetFunction( PtrObj& p, MemFn memFn )   {
   // set from a pointer to a member function
   fType = 1;
   fFunctor = ROOT::Math::ParamFunctor(p,memFn);
}

#endif
 TF1.h:1
 TF1.h:2
 TF1.h:3
 TF1.h:4
 TF1.h:5
 TF1.h:6
 TF1.h:7
 TF1.h:8
 TF1.h:9
 TF1.h:10
 TF1.h:11
 TF1.h:12
 TF1.h:13
 TF1.h:14
 TF1.h:15
 TF1.h:16
 TF1.h:17
 TF1.h:18
 TF1.h:19
 TF1.h:20
 TF1.h:21
 TF1.h:22
 TF1.h:23
 TF1.h:24
 TF1.h:25
 TF1.h:26
 TF1.h:27
 TF1.h:28
 TF1.h:29
 TF1.h:30
 TF1.h:31
 TF1.h:32
 TF1.h:33
 TF1.h:34
 TF1.h:35
 TF1.h:36
 TF1.h:37
 TF1.h:38
 TF1.h:39
 TF1.h:40
 TF1.h:41
 TF1.h:42
 TF1.h:43
 TF1.h:44
 TF1.h:45
 TF1.h:46
 TF1.h:47
 TF1.h:48
 TF1.h:49
 TF1.h:50
 TF1.h:51
 TF1.h:52
 TF1.h:53
 TF1.h:54
 TF1.h:55
 TF1.h:56
 TF1.h:57
 TF1.h:58
 TF1.h:59
 TF1.h:60
 TF1.h:61
 TF1.h:62
 TF1.h:63
 TF1.h:64
 TF1.h:65
 TF1.h:66
 TF1.h:67
 TF1.h:68
 TF1.h:69
 TF1.h:70
 TF1.h:71
 TF1.h:72
 TF1.h:73
 TF1.h:74
 TF1.h:75
 TF1.h:76
 TF1.h:77
 TF1.h:78
 TF1.h:79
 TF1.h:80
 TF1.h:81
 TF1.h:82
 TF1.h:83
 TF1.h:84
 TF1.h:85
 TF1.h:86
 TF1.h:87
 TF1.h:88
 TF1.h:89
 TF1.h:90
 TF1.h:91
 TF1.h:92
 TF1.h:93
 TF1.h:94
 TF1.h:95
 TF1.h:96
 TF1.h:97
 TF1.h:98
 TF1.h:99
 TF1.h:100
 TF1.h:101
 TF1.h:102
 TF1.h:103
 TF1.h:104
 TF1.h:105
 TF1.h:106
 TF1.h:107
 TF1.h:108
 TF1.h:109
 TF1.h:110
 TF1.h:111
 TF1.h:112
 TF1.h:113
 TF1.h:114
 TF1.h:115
 TF1.h:116
 TF1.h:117
 TF1.h:118
 TF1.h:119
 TF1.h:120
 TF1.h:121
 TF1.h:122
 TF1.h:123
 TF1.h:124
 TF1.h:125
 TF1.h:126
 TF1.h:127
 TF1.h:128
 TF1.h:129
 TF1.h:130
 TF1.h:131
 TF1.h:132
 TF1.h:133
 TF1.h:134
 TF1.h:135
 TF1.h:136
 TF1.h:137
 TF1.h:138
 TF1.h:139
 TF1.h:140
 TF1.h:141
 TF1.h:142
 TF1.h:143
 TF1.h:144
 TF1.h:145
 TF1.h:146
 TF1.h:147
 TF1.h:148
 TF1.h:149
 TF1.h:150
 TF1.h:151
 TF1.h:152
 TF1.h:153
 TF1.h:154
 TF1.h:155
 TF1.h:156
 TF1.h:157
 TF1.h:158
 TF1.h:159
 TF1.h:160
 TF1.h:161
 TF1.h:162
 TF1.h:163
 TF1.h:164
 TF1.h:165
 TF1.h:166
 TF1.h:167
 TF1.h:168
 TF1.h:169
 TF1.h:170
 TF1.h:171
 TF1.h:172
 TF1.h:173
 TF1.h:174
 TF1.h:175
 TF1.h:176
 TF1.h:177
 TF1.h:178
 TF1.h:179
 TF1.h:180
 TF1.h:181
 TF1.h:182
 TF1.h:183
 TF1.h:184
 TF1.h:185
 TF1.h:186
 TF1.h:187
 TF1.h:188
 TF1.h:189
 TF1.h:190
 TF1.h:191
 TF1.h:192
 TF1.h:193
 TF1.h:194
 TF1.h:195
 TF1.h:196
 TF1.h:197
 TF1.h:198
 TF1.h:199
 TF1.h:200
 TF1.h:201
 TF1.h:202
 TF1.h:203
 TF1.h:204
 TF1.h:205
 TF1.h:206
 TF1.h:207
 TF1.h:208
 TF1.h:209
 TF1.h:210
 TF1.h:211
 TF1.h:212
 TF1.h:213
 TF1.h:214
 TF1.h:215
 TF1.h:216
 TF1.h:217
 TF1.h:218
 TF1.h:219
 TF1.h:220
 TF1.h:221
 TF1.h:222
 TF1.h:223
 TF1.h:224
 TF1.h:225
 TF1.h:226
 TF1.h:227
 TF1.h:228
 TF1.h:229
 TF1.h:230
 TF1.h:231
 TF1.h:232
 TF1.h:233
 TF1.h:234
 TF1.h:235
 TF1.h:236
 TF1.h:237
 TF1.h:238
 TF1.h:239
 TF1.h:240
 TF1.h:241
 TF1.h:242
 TF1.h:243
 TF1.h:244
 TF1.h:245
 TF1.h:246
 TF1.h:247
 TF1.h:248
 TF1.h:249
 TF1.h:250
 TF1.h:251
 TF1.h:252
 TF1.h:253
 TF1.h:254
 TF1.h:255
 TF1.h:256
 TF1.h:257
 TF1.h:258
 TF1.h:259
 TF1.h:260
 TF1.h:261
 TF1.h:262
 TF1.h:263
 TF1.h:264
 TF1.h:265
 TF1.h:266
 TF1.h:267
 TF1.h:268
 TF1.h:269
 TF1.h:270
 TF1.h:271
 TF1.h:272
 TF1.h:273
 TF1.h:274
 TF1.h:275
 TF1.h:276
 TF1.h:277
 TF1.h:278
 TF1.h:279
 TF1.h:280
 TF1.h:281
 TF1.h:282
 TF1.h:283
 TF1.h:284
 TF1.h:285
 TF1.h:286
 TF1.h:287
 TF1.h:288
 TF1.h:289
 TF1.h:290
 TF1.h:291
 TF1.h:292
 TF1.h:293
 TF1.h:294
 TF1.h:295
 TF1.h:296
 TF1.h:297
 TF1.h:298
 TF1.h:299
 TF1.h:300
 TF1.h:301
 TF1.h:302
 TF1.h:303
 TF1.h:304
 TF1.h:305
 TF1.h:306
 TF1.h:307
 TF1.h:308
 TF1.h:309
 TF1.h:310
 TF1.h:311
 TF1.h:312
 TF1.h:313
 TF1.h:314
 TF1.h:315
 TF1.h:316
 TF1.h:317
 TF1.h:318
 TF1.h:319
 TF1.h:320
 TF1.h:321
 TF1.h:322
 TF1.h:323
 TF1.h:324
 TF1.h:325
 TF1.h:326
 TF1.h:327
 TF1.h:328
 TF1.h:329
 TF1.h:330
 TF1.h:331
 TF1.h:332
 TF1.h:333
 TF1.h:334
 TF1.h:335
 TF1.h:336
 TF1.h:337
 TF1.h:338
 TF1.h:339
 TF1.h:340
 TF1.h:341
 TF1.h:342
 TF1.h:343
 TF1.h:344
 TF1.h:345
 TF1.h:346
 TF1.h:347
 TF1.h:348
 TF1.h:349
 TF1.h:350
 TF1.h:351
 TF1.h:352
 TF1.h:353
 TF1.h:354
 TF1.h:355
 TF1.h:356
 TF1.h:357
 TF1.h:358
 TF1.h:359
 TF1.h:360
 TF1.h:361
 TF1.h:362
 TF1.h:363
 TF1.h:364
 TF1.h:365
 TF1.h:366
 TF1.h:367
 TF1.h:368
 TF1.h:369
 TF1.h:370
 TF1.h:371
 TF1.h:372
 TF1.h:373
 TF1.h:374
 TF1.h:375
 TF1.h:376
 TF1.h:377
 TF1.h:378
 TF1.h:379
 TF1.h:380
 TF1.h:381
 TF1.h:382
 TF1.h:383
 TF1.h:384
 TF1.h:385
 TF1.h:386
 TF1.h:387
 TF1.h:388
 TF1.h:389
 TF1.h:390
 TF1.h:391
 TF1.h:392
 TF1.h:393
 TF1.h:394
 TF1.h:395
 TF1.h:396
 TF1.h:397
 TF1.h:398
 TF1.h:399
 TF1.h:400
 TF1.h:401
 TF1.h:402
 TF1.h:403
 TF1.h:404
 TF1.h:405
 TF1.h:406
 TF1.h:407
 TF1.h:408
 TF1.h:409
 TF1.h:410
 TF1.h:411
 TF1.h:412
 TF1.h:413
 TF1.h:414
 TF1.h:415
 TF1.h:416
 TF1.h:417
 TF1.h:418
 TF1.h:419
 TF1.h:420
 TF1.h:421
 TF1.h:422
 TF1.h:423
 TF1.h:424
 TF1.h:425
 TF1.h:426
 TF1.h:427
 TF1.h:428
 TF1.h:429
 TF1.h:430
 TF1.h:431
 TF1.h:432
 TF1.h:433
 TF1.h:434
 TF1.h:435
 TF1.h:436
 TF1.h:437
 TF1.h:438
 TF1.h:439
 TF1.h:440
 TF1.h:441
 TF1.h:442
 TF1.h:443
 TF1.h:444
 TF1.h:445
 TF1.h:446
 TF1.h:447
 TF1.h:448
 TF1.h:449
 TF1.h:450
 TF1.h:451
 TF1.h:452
 TF1.h:453
 TF1.h:454
 TF1.h:455
 TF1.h:456
 TF1.h:457
 TF1.h:458
 TF1.h:459
 TF1.h:460
 TF1.h:461
 TF1.h:462
 TF1.h:463
 TF1.h:464
 TF1.h:465
 TF1.h:466
 TF1.h:467
 TF1.h:468
 TF1.h:469
 TF1.h:470
 TF1.h:471
 TF1.h:472
 TF1.h:473
 TF1.h:474
 TF1.h:475
 TF1.h:476
 TF1.h:477
 TF1.h:478
 TF1.h:479
 TF1.h:480
 TF1.h:481
 TF1.h:482
 TF1.h:483
 TF1.h:484
 TF1.h:485
 TF1.h:486
 TF1.h:487
 TF1.h:488
 TF1.h:489
 TF1.h:490
 TF1.h:491
 TF1.h:492
 TF1.h:493
 TF1.h:494
 TF1.h:495
 TF1.h:496
 TF1.h:497
 TF1.h:498
 TF1.h:499
 TF1.h:500
 TF1.h:501
 TF1.h:502
 TF1.h:503
 TF1.h:504
 TF1.h:505
 TF1.h:506
 TF1.h:507
 TF1.h:508
 TF1.h:509
 TF1.h:510
 TF1.h:511
 TF1.h:512