00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #include "Math/WrappedTF1.h"
00014 #include "Math/WrappedMultiTF1.h"
00015
00016 #include <cmath>
00017
00018
00019 namespace ROOT {
00020
00021 namespace Math {
00022
00023
00024 double WrappedTF1::fgEps = 0.001;
00025 double WrappedMultiTF1::fgEps = 0.001;
00026
00027
00028 WrappedTF1::WrappedTF1 ( TF1 & f ) :
00029 fLinear(false),
00030 fPolynomial(false),
00031 fFunc(&f),
00032 fX (),
00033 fParams(f.GetParameters(),f.GetParameters()+f.GetNpar())
00034 {
00035
00036
00037
00038 if (fFunc->GetMethodCall() ) fFunc->InitArgs(fX, &fParams.front() );
00039
00040 if (fFunc->GetNumber() >= 300 && fFunc->GetNumber() < 310) {
00041 fLinear = true;
00042 fPolynomial = true;
00043 }
00044
00045 if (fFunc->IsLinear() ) {
00046 unsigned int ip = 0;
00047 fLinear = true;
00048 while (fLinear && ip < fParams.size() ) {
00049 fLinear &= (fFunc->GetLinearPart(ip) != 0) ;
00050 ip++;
00051 }
00052 }
00053 }
00054
00055 WrappedTF1::WrappedTF1(const WrappedTF1 & rhs) :
00056 BaseFunc(),
00057 BaseGradFunc(),
00058 IGrad(),
00059 fLinear(rhs.fLinear),
00060 fPolynomial(rhs.fPolynomial),
00061 fFunc(rhs.fFunc),
00062 fX(),
00063 fParams(rhs.fParams)
00064 {
00065
00066 fFunc->InitArgs(fX,&fParams.front() );
00067 }
00068
00069 WrappedTF1 & WrappedTF1::operator = (const WrappedTF1 & rhs) {
00070
00071 if (this == &rhs) return *this;
00072 fLinear = rhs.fLinear;
00073 fPolynomial = rhs.fPolynomial;
00074 fFunc = rhs.fFunc;
00075 fFunc->InitArgs(fX, &fParams.front() );
00076 fParams = rhs.fParams;
00077 return *this;
00078 }
00079
00080 void WrappedTF1::ParameterGradient(double x, const double * par, double * grad ) const {
00081
00082 if (!fLinear) {
00083
00084 fFunc->SetParameters( par );
00085
00086 fFunc->GradientPar(&x,grad,fgEps);
00087 }
00088 else {
00089 unsigned int np = NPar();
00090 for (unsigned int i = 0; i < np; ++i)
00091 grad[i] = DoParameterDerivative(x, par, i);
00092 }
00093 }
00094
00095 double WrappedTF1::DoDerivative( double x ) const {
00096
00097
00098
00099 double * p = (fParams.size() > 0) ? const_cast<double *>( &fParams.front()) : 0;
00100 return fFunc->Derivative(x,p,fgEps);
00101 }
00102
00103 double WrappedTF1::DoParameterDerivative(double x, const double * p, unsigned int ipar ) const {
00104
00105
00106 if (! fLinear ) {
00107 fFunc->SetParameters( p );
00108 return fFunc->GradientPar(ipar, &x,fgEps);
00109 }
00110 else if (fPolynomial) {
00111
00112 return std::pow(x, static_cast<int>(ipar) );
00113 }
00114 else {
00115
00116 const TFormula * df = dynamic_cast<const TFormula*>( fFunc->GetLinearPart(ipar) );
00117 assert(df != 0);
00118 fX[0] = x;
00119
00120 return (const_cast<TFormula*> ( df) )->EvalPar( fX ) ;
00121 }
00122 }
00123
00124 void WrappedTF1::SetDerivPrecision(double eps) { fgEps = eps; }
00125
00126 double WrappedTF1::GetDerivPrecision( ) { return fgEps; }
00127
00128
00129
00130
00131
00132
00133 WrappedMultiTF1::WrappedMultiTF1 (TF1 & f, unsigned int dim ) :
00134 fLinear(false),
00135 fFunc(&f),
00136 fDim(dim),
00137 fParams(f.GetParameters(),f.GetParameters()+f.GetNpar())
00138 {
00139
00140
00141
00142 if (fDim == 0) fDim = fFunc->GetNdim();
00143
00144
00145
00146
00147 if (fFunc->IsLinear() ) {
00148 unsigned int ip = 0;
00149 fLinear = true;
00150 while (fLinear && ip < fParams.size() ) {
00151 fLinear &= (fFunc->GetLinearPart(ip) != 0) ;
00152 ip++;
00153 }
00154 }
00155 }
00156
00157
00158 WrappedMultiTF1::WrappedMultiTF1(const WrappedMultiTF1 & rhs) :
00159 BaseFunc(),
00160 BaseParamFunc(),
00161 fLinear(rhs.fLinear),
00162 fFunc(rhs.fFunc),
00163 fDim(rhs.fDim),
00164 fParams(rhs.fParams)
00165 {
00166
00167 }
00168
00169
00170 WrappedMultiTF1 & WrappedMultiTF1::operator= (const WrappedMultiTF1 & rhs) {
00171
00172 if (this == &rhs) return *this;
00173 fLinear = rhs.fLinear;
00174 fFunc = rhs.fFunc;
00175 fDim = rhs.fDim;
00176 fParams = rhs.fParams;
00177 return *this;
00178 }
00179
00180
00181 void WrappedMultiTF1::ParameterGradient(const double * x, const double * par, double * grad ) const {
00182
00183 if (!fLinear) {
00184
00185 fFunc->SetParameters( par );
00186
00187 fFunc->GradientPar(x,grad,fgEps);
00188 }
00189 else {
00190 unsigned int np = NPar();
00191 for (unsigned int i = 0; i < np; ++i)
00192 grad[i] = DoParameterDerivative(x, par, i);
00193 }
00194 }
00195
00196 double WrappedMultiTF1::DoParameterDerivative(const double * x, const double * p, unsigned int ipar ) const {
00197
00198 if (! fLinear ) {
00199 fFunc->SetParameters( p );
00200 return fFunc->GradientPar(ipar, x,fgEps);
00201 }
00202 else {
00203
00204 const TFormula * df = dynamic_cast<const TFormula*>( fFunc->GetLinearPart(ipar) );
00205 assert(df != 0);
00206
00207 return (const_cast<TFormula*> ( df) )->EvalPar( x ) ;
00208 }
00209 }
00210
00211 void WrappedMultiTF1::SetDerivPrecision(double eps) { fgEps = eps; }
00212
00213 double WrappedMultiTF1::GetDerivPrecision( ) { return fgEps; }
00214
00215
00216 }
00217
00218 }
00219
00220