00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #ifndef ROOT_Math_GSLMultiMinimizer
00028 #define ROOT_Math_GSLMultiMinimizer
00029
00030 #include "gsl/gsl_vector.h"
00031 #include "gsl/gsl_multimin.h"
00032 #include "GSLMultiMinFunctionWrapper.h"
00033
00034 #include "Math/Error.h"
00035
00036 #include "Math/IFunction.h"
00037
00038 #include <cassert>
00039
00040 namespace ROOT {
00041
00042 namespace Math {
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052 class GSLMultiMinimizer {
00053
00054 public:
00055
00056
00057
00058
00059 GSLMultiMinimizer (ROOT::Math::EGSLMinimizerType type) :
00060 fMinimizer(0),
00061 fType(0),
00062 fVec(0)
00063 {
00064 switch(type)
00065 {
00066 case ROOT::Math::kConjugateFR :
00067 fType = gsl_multimin_fdfminimizer_conjugate_fr;
00068 break;
00069 case ROOT::Math::kConjugatePR :
00070 fType = gsl_multimin_fdfminimizer_conjugate_pr;
00071 break;
00072 case ROOT::Math::kVectorBFGS :
00073 fType = gsl_multimin_fdfminimizer_vector_bfgs;
00074 break;
00075 case ROOT::Math::kVectorBFGS2 :
00076 #if defined (GSL_VERSION_NUM) && GSL_VERSION_NUM >= 1009
00077
00078 fType = gsl_multimin_fdfminimizer_vector_bfgs2;
00079 #else
00080 MATH_INFO_MSG("GSLMultiMinimizer","minimizer BFSG2 does not exist with this GSL version , use BFGS");
00081 fType = gsl_multimin_fdfminimizer_vector_bfgs;
00082 #endif
00083 break;
00084 case ROOT::Math::kSteepestDescent:
00085 fType = gsl_multimin_fdfminimizer_steepest_descent;
00086 break;
00087 default:
00088 fType = gsl_multimin_fdfminimizer_conjugate_fr;
00089 break;
00090 }
00091
00092 }
00093
00094
00095
00096
00097 ~GSLMultiMinimizer () {
00098 if (fMinimizer != 0 ) gsl_multimin_fdfminimizer_free(fMinimizer);
00099
00100 if (fVec != 0) gsl_vector_free(fVec);
00101 }
00102
00103 private:
00104
00105
00106
00107
00108
00109 GSLMultiMinimizer(const GSLMultiMinimizer &) {}
00110
00111
00112
00113
00114 GSLMultiMinimizer & operator = (const GSLMultiMinimizer & rhs) {
00115 if (this == &rhs) return *this;
00116 return *this;
00117 }
00118
00119 public:
00120
00121
00122
00123
00124
00125 int Set(const ROOT::Math::IMultiGradFunction & func, const double * x, double stepSize, double tol) {
00126
00127 fFunc.SetFunction(func);
00128
00129 unsigned int ndim = func.NDim();
00130 CreateMinimizer( ndim );
00131
00132 if (fVec != 0) gsl_vector_free(fVec);
00133 fVec = gsl_vector_alloc( ndim );
00134 std::copy(x,x+ndim, fVec->data);
00135 assert(fMinimizer != 0);
00136 return gsl_multimin_fdfminimizer_set(fMinimizer, fFunc.GetFunc(), fVec, stepSize, tol);
00137 }
00138
00139
00140 void CreateMinimizer(unsigned int n) {
00141 if (fMinimizer) gsl_multimin_fdfminimizer_free(fMinimizer);
00142 fMinimizer = gsl_multimin_fdfminimizer_alloc(fType, n);
00143 }
00144
00145 std::string Name() const {
00146 if (fMinimizer == 0) return "undefined";
00147 return std::string(gsl_multimin_fdfminimizer_name(fMinimizer) );
00148 }
00149
00150 int Iterate() {
00151 if (fMinimizer == 0) return -1;
00152 return gsl_multimin_fdfminimizer_iterate(fMinimizer);
00153 }
00154
00155
00156 double * X() const {
00157 if (fMinimizer == 0) return 0;
00158 gsl_vector * x = gsl_multimin_fdfminimizer_x(fMinimizer);
00159 return x->data;
00160 }
00161
00162
00163 double Minimum() const {
00164 if (fMinimizer == 0) return 0;
00165 return gsl_multimin_fdfminimizer_minimum(fMinimizer);
00166 }
00167
00168
00169 double * Gradient() const {
00170 if (fMinimizer == 0) return 0;
00171 gsl_vector * g = gsl_multimin_fdfminimizer_gradient(fMinimizer);
00172 return g->data;
00173 }
00174
00175
00176 int Restart() {
00177 if (fMinimizer == 0) return -1;
00178 return gsl_multimin_fdfminimizer_restart(fMinimizer);
00179 }
00180
00181
00182 int TestGradient(double absTol) const {
00183 if (fMinimizer == 0) return -1;
00184 gsl_vector * g = gsl_multimin_fdfminimizer_gradient(fMinimizer);
00185 return gsl_multimin_test_gradient( g, absTol);
00186 }
00187
00188
00189 int TestGradient(const double * g, double absTol) const {
00190 if (fVec == 0 ) return -1;
00191 unsigned int n = fVec->size;
00192 if (n == 0 ) return -1;
00193 std::copy(g,g+n, fVec->data);
00194 return gsl_multimin_test_gradient( fVec, absTol);
00195 }
00196
00197
00198 private:
00199
00200 gsl_multimin_fdfminimizer * fMinimizer;
00201 GSLMultiMinDerivFunctionWrapper fFunc;
00202 const gsl_multimin_fdfminimizer_type * fType;
00203
00204 mutable gsl_vector * fVec;
00205
00206 };
00207
00208 }
00209
00210 }
00211
00212
00213 #endif