00001 // @(#)root/mathmore:$Id: MultiNumGradFunction.h 37448 2010-12-09 20:20:56Z moneta $ 00002 // Author: L. Moneta Wed Dec 20 14:36:31 2006 00003 00004 /********************************************************************** 00005 * * 00006 * Copyright (c) 2006 LCG ROOT Math Team, CERN/PH-SFT * 00007 * * 00008 * This library is free software; you can redistribute it and/or * 00009 * modify it under the terms of the GNU General Public License * 00010 * as published by the Free Software Foundation; either version 2 * 00011 * of the License, or (at your option) any later version. * 00012 * * 00013 * This library is distributed in the hope that it will be useful, * 00014 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 00015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * 00016 * General Public License for more details. * 00017 * * 00018 * You should have received a copy of the GNU General Public License * 00019 * along with this library (see file COPYING); if not, write * 00020 * to the Free Software Foundation, Inc., 59 Temple Place, Suite * 00021 * 330, Boston, MA 02111-1307 USA, or contact the author. * 00022 * * 00023 **********************************************************************/ 00024 00025 // Header file for class MultiNumGradFunction 00026 00027 #ifndef ROOT_Math_MultiNumGradFunction 00028 #define ROOT_Math_MultiNumGradFunction 00029 00030 00031 #ifndef ROOT_Math_IFunction 00032 #include "Math/IFunction.h" 00033 #endif 00034 00035 #ifndef ROOT_Math_WrappedFunction 00036 #include "Math/WrappedFunction.h" 00037 #endif 00038 00039 00040 namespace ROOT { 00041 00042 namespace Math { 00043 00044 00045 /** 00046 MultiNumGradFunction class to wrap a normal function in a 00047 gradient function using numerical gradient calculation 00048 provided by the class Derivator (based on GSL numerical derivation) 00049 00050 00051 @ingroup MultiMin 00052 */ 00053 class MultiNumGradFunction : public IMultiGradFunction { 00054 00055 public: 00056 00057 00058 /** 00059 Constructor from a IMultiGenFunction interface 00060 */ 00061 MultiNumGradFunction (const IMultiGenFunction & f) : 00062 fFunc(&f), 00063 fDim(f.NDim() ), 00064 fNCalls(0), 00065 fOwner(false) 00066 {} 00067 00068 /** 00069 Constructor from a generic function (pointer or reference) and number of dimension 00070 implementiong operator () (double * x) 00071 */ 00072 00073 template<class FuncType> 00074 MultiNumGradFunction (FuncType f, int n) : 00075 fDim( n ), 00076 fNCalls(0), 00077 fOwner(true) 00078 { 00079 // create a wrapped function 00080 fFunc = new ROOT::Math::WrappedMultiFunction<FuncType> (f, n); 00081 } 00082 00083 /** 00084 Destructor (no operations) 00085 */ 00086 ~MultiNumGradFunction () { 00087 if (fOwner) delete fFunc; 00088 } 00089 00090 00091 // method inheritaed from IFunction interface 00092 00093 unsigned int NDim() const { return fDim; } 00094 00095 unsigned int NCalls() const { return fNCalls; } 00096 00097 IMultiGenFunction * Clone() const { 00098 if (!fOwner) 00099 return new MultiNumGradFunction(*fFunc); 00100 else { 00101 // we need to copy the pointer to the wrapped function 00102 MultiNumGradFunction * f = new MultiNumGradFunction(*(fFunc->Clone()) ); 00103 f->fOwner = true; 00104 return f; 00105 } 00106 } 00107 00108 00109 /// precision value used for calculating the derivative step-size 00110 /// h = eps * |x|. The default is 0.001, give a smaller in case function chanes rapidly 00111 static void SetDerivPrecision(double eps); 00112 00113 /// get precision value used for calculating the derivative step-size 00114 static double GetDerivPrecision(); 00115 00116 00117 private: 00118 00119 00120 double DoEval(const double * x) const { 00121 fNCalls++; 00122 return (*fFunc)(x); 00123 } 00124 00125 // calculate derivative using mathcore derivator 00126 double DoDerivative (const double * x, unsigned int icoord ) const; 00127 00128 // adapat internal function type to IMultiGenFunction needed by derivative calculation 00129 const IMultiGenFunction * fFunc; 00130 unsigned int fDim; 00131 mutable unsigned int fNCalls; 00132 bool fOwner; 00133 00134 static double fgEps; // epsilon used in derivative calculation h ~ eps |x| 00135 00136 }; 00137 00138 } // end namespace Math 00139 00140 } // end namespace ROOT 00141 00142 00143 #endif /* ROOT_Math_NumGradFunction */