WrappedParamFunction.h

Go to the documentation of this file.
00001 // @(#)root/mathcore:$Id: WrappedParamFunction.h 36185 2010-10-08 10:12:18Z rdm $
00002 // Author: L. Moneta Thu Nov 23 10:38:32 2006
00003 
00004 /**********************************************************************
00005  *                                                                    *
00006  * Copyright (c) 2006  LCG ROOT Math Team, CERN/PH-SFT                *
00007  *                                                                    *
00008  *                                                                    *
00009  **********************************************************************/
00010 
00011 // Header file for class WrappedParamFunction
00012 
00013 #ifndef ROOT_Math_WrappedParamFunction
00014 #define ROOT_Math_WrappedParamFunction
00015 
00016 #ifndef ROOT_Math_IParamFunction
00017 #include "Math/IParamFunction.h"
00018 #endif
00019 
00020 //#include <iostream>
00021 //#include <iterator>
00022 
00023 #include <vector>
00024 
00025 
00026 namespace ROOT {
00027 
00028    namespace Math {
00029 
00030 
00031 typedef double( * FreeParamMultiFunctionPtr ) (const double *, const double * );
00032 
00033 /**
00034    WrappedParamFunction class to wrap any multi-dimensional function pbject
00035    implementing the operator()(const double * x, const double * p)
00036    in an interface-like IParamFunction with a vector storing and caching internally the
00037    parameter values
00038 
00039    @ingroup  ParamFunc
00040 
00041 */
00042 template< typename FuncPtr =  FreeParamMultiFunctionPtr   >
00043 class WrappedParamFunction : public IParamMultiFunction {
00044 
00045 public:
00046 
00047    /**
00048       Constructor a wrapped function from a pointer to a callable object, the function dimension and number of parameters
00049       which are set to zero by default
00050    */
00051    WrappedParamFunction (FuncPtr  func, unsigned int dim = 1, unsigned int npar = 0, double * par = 0) :
00052       fFunc(func),
00053       fDim(dim),
00054       fParams(std::vector<double>(npar) )
00055    {
00056       if (par != 0) std::copy(par,par+npar,fParams.begin() );
00057    }
00058 
00059 //    /**
00060 //       Constructor a wrapped function from a non-const pointer to a callable object, the function dimension and number of parameters
00061 //       which are set to zero by default
00062 //       This constructor is needed in the case FuncPtr is a std::auto_ptr which has a copy ctor taking non const objects
00063 //    */
00064 //    WrappedParamFunction (FuncPtr & func, unsigned int dim = 1, unsigned int npar = 0, double * par = 0) :
00065 //       fFunc(func),
00066 //       fDim(dim),
00067 //       fParams(std::vector<double>(npar) )
00068 //    {
00069 //       if (par != 0) std::copy(par,par+npar,fParams.begin() );
00070 //    }
00071 
00072    /**
00073       Constructor a wrapped function from a pointer to a callable object, the function dimension and an iterator specifying begin and end
00074       of parameters
00075    */
00076    template<class Iterator>
00077    WrappedParamFunction (FuncPtr func, unsigned int dim, Iterator begin, Iterator end) :
00078       fFunc(func),
00079       fDim(dim),
00080       fParams(std::vector<double>(begin,end) )
00081    {}
00082 
00083 //    /**
00084 //       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.
00085 //       This constructor is needed in the case FuncPtr is a std::auto_ptr which has a copy ctor taking non const objects
00086 //    */
00087 //    template<class Iterator>
00088 //    WrappedParamFunction (FuncPtr func, unsigned int dim, Iterator begin, Iterator end) :
00089 //       fFunc(func),
00090 //       fDim(dim),
00091 //       fParams(std::vector<double>(begin,end) )
00092 //    {}
00093 
00094    /// clone the function
00095    IMultiGenFunction * Clone() const {
00096       return new WrappedParamFunction(fFunc, fDim, fParams.begin(), fParams.end());
00097    }
00098 
00099    const double * Parameters() const {
00100       return  &(fParams.front());
00101    }
00102 
00103    void SetParameters(const double * p)  {
00104       std::copy(p, p+NPar(), fParams.begin() );
00105    }
00106 
00107    unsigned int NPar() const { return fParams.size(); }
00108 
00109    unsigned int NDim() const { return fDim; }
00110 
00111 
00112 private:
00113 
00114    /// evaluate the function given values and parameters (requested interface)
00115    double DoEvalPar(const double * x, const double * p) const {
00116       return (*fFunc)( x, p );
00117    }
00118 
00119 
00120    FuncPtr fFunc;
00121    unsigned int fDim;
00122    std::vector<double> fParams;
00123 
00124 
00125 
00126 };
00127 
00128 
00129 typedef double( * FreeMultiFunctionPtr ) (const double *);
00130 
00131 /**
00132    WrappedParamGenFunction class to wrap any multi-dimensional function
00133    implementing the operator()(const double * )
00134    in an interface-like IParamFunction, by fixing some of the variables and define them as
00135    parameters.
00136    i.e. transform any multi-dim function in a parametric function
00137 
00138    @ingroup  ParamFunc
00139 
00140 */
00141 template< typename FuncPtr =  FreeMultiFunctionPtr   >
00142 class WrappedParamFunctionGen : public IParamMultiFunction {
00143 
00144 public:
00145 
00146    /**
00147       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
00148       parameters in the new API
00149    */
00150 
00151    WrappedParamFunctionGen (const FuncPtr & func, unsigned int dim, unsigned int npar, const double * par, const unsigned int * idx) :
00152       fFunc(func),
00153       fDim(dim),
00154       fParams(std::vector<double>(par,par+npar) ),
00155       fParIndices(std::vector<unsigned int>(idx, idx + npar) ),
00156       fX(std::vector<double>(npar+dim) )  // cached vector
00157    {
00158       DoInit();
00159    }
00160 
00161    /**
00162       Constructor as before but taking now a non - const pointer to a callable object.
00163       This constructor is needed in the case FuncPtr is a std::auto_ptr which has a copy ctor taking non const objects
00164    */
00165    WrappedParamFunctionGen (FuncPtr & func, unsigned int dim, unsigned int npar, const double * par, const unsigned int * idx) :
00166       fFunc(func),
00167       fDim(dim),
00168       fParams(std::vector<double>(par,par+npar) ),
00169       fParIndices(std::vector<unsigned int>(idx, idx + npar) ),
00170       fX(std::vector<double>(npar+dim) ) // cached vector
00171    {
00172       DoInit();
00173    }
00174 
00175    /// clone the function
00176    IMultiGenFunction * Clone() const {
00177       return new WrappedParamFunctionGen(fFunc, fDim, fParams.size() , &fParams.front(), &fParIndices.front());
00178    }
00179 
00180 private:
00181    // copy ctor
00182    WrappedParamFunctionGen(const  WrappedParamFunctionGen &);   // not implemented
00183    WrappedParamFunctionGen & operator=(const  WrappedParamFunctionGen &); // not implemented
00184 
00185 public:
00186 
00187    const double * Parameters() const {
00188       return  &(fParams.front());
00189    }
00190 
00191    void SetParameters(const double * p)  {
00192       unsigned int npar = NPar();
00193       std::copy(p, p+ npar, fParams.begin() );
00194       SetParValues(npar, p);
00195    }
00196 
00197    unsigned int NPar() const { return fParams.size(); }
00198 
00199    unsigned int NDim() const { return fDim; }
00200 
00201 //    // re-implement this since is more efficient
00202 //    double operator() (const double * x, const double * p) {
00203 //       unsigned int n = fX.size();
00204 //       unsigned int npar = fParams.size();
00205 //       unsigned j = 0;
00206 //       return (*fFunc)( fX);
00207 //    }
00208 
00209 private:
00210 
00211    /// evaluate the function (re-implement for being more efficient)
00212    double DoEval(const double * x) const {
00213 
00214       unsigned int npar = NPar();
00215 
00216 //       std::cout << this << fDim << " x : ";
00217 //       std::ostream_iterator<double> oix(std::cout," ,  ");
00218 //       std::copy(x, x+fDim, oix);
00219 //       std::cout << std::endl;
00220 //       std::cout << "npar " << npar << std::endl;
00221 //       std::cout <<  fVarIndices.size() << std::endl;
00222 //       assert ( fVarIndices.size() == fDim);  // otherwise something is wrong
00223 
00224       for (unsigned int i = 0; i < fDim; ++i) {
00225          unsigned int j = fVarIndices[i];
00226          assert ( j  < npar + fDim);
00227          fX[ j ] = x[i];
00228       }
00229 //       std::cout << "X : (";
00230 //       std::ostream_iterator<double> oi(std::cout," ,  ");
00231 //       std::copy(fX.begin(), fX.end(), oi);
00232 //       std::cout << std::endl;
00233 
00234       return (*fFunc)( &fX.front() );
00235    }
00236 
00237 
00238    /**
00239        implement the required IParamFunction interface
00240    */
00241    double DoEvalPar(const double * x, const double * p ) const {
00242       SetParValues(NPar(), p);
00243       return DoEval(x);
00244    }
00245 
00246 
00247    void DoInit() {
00248       // calculate variable indices and set in X the parameter values
00249       fVarIndices.reserve(fDim);
00250       unsigned int npar = NPar();
00251       for (unsigned int i = 0; i < npar + fDim; ++i) {
00252          bool isVar = true;
00253          for (unsigned int j = 0; j < npar; ++j) {
00254             if (fParIndices[j] == i) {
00255                isVar = false;
00256                break;
00257             }
00258          }
00259          if (isVar) fVarIndices.push_back(i);
00260       }
00261       assert ( fVarIndices.size() == fDim);  // otherwise something is wrong
00262 
00263 //       std::cout << "n variables " << fVarIndices.size() << std::endl;
00264 //       std::ostream_iterator<int> oi(std::cout,"  ");
00265 //       std::copy(fVarIndices.begin(), fVarIndices.end(), oi);
00266 //       std::cout << std::endl;
00267 //       assert( fVarIndices.size() == fDim);
00268 //       std::cout << this << std::endl;
00269 
00270       // set parameter values in fX
00271       SetParValues(npar, &fParams.front() );
00272       for (unsigned int i = 0; i < npar; ++i) {
00273          unsigned int j = fParIndices[i];
00274          assert ( j  < npar + fDim);
00275          fX[j] = fParams[i];
00276       }
00277 
00278    }
00279 
00280    // set the parameter values in the cached fX vector
00281    // makme const because it might be called from const methods
00282    void SetParValues(unsigned int npar, const double * p) const {
00283       for (unsigned int i = 0; i < npar; ++i) {
00284          unsigned int j = fParIndices[i];
00285          assert ( j  < npar + fDim);
00286          fX[j] = p[i];
00287       }
00288    }
00289 
00290 
00291    mutable FuncPtr fFunc;
00292    unsigned int fDim;
00293    std::vector<double> fParams;
00294    std::vector<unsigned int> fVarIndices;
00295    std::vector<unsigned int> fParIndices;
00296    mutable std::vector<double> fX;
00297 
00298 
00299 
00300 };
00301 
00302 
00303    } // end namespace Math
00304 
00305 } // end namespace ROOT
00306 
00307 
00308 #endif /* ROOT_Math_WrappedParamFunction */

Generated on Tue Jul 5 14:25:39 2011 for ROOT_528-00b_version by  doxygen 1.5.1