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>;