00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #ifndef ROOT_Math_OneDimFunctionAdapter
00014 #define ROOT_Math_OneDimFunctionAdapter
00015
00016 #ifndef ROOT_Math_IFunction
00017 #include "Math/IFunction.h"
00018 #endif
00019 #ifndef ROOT_Math_IParamFunction
00020 #include "Math/IParamFunction.h"
00021 #endif
00022
00023 #include <cassert>
00024
00025 namespace ROOT {
00026
00027 namespace Math {
00028
00029
00030
00031
00032 template<class MultiFuncType>
00033 struct EvaluatorOneDim {
00034
00035 static double F (MultiFuncType f, const double * x, const double * = 0 ) {
00036 return f( x );
00037 }
00038 };
00039
00040 template<>
00041 struct EvaluatorOneDim< const ROOT::Math::IParamMultiFunction &> {
00042 static double F ( const ROOT::Math::IParamMultiFunction & f, const double * x, const double * p = 0 ) {
00043 return f( x, p );
00044 }
00045 };
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059 template <class MultiFuncType = const ROOT::Math::IMultiGenFunction &>
00060 class OneDimMultiFunctionAdapter : public ROOT::Math::IGenFunction {
00061
00062 public:
00063
00064
00065
00066
00067
00068
00069 OneDimMultiFunctionAdapter (MultiFuncType f, const double * x, unsigned int icoord =0, const double * p = 0 ) :
00070 fFunc(f),
00071 fX( const_cast<double *>(x) ),
00072 fParams(p),
00073 fCoord(icoord),
00074 fDim(0),
00075 fOwn(false)
00076 {
00077 assert(fX != 0);
00078 }
00079
00080
00081
00082
00083
00084
00085 OneDimMultiFunctionAdapter (MultiFuncType f, unsigned int dim = 1, unsigned int icoord =0, const double * p = 0 ) :
00086 fFunc(f),
00087 fX(0 ),
00088 fParams(p),
00089 fCoord(icoord),
00090 fDim(dim),
00091 fOwn(true)
00092 {
00093 fX = new double[dim];
00094 }
00095
00096
00097
00098
00099 virtual ~OneDimMultiFunctionAdapter () { if (fOwn && fX) delete [] fX; }
00100
00101
00102
00103
00104 virtual OneDimMultiFunctionAdapter * Clone( ) const {
00105 if (fOwn)
00106 return new OneDimMultiFunctionAdapter( fFunc, fDim, fCoord, fParams);
00107 else
00108 return new OneDimMultiFunctionAdapter( fFunc, fX, fCoord, fParams);
00109 }
00110
00111 public:
00112
00113
00114
00115
00116
00117 template<class Iterator>
00118 void SetX(Iterator begin, Iterator end) {
00119 if (fOwn) std::copy(begin, end, fX);
00120 }
00121
00122
00123
00124
00125
00126 void SetX(double * x) {
00127 if (!fOwn) fX = x;
00128 }
00129
00130
00131
00132
00133 void SetX(const double * x) {
00134 if (fOwn) std::copy(x, x+fDim, fX);
00135 else
00136 SetX( const_cast<double *>(x) );
00137 }
00138
00139
00140 void SetCoord(int icoord) { fCoord=icoord;}
00141
00142
00143 OneDimMultiFunctionAdapter( const OneDimMultiFunctionAdapter & rhs) :
00144 fFunc(rhs.fFunc),
00145 fParams(rhs.fParams),
00146 fCoord(rhs.fCoord),
00147 fDim(rhs.fDim),
00148 fOwn(rhs.fOwn)
00149 {
00150 if (fOwn) {
00151 fX = new double[fDim];
00152 std::copy( rhs.fX, rhs.fX+fDim, fX);
00153 }
00154 else fX = rhs.fX;
00155 }
00156
00157
00158 private:
00159
00160
00161 OneDimMultiFunctionAdapter & operator= ( const OneDimMultiFunctionAdapter & rhs) {
00162 if (this == &rhs) return *this;
00163 assert(false);
00164 }
00165
00166
00167
00168
00169
00170 double DoEval(double x) const {
00171 if (fOwn) {
00172 fX[fCoord] = x;
00173 return EvaluatorOneDim<MultiFuncType>::F( fFunc, fX, fParams );
00174 }
00175 else {
00176
00177
00178
00179 double xprev = fX[fCoord];
00180 fX[fCoord] = x;
00181 double y = EvaluatorOneDim<MultiFuncType>::F( fFunc, fX, fParams );
00182
00183 fX[fCoord] = xprev;
00184 return y;
00185 }
00186 }
00187
00188
00189 private:
00190
00191 MultiFuncType fFunc;
00192 mutable double * fX;
00193 const double * fParams;
00194 unsigned int fCoord;
00195 unsigned int fDim;
00196 bool fOwn;
00197
00198 };
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213 template <class ParamFuncType = ROOT::Math::IParamMultiFunction &>
00214 class OneDimParamFunctionAdapter : public ROOT::Math::IGenFunction {
00215
00216 public:
00217
00218
00219
00220
00221
00222 OneDimParamFunctionAdapter (ParamFuncType f, const double * x, const double * p, unsigned int ipar =0 ) :
00223 fFunc(f),
00224 fX(x ),
00225 fParams(p),
00226 fIpar(ipar)
00227 {
00228 assert(fX != 0);
00229 assert(fParams != 0);
00230 }
00231
00232
00233
00234
00235 ~OneDimParamFunctionAdapter () {}
00236
00237
00238
00239
00240 virtual OneDimParamFunctionAdapter * Clone( ) const {
00241 return new OneDimParamFunctionAdapter(fFunc, fX, fParams, fIpar);
00242 }
00243
00244
00245
00246 private:
00247
00248
00249
00250
00251
00252 double DoEval(double x) const {
00253
00254 double * p = const_cast<double *>(fParams);
00255 double pprev = fParams[fIpar];
00256 p[fIpar] = x;
00257 double y = fFunc( fX, p );
00258 p[fIpar] = pprev;
00259 return y;
00260 }
00261
00262
00263 private:
00264
00265 ParamFuncType fFunc;
00266 const double * fX;
00267 const double * fParams;
00268 unsigned int fIpar;
00269
00270 };
00271
00272
00273
00274
00275 }
00276
00277 }
00278
00279
00280 #endif