File indexing completed on 2025-01-18 10:10:23
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016 #ifndef ROOT_Math_WrappedParamFunction
0017 #define ROOT_Math_WrappedParamFunction
0018
0019 #include "Math/IParamFunction.h"
0020
0021
0022
0023
0024 #include <vector>
0025
0026
0027 namespace ROOT {
0028
0029 namespace Math {
0030
0031
0032 typedef double( * FreeParamMultiFunctionPtr ) (const double *, const double * );
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043 template< typename FuncPtr = FreeParamMultiFunctionPtr >
0044 class WrappedParamFunction : public IParamMultiFunction {
0045
0046 public:
0047
0048
0049
0050
0051
0052 WrappedParamFunction (FuncPtr func, unsigned int dim = 1, unsigned int npar = 0, double * par = nullptr) :
0053 fFunc(func),
0054 fDim(dim),
0055 fParams(std::vector<double>(npar) )
0056 {
0057 if (par) std::copy(par, par+npar, fParams.begin());
0058 }
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074
0075
0076
0077 template<class Iterator>
0078 WrappedParamFunction (FuncPtr func, unsigned int dim, Iterator begin, Iterator end) :
0079 fFunc(func),
0080 fDim(dim),
0081 fParams(std::vector<double>(begin,end) )
0082 {}
0083
0084
0085
0086
0087
0088
0089
0090
0091
0092
0093
0094
0095
0096 IMultiGenFunction * Clone() const override {
0097 return new WrappedParamFunction(fFunc, fDim, fParams.begin(), fParams.end());
0098 }
0099
0100 const double * Parameters() const override {
0101 return fParams.empty() ? nullptr : &fParams.front();
0102 }
0103
0104 void SetParameters(const double * p) override {
0105 std::copy(p, p+NPar(), fParams.begin() );
0106 }
0107
0108 unsigned int NPar() const override { return fParams.size(); }
0109
0110 unsigned int NDim() const override { return fDim; }
0111
0112
0113 private:
0114
0115
0116 double DoEvalPar(const double * x, const double * p) const override {
0117 return (*fFunc)( x, p );
0118 }
0119
0120
0121 FuncPtr fFunc;
0122 unsigned int fDim;
0123 std::vector<double> fParams;
0124
0125
0126
0127 };
0128
0129
0130 typedef double( * FreeMultiFunctionPtr ) (const double *);
0131
0132
0133
0134
0135
0136
0137
0138
0139
0140
0141
0142 template< typename FuncPtr = FreeMultiFunctionPtr >
0143 class WrappedParamFunctionGen : public IParamMultiFunction {
0144
0145 public:
0146
0147
0148
0149
0150
0151
0152 WrappedParamFunctionGen (const FuncPtr & func, unsigned int dim, unsigned int npar, const double * par, const unsigned int * idx) :
0153 fFunc(func),
0154 fDim(dim),
0155 fParams(std::vector<double>(par,par+npar) ),
0156 fParIndices(std::vector<unsigned int>(idx, idx + npar) ),
0157 fX(std::vector<double>(npar+dim) )
0158 {
0159 DoInit();
0160 }
0161
0162
0163
0164
0165
0166 WrappedParamFunctionGen (FuncPtr & func, unsigned int dim, unsigned int npar, const double * par, const unsigned int * idx) :
0167 fFunc(func),
0168 fDim(dim),
0169 fParams(std::vector<double>(par,par+npar) ),
0170 fParIndices(std::vector<unsigned int>(idx, idx + npar) ),
0171 fX(std::vector<double>(npar+dim) )
0172 {
0173 DoInit();
0174 }
0175
0176
0177 IMultiGenFunction * Clone() const override {
0178 return new WrappedParamFunctionGen(fFunc, fDim, fParams.size(), fParams.empty() ? nullptr : &fParams.front(), fParIndices.empty() ? nullptr : &fParIndices.front());
0179 }
0180
0181 private:
0182
0183 WrappedParamFunctionGen(const WrappedParamFunctionGen &) = delete;
0184 WrappedParamFunctionGen & operator=(const WrappedParamFunctionGen &) = delete;
0185
0186 public:
0187
0188 const double * Parameters() const override {
0189 return fParams.empty() ? nullptr : &fParams.front();
0190 }
0191
0192 void SetParameters(const double * p) override {
0193 unsigned int npar = NPar();
0194 std::copy(p, p+ npar, fParams.begin() );
0195 SetParValues(npar, p);
0196 }
0197
0198 unsigned int NPar() const override { return fParams.size(); }
0199
0200 unsigned int NDim() const override { return fDim; }
0201
0202
0203
0204
0205
0206
0207
0208
0209
0210 private:
0211
0212
0213 double DoEval(const double * x) const override {
0214
0215
0216
0217
0218
0219
0220
0221
0222
0223 for (unsigned int i = 0; i < fDim; ++i) {
0224 unsigned int j = fVarIndices[i];
0225 assert ( j < NPar() + fDim);
0226 fX[ j ] = x[i];
0227 }
0228
0229
0230
0231
0232
0233 return (*fFunc)( fX.empty() ? nullptr : &fX.front() );
0234 }
0235
0236
0237
0238
0239
0240 double DoEvalPar(const double * x, const double * p ) const override {
0241 SetParValues(NPar(), p);
0242 return DoEval(x);
0243 }
0244
0245
0246 void DoInit() {
0247
0248 fVarIndices.reserve(fDim);
0249 unsigned int npar = NPar();
0250 for (unsigned int i = 0; i < npar + fDim; ++i) {
0251 bool isVar = true;
0252 for (unsigned int j = 0; j < npar; ++j) {
0253 if (fParIndices[j] == i) {
0254 isVar = false;
0255 break;
0256 }
0257 }
0258 if (isVar) fVarIndices.push_back(i);
0259 }
0260 assert ( fVarIndices.size() == fDim);
0261
0262
0263
0264
0265
0266
0267
0268
0269
0270 SetParValues(npar, fParams.empty() ? nullptr : &fParams.front());
0271 for (unsigned int i = 0; i < npar; ++i) {
0272 unsigned int j = fParIndices[i];
0273 assert ( j < npar + fDim);
0274 fX[j] = fParams[i];
0275 }
0276
0277 }
0278
0279
0280
0281 void SetParValues(unsigned int npar, const double * p) const {
0282 for (unsigned int i = 0; i < npar; ++i) {
0283 unsigned int j = fParIndices[i];
0284 assert ( j < npar + fDim);
0285 fX[j] = p[i];
0286 }
0287 }
0288
0289
0290 mutable FuncPtr fFunc;
0291 unsigned int fDim;
0292 std::vector<double> fParams;
0293 std::vector<unsigned int> fVarIndices;
0294 std::vector<unsigned int> fParIndices;
0295 mutable std::vector<double> fX;
0296
0297
0298
0299 };
0300
0301
0302 }
0303
0304 }
0305
0306
0307 #endif