00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00025
00026 #include <qvmath/qvnumericalanalysis.h>
00027
00028 const QVVector qvEstimateGradient(const QVFunction<QVVector, double> &multivariateFunction, const QVVector &location, const double h)
00029 {
00030 const int dim = location.size();
00031 QVVector gradient(dim);
00032 const double actual = multivariateFunction(location);
00033 for (int i = 0; i < dim; i++)
00034 {
00035 QVVector stepLocation = location;
00036 stepLocation[i] += h;
00037 gradient[i] = (multivariateFunction(stepLocation) - actual)/h;
00038 }
00039 return gradient;
00040 }
00041
00042 const QVMatrix qvEstimateHessian( const QVFunction<QVVector, double> &multivariateFunction,
00043 const QVVector &location, const double h)
00044 {
00045 const int dim = location.size();
00046 const QVVector g = qvEstimateGradient(multivariateFunction, location, h);
00047
00048 QVMatrix hessian(dim, dim);
00049
00050 const double actual = multivariateFunction(location);
00051 for (int i = 0; i < dim; i++)
00052 for (int j = 0; j < dim; j++)
00053 {
00054 QVVector stepLocationIJ = location;
00055 stepLocationIJ[i] += h;
00056 stepLocationIJ[j] += h;
00057 hessian(i,j) = (multivariateFunction(stepLocationIJ) - actual)/(h*h) - (g[i] + g[j])/h;
00058 }
00059 return hessian;
00060 }
00061
00063
00064 #include <gsl/gsl_multimin.h>
00065
00066 double my_f (const gsl_vector *v, void *params)
00067 {
00068 return ((QVFunction<QVVector, double> *) params)->operator()(QVVector(v));
00069 }
00070
00071
00072 void my_df (const gsl_vector *v, void *params, gsl_vector *df)
00073 {
00074 gsl_vector_memcpy(df, qvEstimateGradient( * (QVFunction<QVVector, double> *) params,QVVector(v)));
00075 }
00076
00077
00078 void my_fdf (const gsl_vector *x, void *params, double *f, gsl_vector *df)
00079 {
00080 *f = my_f(x, params);
00081 my_df(x, params, df);
00082 }
00083
00084 const bool qvGSLMinimizeFDF ( QVFunction<QVVector, double> & function, QVVector &point,
00085 const GSLMultiminFDFMinimizerType gslMinimizerAlgorithm,
00086 const int maxIterations, const double maxGradientNorm,
00087 const double step, const double tol)
00088 {
00089 const int dims = point.size();
00090 const gsl_multimin_fdfminimizer_type *minimizer_type = NULL;
00091 switch(gslMinimizerAlgorithm)
00092 {
00093 case ConjugateFR: minimizer_type = gsl_multimin_fdfminimizer_conjugate_fr; break;
00094 case ConjugatePR: minimizer_type = gsl_multimin_fdfminimizer_conjugate_pr; break;
00095 case VectorBFGS: minimizer_type = gsl_multimin_fdfminimizer_vector_bfgs; break;
00096 case SteepestDescent: minimizer_type = gsl_multimin_fdfminimizer_steepest_descent; break;
00097 }
00098
00099 gsl_multimin_fdfminimizer *minimizer = gsl_multimin_fdfminimizer_alloc (minimizer_type, dims);
00100
00101 gsl_multimin_function_fdf my_func;
00102 my_func.n = dims;
00103 my_func.f = &my_f;
00104 my_func.df = &my_df;
00105 my_func.fdf = &my_fdf;
00106 my_func.params = &function;
00107
00108 gsl_vector *x = point;
00109
00110 gsl_multimin_fdfminimizer_set (minimizer, &my_func, x, step, tol);
00111
00112 int status = GSL_CONTINUE;
00113 for (int i = 0; status == GSL_CONTINUE && i < maxIterations; i++)
00114 {
00115 if ((status = gsl_multimin_fdfminimizer_iterate (minimizer)))
00116 break;
00117
00118 status = gsl_multimin_test_gradient (gsl_multimin_fdfminimizer_gradient(minimizer), maxGradientNorm);
00119 }
00120
00121
00122 point = QVVector(gsl_multimin_fdfminimizer_x(minimizer));
00123
00124 gsl_multimin_fdfminimizer_free (minimizer);
00125
00126 gsl_vector_free (x);
00127
00128 return (status == GSL_SUCCESS);
00129 }
00130
00132 #include <QPair>
00133 double my_f_gradient (const gsl_vector *v, void *params)
00134 {
00135 return ((QPair< QVFunction<QVVector, double> *, QVFunction<QVVector, QVVector> *> *) params)->first->operator()(QVVector(v));
00136 }
00137
00138
00139 void my_df_gradient (const gsl_vector *v, void *params, gsl_vector *df)
00140 {
00141 gsl_vector_memcpy(df, ((QPair< QVFunction<QVVector, double> *, QVFunction<QVVector, QVVector> *> *) params)->second->operator()(QVVector(v)));
00142 }
00143
00144
00145 void my_fdf_gradient (const gsl_vector *x, void *params, double *f, gsl_vector *df)
00146 {
00147 *f = my_f_gradient(x, params);
00148 my_df_gradient(x, params, df);
00149 }
00150
00151 const bool qvGSLMinimizeFDF ( QVFunction<QVVector, double> & function, QVFunction<QVVector, QVVector> & gradientFunction,
00152 QVVector &point, const GSLMultiminFDFMinimizerType gslMinimizerAlgorithm,
00153 const int maxIterations, const double maxGradientNorm,
00154 const double step, const double tol)
00155 {
00156 const int dims = point.size();
00157 const gsl_multimin_fdfminimizer_type *minimizer_type = NULL;
00158 switch(gslMinimizerAlgorithm)
00159 {
00160 case ConjugateFR: minimizer_type = gsl_multimin_fdfminimizer_conjugate_fr; break;
00161 case ConjugatePR: minimizer_type = gsl_multimin_fdfminimizer_conjugate_pr; break;
00162 case VectorBFGS: minimizer_type = gsl_multimin_fdfminimizer_vector_bfgs; break;
00163 case SteepestDescent: minimizer_type = gsl_multimin_fdfminimizer_steepest_descent; break;
00164 }
00165
00166 gsl_multimin_fdfminimizer *minimizer = gsl_multimin_fdfminimizer_alloc (minimizer_type, dims);
00167 QPair< QVFunction<QVVector, double> *, QVFunction<QVVector, QVVector> *> functions(&function, &gradientFunction);
00168
00169 gsl_multimin_function_fdf my_func;
00170 my_func.n = dims;
00171 my_func.f = &my_f_gradient;
00172 my_func.df = &my_df_gradient;
00173 my_func.fdf = &my_fdf_gradient;
00174 my_func.params = &functions;
00175
00176 gsl_vector *x = point;
00177
00178 gsl_multimin_fdfminimizer_set (minimizer, &my_func, x, step, tol);
00179
00180 int status = GSL_CONTINUE;
00181 for (int i = 0; status == GSL_CONTINUE && i < maxIterations; i++)
00182 {
00183 if ((status = gsl_multimin_fdfminimizer_iterate (minimizer)))
00184 break;
00185
00186 status = gsl_multimin_test_gradient (gsl_multimin_fdfminimizer_gradient(minimizer), maxGradientNorm);
00187 }
00188
00189
00190 point = QVVector(gsl_multimin_fdfminimizer_x(minimizer));
00191
00192 gsl_multimin_fdfminimizer_free (minimizer);
00193
00194 gsl_vector_free (x);
00195
00196 return (status == GSL_SUCCESS);
00197 }
00198
00200
00201 #include <gsl/gsl_errno.h>
00202 #include <gsl/gsl_math.h>
00203 #include <gsl/gsl_min.h>
00204
00205 double fn2 (double x, void * params)
00206 {
00207 return ((QVFunction<double, double> *) params)->operator()(x);
00208 }
00209
00210 const bool qvGSLMinimize(QVFunction<double, double> &function,
00211 double &x, double &lower, double &upper,
00212 const GSLMinFMinimizer gslMinimizerAlgorithm,
00213 const int maxIterations,
00214 const double absoluteError,
00215 const double relativeError)
00216 {
00217 const gsl_min_fminimizer_type *minimizer_type =
00218 (gslMinimizerAlgorithm == GoldenSection)? gsl_min_fminimizer_goldensection : gsl_min_fminimizer_brent;
00219
00220 gsl_function F;
00221 F.function = &fn2;
00222 F.params = &function;
00223
00224 gsl_min_fminimizer *s = gsl_min_fminimizer_alloc (minimizer_type);
00225 gsl_min_fminimizer_set (s, &F, x, lower, upper);
00226
00227 for (int i = 0; i <maxIterations; i++)
00228 {
00229 gsl_min_fminimizer_iterate(s);
00230 x = gsl_min_fminimizer_x_minimum (s);
00231 lower = gsl_min_fminimizer_x_lower (s);
00232 upper = gsl_min_fminimizer_x_upper (s);
00233 if (gsl_min_test_interval(lower, upper, absoluteError, relativeError) != GSL_CONTINUE)
00234 break;
00235 }
00236
00237 gsl_min_fminimizer_free (s);
00238
00239 return gsl_min_test_interval(lower, upper, absoluteError, relativeError) == GSL_SUCCESS;
00240 }