Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 10:10:20

0001 // @(#)root/mathmore:$Id$
0002 // Author: L. Moneta Wed Dec 20 14:36:31 2006
0003 
0004 /**********************************************************************
0005  *                                                                    *
0006  * Copyright (c) 2006  LCG ROOT Math Team, CERN/PH-SFT                *
0007  *                                                                    *
0008  * This library is free software; you can redistribute it and/or      *
0009  * modify it under the terms of the GNU General Public License        *
0010  * as published by the Free Software Foundation; either version 2     *
0011  * of the License, or (at your option) any later version.             *
0012  *                                                                    *
0013  * This library is distributed in the hope that it will be useful,    *
0014  * but WITHOUT ANY WARRANTY; without even the implied warranty of     *
0015  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU   *
0016  * General Public License for more details.                           *
0017  *                                                                    *
0018  * You should have received a copy of the GNU General Public License  *
0019  * along with this library (see file COPYING); if not, write          *
0020  * to the Free Software Foundation, Inc., 59 Temple Place, Suite      *
0021  * 330, Boston, MA 02111-1307 USA, or contact the author.             *
0022  *                                                                    *
0023  **********************************************************************/
0024 
0025 // Header file for class MultiNumGradFunction
0026 
0027 #ifndef ROOT_Math_MultiNumGradFunction
0028 #define ROOT_Math_MultiNumGradFunction
0029 
0030 
0031 #include "Math/IFunction.h"
0032 
0033 #include "Math/WrappedFunction.h"
0034 
0035 
0036 namespace ROOT {
0037 
0038    namespace Math {
0039 
0040 
0041 /**
0042    MultiNumGradFunction class to wrap a normal function in  a
0043    gradient function using numerical gradient calculation
0044    provided by the class Derivator (based on GSL numerical derivation)
0045 
0046 
0047    @ingroup MultiMin
0048 */
0049 class MultiNumGradFunction : public IMultiGradFunction {
0050 
0051 public:
0052 
0053 
0054    /**
0055      Constructor from a IMultiGenFunction interface
0056    */
0057    MultiNumGradFunction (const IMultiGenFunction & f) :
0058       fFunc(&f),
0059       fDim(f.NDim() ),
0060       fNCalls(0),
0061       fOwner(false)
0062    {}
0063 
0064    /**
0065      Constructor from a generic function (pointer or reference) and number of dimension
0066      implementing operator () (double * x)
0067    */
0068 
0069    template<class FuncType>
0070    MultiNumGradFunction (FuncType f, int n) :
0071       fDim( n ),
0072       fNCalls(0),
0073       fOwner(true)
0074    {
0075       // create a wrapped function
0076       fFunc = new ROOT::Math::WrappedMultiFunction<FuncType> (f, n);
0077    }
0078 
0079    /**
0080       Destructor (no operations)
0081    */
0082    ~MultiNumGradFunction () override  {
0083       if (fOwner) delete fFunc;
0084    }
0085 
0086 
0087    // method inheritaed from IFunction interface
0088 
0089    unsigned int NDim() const override { return fDim; }
0090 
0091    unsigned int NCalls() const { return fNCalls; }
0092 
0093    IMultiGenFunction * Clone() const override {
0094       if (!fOwner)
0095          return new MultiNumGradFunction(*fFunc);
0096       else {
0097          // we need to copy the pointer to the wrapped function
0098          MultiNumGradFunction * f =  new MultiNumGradFunction(*(fFunc->Clone()) );
0099          f->fOwner = true;
0100          return f;
0101       }
0102    }
0103 
0104    // set ownership
0105    void SetOwnership(bool on = true) { fOwner = on;  }
0106 
0107    /// precision value used for calculating the derivative step-size
0108    /// h = eps * |x|. The default is 0.001, give a smaller in case function chanes rapidly
0109    static void SetDerivPrecision(double eps);
0110 
0111    /// get precision value used for calculating the derivative step-size
0112    static double GetDerivPrecision();
0113 
0114 
0115 private:
0116 
0117 
0118    double DoEval(const double * x) const override {
0119       fNCalls++;
0120       return (*fFunc)(x);
0121    }
0122 
0123    // calculate derivative using mathcore derivator
0124    double DoDerivative (const double * x, unsigned int icoord  ) const override;
0125 
0126    // adapat internal function type to IMultiGenFunction needed by derivative calculation
0127    const IMultiGenFunction * fFunc;
0128    unsigned int fDim;
0129    mutable unsigned int fNCalls;
0130    bool fOwner;
0131 
0132    static double fgEps;          // epsilon used in derivative calculation h ~ eps |x|
0133 
0134 };
0135 
0136    } // end namespace Math
0137 
0138 } // end namespace ROOT
0139 
0140 
0141 #endif /* ROOT_Math_NumGradFunction */