#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.