File indexing completed on 2025-01-18 10:10:20
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013 #ifndef ROOT_Math_OneDimFunctionAdapter
0014 #define ROOT_Math_OneDimFunctionAdapter
0015
0016 #include "Math/IFunction.h"
0017 #include "Math/IParamFunction.h"
0018
0019 #include <cassert>
0020
0021 namespace ROOT {
0022
0023 namespace Math {
0024
0025
0026
0027
0028 template<class MultiFuncType>
0029 struct EvaluatorOneDim {
0030
0031 static double F (MultiFuncType f, const double * x, const double * = nullptr ) {
0032 return f( x );
0033 }
0034 };
0035
0036 template<>
0037 struct EvaluatorOneDim< const ROOT::Math::IParamMultiFunction &> {
0038 static double F ( const ROOT::Math::IParamMultiFunction & f, const double * x, const double * p = nullptr ) {
0039 return f( x, p );
0040 }
0041 };
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055 template <class MultiFuncType = const ROOT::Math::IMultiGenFunction &>
0056 class OneDimMultiFunctionAdapter : public ROOT::Math::IGenFunction {
0057
0058 public:
0059
0060
0061
0062
0063
0064
0065 OneDimMultiFunctionAdapter (MultiFuncType f, const double * x, unsigned int icoord = 0, const double * p = nullptr ) :
0066 fFunc(f),
0067 fX( const_cast<double *>(x) ),
0068 fParams(p),
0069 fCoord(icoord),
0070 fDim(0),
0071 fOwn(false)
0072 {
0073 assert(fX != nullptr);
0074 }
0075
0076
0077
0078
0079
0080
0081 OneDimMultiFunctionAdapter (MultiFuncType f, unsigned int dim = 1, unsigned int icoord = 0, const double *p = nullptr) :
0082 fFunc(f),
0083 fX(nullptr),
0084 fParams(p),
0085 fCoord(icoord),
0086 fDim(dim),
0087 fOwn(true)
0088 {
0089 fX = new double[dim];
0090 }
0091
0092
0093
0094
0095 ~OneDimMultiFunctionAdapter () override { if (fOwn && fX) delete [] fX; }
0096
0097
0098
0099
0100 OneDimMultiFunctionAdapter * Clone( ) const override {
0101 if (fOwn) {
0102 OneDimMultiFunctionAdapter * f = new OneDimMultiFunctionAdapter( fFunc, fDim, fCoord, fParams);
0103 std::copy(fX, fX+fDim, f->fX);
0104 return f;
0105 }
0106 else
0107 return new OneDimMultiFunctionAdapter( fFunc, fX, fCoord, fParams);
0108 }
0109
0110 public:
0111
0112
0113
0114
0115
0116 template<class Iterator>
0117 void SetX(Iterator begin, Iterator end) {
0118 if (fOwn) std::copy(begin, end, fX);
0119 }
0120
0121
0122
0123
0124
0125 void SetX(double * x) {
0126 if (!fOwn) fX = x;
0127 }
0128
0129
0130
0131
0132 void SetX(const double * x) {
0133 if (fOwn) std::copy(x, x+fDim, fX);
0134 else
0135 SetX( const_cast<double *>(x) );
0136 }
0137
0138
0139 void SetCoord(int icoord) { fCoord=icoord;}
0140
0141
0142 OneDimMultiFunctionAdapter( const OneDimMultiFunctionAdapter & rhs) :
0143 fFunc(rhs.fFunc),
0144 fParams(rhs.fParams),
0145 fCoord(rhs.fCoord),
0146 fDim(rhs.fDim),
0147 fOwn(rhs.fOwn)
0148 {
0149 if (fOwn) {
0150 fX = new double[fDim];
0151 std::copy( rhs.fX, rhs.fX+fDim, fX);
0152 }
0153 else fX = rhs.fX;
0154 }
0155
0156
0157 private:
0158
0159
0160 OneDimMultiFunctionAdapter & operator= ( const OneDimMultiFunctionAdapter & rhs) {
0161 if (this == &rhs) return *this;
0162 assert(false);
0163 }
0164
0165
0166
0167
0168
0169 double DoEval(double x) const override {
0170 if (fOwn) {
0171 fX[fCoord] = x;
0172 return EvaluatorOneDim<MultiFuncType>::F( fFunc, fX, fParams );
0173 }
0174 else {
0175
0176
0177
0178 double xprev = fX[fCoord];
0179 fX[fCoord] = x;
0180 double y = EvaluatorOneDim<MultiFuncType>::F( fFunc, fX, fParams );
0181
0182 fX[fCoord] = xprev;
0183 return y;
0184 }
0185 }
0186
0187
0188 private:
0189
0190 MultiFuncType fFunc;
0191 mutable double * fX;
0192 const double * fParams;
0193 unsigned int fCoord;
0194 unsigned int fDim;
0195 bool fOwn;
0196
0197 };
0198
0199
0200
0201
0202
0203
0204
0205
0206
0207
0208
0209
0210
0211
0212 template <class ParamFuncType = ROOT::Math::IParamMultiFunction &>
0213 class OneDimParamFunctionAdapter : public ROOT::Math::IGenFunction {
0214
0215 public:
0216
0217
0218
0219
0220
0221 OneDimParamFunctionAdapter (ParamFuncType f, const double * x, const double * p, unsigned int ipar =0 ) :
0222 fFunc(f),
0223 fX(x ),
0224 fParams(p),
0225 fIpar(ipar)
0226 {
0227 assert(fX != nullptr);
0228 assert(fParams != nullptr);
0229 }
0230
0231
0232
0233
0234 ~OneDimParamFunctionAdapter () override {}
0235
0236
0237
0238
0239 OneDimParamFunctionAdapter * Clone( ) const override {
0240 return new OneDimParamFunctionAdapter(fFunc, fX, fParams, fIpar);
0241 }
0242
0243
0244
0245 private:
0246
0247
0248
0249
0250
0251 double DoEval(double x) const override {
0252
0253 double * p = const_cast<double *>(fParams);
0254 double pprev = fParams[fIpar];
0255 p[fIpar] = x;
0256 double y = fFunc( fX, p );
0257 p[fIpar] = pprev;
0258 return y;
0259 }
0260
0261
0262 private:
0263
0264 ParamFuncType fFunc;
0265 const double * fX;
0266 const double * fParams;
0267 unsigned int fIpar;
0268
0269 };
0270
0271
0272 }
0273
0274 }
0275
0276
0277 #endif