#ifndef ROOT_Math_WrappedTF1
#define ROOT_Math_WrappedTF1
#ifndef ROOT_Math_IParamFunction
#include "Math/IParamFunction.h"
#endif
#ifndef ROOT_TF1
#include "TF1.h"
#endif
#include <cmath>
namespace ROOT {
namespace Math {
class WrappedTF1 : public ROOT::Math::IParamGradFunction {
public:
typedef ROOT::Math::IParamGradFunction BaseGradFunc;
typedef ROOT::Math::IParamGradFunction::BaseFunc BaseFunc;
WrappedTF1() {}
WrappedTF1 ( TF1 & f ) :
fLinear(false),
fPolynomial(false),
fFunc(&f),
fParams(f.GetParameters(),f.GetParameters()+f.GetNpar())
{
if (fFunc->GetMethodCall() ) fFunc->InitArgs(fX, &fParams.front() );
if (fFunc->GetNumber() >= 300 && fFunc->GetNumber() < 310) {
fLinear = true;
fPolynomial = true;
}
if (fFunc->IsLinear() ) {
unsigned int ip = 0;
fLinear = true;
while (fLinear && ip < fParams.size() ) {
fLinear &= (fFunc->GetLinearPart(ip) != 0) ;
ip++;
}
}
}
virtual ~WrappedTF1 () {}
WrappedTF1(const WrappedTF1 & rhs) :
BaseFunc(),
BaseGradFunc(),
fLinear(rhs.fLinear),
fPolynomial(rhs.fPolynomial),
fFunc(rhs.fFunc),
fParams(rhs.fParams)
{
fFunc->InitArgs(fX,&fParams.front() );
}
WrappedTF1 & operator = (const WrappedTF1 & rhs) {
if (this == &rhs) return *this;
fLinear = rhs.fLinear;
fPolynomial = rhs.fPolynomial;
fFunc = rhs.fFunc;
fFunc->InitArgs(fX, &fParams.front() );
fParams = rhs.fParams;
return *this;
}
ROOT::Math::IGenFunction * Clone() const {
return new WrappedTF1(*this);
}
const double * Parameters() const {
return &fParams.front();
}
void SetParameters(const double * p) {
std::copy(p,p+fParams.size(),fParams.begin());
}
unsigned int NPar() const {
return fParams.size();
}
std::string ParameterName(unsigned int i) const {
return std::string(fFunc->GetParName(i));
}
using BaseGradFunc::operator();
void ParameterGradient(double x, const double * par, double * grad ) const {
if (!fLinear) {
fFunc->SetParameters( par );
static const double kEps = 0.001;
fFunc->GradientPar(&x,grad,kEps);
}
else {
unsigned int np = NPar();
for (unsigned int i = 0; i < np; ++i)
grad[i] = DoParameterDerivative(x, par, i);
}
}
private:
double DoEvalPar (double x, const double * p ) const {
fX[0] = x;
if (fFunc->GetMethodCall() ) fFunc->InitArgs(fX,p);
return fFunc->EvalPar(fX,p);
}
double DoEval (double x) const {
fX[0] = x;
return fFunc->EvalPar(fX,&fParams.front());
}
double DoDerivative( double x ) const {
static const double kEps = 0.001;
double * p = const_cast<double *>(&fParams.front() );
return fFunc->Derivative(x,p,kEps);
}
double DoParameterDerivative(double x, const double * p, unsigned int ipar ) const {
if (! fLinear ) {
std::vector<double> grad(NPar());
ParameterGradient(x, p, &grad[0] );
return grad[ipar];
}
else if (fPolynomial) {
return std::pow(x, static_cast<int>(ipar) );
}
else {
const TFormula * df = dynamic_cast<const TFormula*>( fFunc->GetLinearPart(ipar) );
assert(df != 0);
fX[0] = x;
return (const_cast<TFormula*> ( df) )->EvalPar( fX ) ;
}
}
bool fLinear;
bool fPolynomial;
TF1 * fFunc;
mutable double fX[1];
std::vector<double> fParams;
};
}
}
#endif /* ROOT_Fit_WrappedTF1 */
Last change: Tue Dec 16 12:07:04 2008
Last generated: 2008-12-16 12:07
This page has been automatically generated. If you have any comments or suggestions about the page layout send a mail to ROOT support, or contact the developers with any questions or problems regarding ROOT.