Logo ROOT   6.19/01
Reference Guide
WrappedParamFunction.h
Go to the documentation of this file.
1 // @(#)root/mathcore:$Id$
2 // Author: L. Moneta Thu Nov 23 10:38:32 2006
3 
4 /**********************************************************************
5  * *
6  * Copyright (c) 2006 LCG ROOT Math Team, CERN/PH-SFT *
7  * *
8  * *
9  **********************************************************************/
10 
11 // Header file for class WrappedParamFunction
12 
13 #ifndef ROOT_Math_WrappedParamFunction
14 #define ROOT_Math_WrappedParamFunction
15 
16 #include "Math/IParamFunction.h"
17 
18 //#include <iostream>
19 //#include <iterator>
20 
21 #include <vector>
22 
23 
24 namespace ROOT {
25 
26  namespace Math {
27 
28 
29 typedef double( * FreeParamMultiFunctionPtr ) (const double *, const double * );
30 
31 /**
32  WrappedParamFunction class to wrap any multi-dimensional function pbject
33  implementing the operator()(const double * x, const double * p)
34  in an interface-like IParamFunction with a vector storing and caching internally the
35  parameter values
36 
37  @ingroup ParamFunc
38 
39 */
40 template< typename FuncPtr = FreeParamMultiFunctionPtr >
42 
43 public:
44 
45  /**
46  Constructor a wrapped function from a pointer to a callable object, the function dimension and number of parameters
47  which are set to zero by default
48  */
49  WrappedParamFunction (FuncPtr func, unsigned int dim = 1, unsigned int npar = 0, double * par = 0) :
50  fFunc(func),
51  fDim(dim),
52  fParams(std::vector<double>(npar) )
53  {
54  if (par != 0) std::copy(par,par+npar,fParams.begin() );
55  }
56 
57 // /**
58 // Constructor a wrapped function from a non-const pointer to a callable object, the function dimension and number of parameters
59 // which are set to zero by default
60 // This constructor is needed in the case FuncPtr is a std::unique_ptr which has a copy ctor taking non const objects
61 // */
62 // WrappedParamFunction (FuncPtr & func, unsigned int dim = 1, unsigned int npar = 0, double * par = 0) :
63 // fFunc(func),
64 // fDim(dim),
65 // fParams(std::vector<double>(npar) )
66 // {
67 // if (par != 0) std::copy(par,par+npar,fParams.begin() );
68 // }
69 
70  /**
71  Constructor a wrapped function from a pointer to a callable object, the function dimension and an iterator specifying begin and end
72  of parameters
73  */
74  template<class Iterator>
75  WrappedParamFunction (FuncPtr func, unsigned int dim, Iterator begin, Iterator end) :
76  fFunc(func),
77  fDim(dim),
78  fParams(std::vector<double>(begin,end) )
79  {}
80 
81 // /**
82 // Constructor a wrapped function from a non - const pointer to a callable object, the function dimension and an iterator specifying begin and end of parameters.
83 // This constructor is needed in the case FuncPtr is a std::unique_ptr which has a copy ctor taking non const objects
84 // */
85 // template<class Iterator>
86 // WrappedParamFunction (FuncPtr func, unsigned int dim, Iterator begin, Iterator end) :
87 // fFunc(func),
88 // fDim(dim),
89 // fParams(std::vector<double>(begin,end) )
90 // {}
91 
92  /// clone the function
94  return new WrappedParamFunction(fFunc, fDim, fParams.begin(), fParams.end());
95  }
96 
97  const double * Parameters() const {
98  return fParams.empty() ? nullptr : &fParams.front();
99  }
100 
101  void SetParameters(const double * p) {
102  std::copy(p, p+NPar(), fParams.begin() );
103  }
104 
105  unsigned int NPar() const { return fParams.size(); }
106 
107  unsigned int NDim() const { return fDim; }
108 
109 
110 private:
111 
112  /// evaluate the function given values and parameters (requested interface)
113  double DoEvalPar(const double * x, const double * p) const {
114  return (*fFunc)( x, p );
115  }
116 
117 
118  FuncPtr fFunc;
119  unsigned int fDim;
120  std::vector<double> fParams;
121 
122 
123 
124 };
125 
126 
127 typedef double( * FreeMultiFunctionPtr ) (const double *);
128 
129 /**
130  WrappedParamGenFunction class to wrap any multi-dimensional function
131  implementing the operator()(const double * )
132  in an interface-like IParamFunction, by fixing some of the variables and define them as
133  parameters.
134  i.e. transform any multi-dim function in a parametric function
135 
136  @ingroup ParamFunc
137 
138 */
139 template< typename FuncPtr = FreeMultiFunctionPtr >
141 
142 public:
143 
144  /**
145  Constructor a wrapped function from a pointer to a generic callable object implemention operator()(const double *), the new function dimension, the number of parameters (number of fixed variables) and an array specifying the index of the fixed variables which becames
146  parameters in the new API
147  */
148 
149  WrappedParamFunctionGen (const FuncPtr & func, unsigned int dim, unsigned int npar, const double * par, const unsigned int * idx) :
150  fFunc(func),
151  fDim(dim),
152  fParams(std::vector<double>(par,par+npar) ),
153  fParIndices(std::vector<unsigned int>(idx, idx + npar) ),
154  fX(std::vector<double>(npar+dim) ) // cached vector
155  {
156  DoInit();
157  }
158 
159  /**
160  Constructor as before but taking now a non - const pointer to a callable object.
161  This constructor is needed in the case FuncPtr is a std::unique_ptr which has a copy ctor taking non const objects
162  */
163  WrappedParamFunctionGen (FuncPtr & func, unsigned int dim, unsigned int npar, const double * par, const unsigned int * idx) :
164  fFunc(func),
165  fDim(dim),
166  fParams(std::vector<double>(par,par+npar) ),
167  fParIndices(std::vector<unsigned int>(idx, idx + npar) ),
168  fX(std::vector<double>(npar+dim) ) // cached vector
169  {
170  DoInit();
171  }
172 
173  /// clone the function
175  return new WrappedParamFunctionGen(fFunc, fDim, fParams.size(), fParams.empty() ? nullptr : &fParams.front(), fParIndices.empty() ? nullptr : &fParIndices.front());
176  }
177 
178 private:
179  // copy ctor
180  WrappedParamFunctionGen(const WrappedParamFunctionGen &); // not implemented
181  WrappedParamFunctionGen & operator=(const WrappedParamFunctionGen &); // not implemented
182 
183 public:
184 
185  const double * Parameters() const {
186  return fParams.empty() ? nullptr : &fParams.front();
187  }
188 
189  void SetParameters(const double * p) {
190  unsigned int npar = NPar();
191  std::copy(p, p+ npar, fParams.begin() );
192  SetParValues(npar, p);
193  }
194 
195  unsigned int NPar() const { return fParams.size(); }
196 
197  unsigned int NDim() const { return fDim; }
198 
199 // // re-implement this since is more efficient
200 // double operator() (const double * x, const double * p) {
201 // unsigned int n = fX.size();
202 // unsigned int npar = fParams.size();
203 // unsigned j = 0;
204 // return (*fFunc)( fX);
205 // }
206 
207 private:
208 
209  /// evaluate the function (re-implement for being more efficient)
210  double DoEval(const double * x) const {
211 
212 // std::cout << this << fDim << " x : ";
213 // std::ostream_iterator<double> oix(std::cout," , ");
214 // std::copy(x, x+fDim, oix);
215 // std::cout << std::endl;
216 // std::cout << "npar " << npar << std::endl;
217 // std::cout << fVarIndices.size() << std::endl;
218 // assert ( fVarIndices.size() == fDim); // otherwise something is wrong
219 
220  for (unsigned int i = 0; i < fDim; ++i) {
221  unsigned int j = fVarIndices[i];
222  assert ( j < NPar() + fDim);
223  fX[ j ] = x[i];
224  }
225 // std::cout << "X : (";
226 // std::ostream_iterator<double> oi(std::cout," , ");
227 // std::copy(fX.begin(), fX.end(), oi);
228 // std::cout << std::endl;
229 
230  return (*fFunc)( fX.empty() ? nullptr : &fX.front() );
231  }
232 
233 
234  /**
235  implement the required IParamFunction interface
236  */
237  double DoEvalPar(const double * x, const double * p ) const {
238  SetParValues(NPar(), p);
239  return DoEval(x);
240  }
241 
242 
243  void DoInit() {
244  // calculate variable indices and set in X the parameter values
245  fVarIndices.reserve(fDim);
246  unsigned int npar = NPar();
247  for (unsigned int i = 0; i < npar + fDim; ++i) {
248  bool isVar = true;
249  for (unsigned int j = 0; j < npar; ++j) {
250  if (fParIndices[j] == i) {
251  isVar = false;
252  break;
253  }
254  }
255  if (isVar) fVarIndices.push_back(i);
256  }
257  assert ( fVarIndices.size() == fDim); // otherwise something is wrong
258 
259 // std::cout << "n variables " << fVarIndices.size() << std::endl;
260 // std::ostream_iterator<int> oi(std::cout," ");
261 // std::copy(fVarIndices.begin(), fVarIndices.end(), oi);
262 // std::cout << std::endl;
263 // assert( fVarIndices.size() == fDim);
264 // std::cout << this << std::endl;
265 
266  // set parameter values in fX
267  SetParValues(npar, fParams.empty() ? nullptr : &fParams.front());
268  for (unsigned int i = 0; i < npar; ++i) {
269  unsigned int j = fParIndices[i];
270  assert ( j < npar + fDim);
271  fX[j] = fParams[i];
272  }
273 
274  }
275 
276  // set the parameter values in the cached fX vector
277  // makme const because it might be called from const methods
278  void SetParValues(unsigned int npar, const double * p) const {
279  for (unsigned int i = 0; i < npar; ++i) {
280  unsigned int j = fParIndices[i];
281  assert ( j < npar + fDim);
282  fX[j] = p[i];
283  }
284  }
285 
286 
287  mutable FuncPtr fFunc;
288  unsigned int fDim;
289  std::vector<double> fParams;
290  std::vector<unsigned int> fVarIndices;
291  std::vector<unsigned int> fParIndices;
292  mutable std::vector<double> fX;
293 
294 
295 
296 };
297 
298 
299  } // end namespace Math
300 
301 } // end namespace ROOT
302 
303 
304 #endif /* ROOT_Math_WrappedParamFunction */
void SetParValues(unsigned int npar, const double *p) const
double DoEvalPar(const double *x, const double *p) const
implement the required IParamFunction interface
Namespace for new ROOT classes and functions.
Definition: StringConv.hxx:21
WrappedParamFunction(FuncPtr func, unsigned int dim, Iterator begin, Iterator end)
Constructor a wrapped function from a non-const pointer to a callable object, the function dimensio...
unsigned int NDim() const
Retrieve the dimension of the function.
double DoEval(const double *x) const
evaluate the function (re-implement for being more efficient)
STL namespace.
WrappedParamFunction(FuncPtr func, unsigned int dim=1, unsigned int npar=0, double *par=0)
Constructor a wrapped function from a pointer to a callable object, the function dimension and number...
const double * Parameters() const
Access the parameter values.
WrappedParamGenFunction class to wrap any multi-dimensional function implementing the operator()(cons...
Double_t x[n]
Definition: legend1.C:17
std::vector< unsigned int > fVarIndices
WrappedParamFunctionGen(FuncPtr &func, unsigned int dim, unsigned int npar, const double *par, const unsigned int *idx)
Constructor as before but taking now a non - const pointer to a callable object.
const double * Parameters() const
Access the parameter values.
void SetParameters(const double *p)
Set the parameter values.
WrappedParamFunctionGen & operator=(const WrappedParamFunctionGen &)
Documentation for the abstract class IBaseFunctionMultiDim.
Definition: IFunction.h:62
WrappedParamFunctionGen(const FuncPtr &func, unsigned int dim, unsigned int npar, const double *par, const unsigned int *idx)
Constructor a wrapped function from a pointer to a generic callable object implemention operator()(co...
double(* FreeParamMultiFunctionPtr)(const double *, const double *)
std::vector< unsigned int > fParIndices
Namespace for new Math classes and functions.
IMultiGenFunction * Clone() const
Constructor a wrapped function from a non - const pointer to a callable object, the function dimens...
double DoEvalPar(const double *x, const double *p) const
evaluate the function given values and parameters (requested interface)
unsigned int NPar() const
Return the number of Parameters.
IMultiGenFunction * Clone() const
clone the function
void SetParameters(const double *p)
Set the parameter values.
unsigned int NPar() const
Return the number of Parameters.
unsigned int NDim() const
Retrieve the dimension of the function.
double(* FreeMultiFunctionPtr)(const double *)
WrappedParamFunction class to wrap any multi-dimensional function pbject implementing the operator()(...