13 #ifndef ROOT_Math_WrappedMultiTF1 
   14 #define ROOT_Math_WrappedMultiTF1 
   26          double DerivPrecision(
double eps);
 
   27          TF1 *CopyTF1Ptr(
const TF1 *funcToCopy);
 
   45       class WrappedMultiTF1Templ: 
virtual public ROOT::Math::IParametricGradFunctionMultiDimTempl<T> {
 
   49          typedef  ROOT::Math::IParametricGradFunctionMultiDimTempl<T>  BaseParamFunc;
 
   50          typedef  typename ROOT::Math::IParametricFunctionMultiDimTempl<T>::BaseFunc  BaseFunc;
 
   58          WrappedMultiTF1Templ(TF1 &f, 
unsigned int dim = 0);
 
   63          ~WrappedMultiTF1Templ()
 
   65             if (fOwnFunc && fFunc) 
delete fFunc;
 
   71          WrappedMultiTF1Templ(
const WrappedMultiTF1Templ<T> &rhs);
 
   76          WrappedMultiTF1Templ &operator = (
const WrappedMultiTF1Templ<T> &rhs);
 
   83          IMultiGenFunctionTempl<T> *Clone()
 const 
   85             return new WrappedMultiTF1Templ<T>(*this);
 
   91          unsigned int NDim()
 const 
   97          const double *Parameters()
 const 
  100             return  fFunc->GetParameters();
 
  104          void SetParameters(
const double *p)
 
  107             fFunc->SetParameters(p);
 
  111          unsigned int NPar()
 const 
  114             return fFunc->GetNpar();
 
  118          std::string ParameterName(
unsigned int i)
 const {
 
  119             return std::string(fFunc->GetParName(i));
 
  123          void ParameterGradient(
const T *x, 
const double *par, T *grad) 
const;
 
  127          static void SetDerivPrecision(
double eps);
 
  130          static double GetDerivPrecision();
 
  133          const TF1 *GetFunction()
 const 
  140          void SetAndCopyFunction(
const TF1 *f = 0);
 
  144          T DoEvalPar(
const T *x, 
const double *p)
 const 
  146             return fFunc->EvalPar(x, p);
 
  151          T DoEvalVec(
const T *x)
 const 
  153             return fFunc->EvalPar(x, 0);
 
  158          T DoEval(
const T *x)
 const 
  163             return fFunc->EvalPar(x, 0);
 
  167          T DoParameterDerivative(
const T *x, 
const double *p, 
unsigned int ipar) 
const;
 
  188       struct GeneralLinearFunctionDerivation {
 
  189          static T DoParameterDerivative(
const WrappedMultiTF1Templ<T> *, 
const T *, 
unsigned int)
 
  191             Error(
"DoParameterDerivative", 
"The vectorized implementation of DoParameterDerivative does not support" 
  192                                            "general linear functions built in TFormula with ++");
 
  194             return TMath::SignalingNaN();
 
  199       struct GeneralLinearFunctionDerivation<double> {
 
  201          DoParameterDerivative(
const WrappedMultiTF1Templ<double> *wrappedFunc, 
const double *x, 
unsigned int ipar)
 
  203             const TFormula *df = 
dynamic_cast<const TFormula *
>(wrappedFunc->GetFunction()->GetLinearPart(ipar));
 
  205             return (const_cast<TFormula *>(df))->EvalPar(x); 
 
  212       WrappedMultiTF1Templ<T>::WrappedMultiTF1Templ(TF1 &f, 
unsigned int dim)  :
 
  223          if (fDim == 0) fDim = fFunc->GetNdim();
 
  228          if (fFunc->IsLinear()) {
 
  231             while (fLinear && ip < fFunc->GetNpar())  {
 
  232                fLinear &= (fFunc->GetLinearPart(ip) != 0) ;
 
  237          if (fDim == 1 && fFunc->GetNumber() >= 300 && fFunc->GetNumber() < 310) {
 
  244       WrappedMultiTF1Templ<T>::WrappedMultiTF1Templ(
const WrappedMultiTF1Templ<T> &rhs) :
 
  246          fLinear(rhs.fLinear),
 
  247          fPolynomial(rhs.fPolynomial),
 
  248          fOwnFunc(rhs.fOwnFunc),
 
  254          if (fOwnFunc) SetAndCopyFunction(rhs.fFunc);
 
  258       WrappedMultiTF1Templ<T> &WrappedMultiTF1Templ<T>::operator= (
const WrappedMultiTF1Templ<T> &rhs)
 
  261          if (
this == &rhs) 
return *
this;  
 
  262          fLinear = rhs.fLinear;
 
  263          fPolynomial = rhs.fPolynomial;
 
  264          fOwnFunc = rhs.fOwnFunc;
 
  271       void WrappedMultiTF1Templ<T>::ParameterGradient(
const T *x, 
const double *par, T *grad)
 const 
  280             fFunc->SetParameters(par);
 
  282             double prec = this->GetDerivPrecision();
 
  283             fFunc->GradientPar(x, grad, prec);
 
  285             unsigned int np = NPar();
 
  286             for (
unsigned int i = 0; i < np; ++i)
 
  287                grad[i] = DoParameterDerivative(x, par, i);
 
  292       T WrappedMultiTF1Templ<T>::DoParameterDerivative(
const T *x, 
const double *p, 
unsigned int ipar)
 const 
  297             fFunc->SetParameters(p);
 
  298             double prec = this->GetDerivPrecision();
 
  299             return fFunc->GradientPar(ipar, x, prec);
 
  304             if (ipar == 0) 
return 1.0;
 
  305 #ifdef R__HAS_VECCORE 
  306             return vecCore::math::Pow(x[0], static_cast<T>(ipar));
 
  308             return std::pow(x[0], static_cast<int>(ipar));
 
  312             return GeneralLinearFunctionDerivation<T>::DoParameterDerivative(
this, x, ipar);
 
  316       void WrappedMultiTF1Templ<T>::SetDerivPrecision(
double eps)
 
  318          ::ROOT::Math::Internal::DerivPrecision(eps);
 
  322       double WrappedMultiTF1Templ<T>::GetDerivPrecision()
 
  324          return ::ROOT::Math::Internal::DerivPrecision(-1);
 
  328       void WrappedMultiTF1Templ<T>::SetAndCopyFunction(
const TF1 *f)
 
  330          const TF1 *funcToCopy = (f) ? f : fFunc;
 
  331          fFunc = ::ROOT::Math::Internal::CopyTF1Ptr(funcToCopy);
 
  335       using WrappedMultiTF1 = WrappedMultiTF1Templ<double>;