Rosenbrock function
采用 Levmar 工具包分析用代码:
#include "stdafx.h"
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <float.h>
#include "levmar.h"
#define ROSD 105.0
/* Rosenbrock function, global minimum at (1, 1) */
void ros(double *p, double *x, int m, int n, void *data)
{
register int i;
for (i = 0; i<n; ++i)
x[i] = ((1.0 - p[0])*(1.0 - p[0]) + ROSD*(p[1] - p[0] * p[0])*(p[1] - p[0] * p[0]));
}
void jacros(double *p, double *jac, int m, int n, void *data)
{
register int i, j;
for (i = j = 0; i<n; ++i) {
jac[j++] = (-2 + 2 * p[0] - 4 * ROSD*(p[1] - p[0] * p[0])*p[0]);
jac[j++] = (2 * ROSD*(p[1] - p[0] * p[0]));
}
}
#define MODROSLAM 1E02
/* Modified Rosenbrock problem, global minimum at (1, 1) */
void modros(double *p, double *x, int m, int n, void *data)
{
register int i;
for (i = 0; i<n; i += 3) {
x[i] = 10 * (p[1] - p[0] * p[0]);
x[i + 1] = 1.0 - p[0];
x[i + 2] = MODROSLAM;
}
}
void jacmodros(double *p, double *jac, int m, int n, void *data)
{
register int i, j;
for (i = j = 0; i<n; i += 3) {
jac[j++] = -20.0*p[0];
jac[j++] = 10.0;
jac[j++] = -1.0;
jac[j++] = 0.0;
jac[j++] = 0.0;
jac[j++] = 0.0;
}
}
int main()
{
register int i, j;
int problem, ret;
double p[5], // 5 is max(2, 3, 5)
x[16]; // 16 is max(2, 3, 5, 6, 16)
int m, n;
double opts[LM_OPTS_SZ], info[LM_INFO_SZ];
opts[0] = LM_INIT_MU; opts[1] = 1E-15; opts[2] = 1E-15; opts[3] = 1E-20;
opts[4] = LM_DIFF_DELTA; // relevant only if the Jacobian is approximated using finite differences; specifies forward differencing
//opts[4]=-LM_DIFF_DELTA; // specifies central differencing to approximate Jacobian; more accurate but more expensive to compute!
/* modified Rosenbrock problem */
m = 2; n = 3;
p[0] = -1.2; p[1] = 1.0;
for (i = 0; i<n; i++) x[i] = 0.0;
ret = dlevmar_der(modros, jacmodros, p, x, m, n, 1000, opts, info, NULL, NULL, NULL); // with analytic Jacobian
//ret=dlevmar_dif(modros, p, x, m, n, 1000, opts, info, NULL, NULL, NULL); // no Jacobian
printf("Levenberg-Marquardt returned %d in %g iter, reason %g\nSolution: ", ret, info[5], info[6]);
for (i = 0; i<m; ++i)
printf("%.7g ", p[i]);
printf("\n\nMinimization info:\n");
for (i = 0; i<LM_INFO_SZ; ++i)
printf("%g ", info[i]);
printf("\n");
getchar();
return 0;
}
运行结果:
可以可看到迭代了14次后,最终求出来的(x,y)已经非常接近(1,1)了。
转:https://blog.****.net/weixin_42320100/article/details/89286295