Rosenbrock function

Rosenbrock function

Rosenbrock function

Rosenbrock function

Rosenbrock function

Rosenbrock function

Rosenbrock function

Rosenbrock function

Rosenbrock function

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;
}

运行结果:

Rosenbrock function

可以可看到迭代了14次后,最终求出来的(x,y)已经非常接近(1,1)了。
 

转:https://blog.****.net/weixin_42320100/article/details/89286295