⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lmder.c

📁 DTMK软件开发包,此为开源软件,是一款很好的医学图像开发资源.
💻 C
📖 第 1 页 / 共 2 页
字号:
/* minpack/lmder.f -- translated by f2c (version 20050501).
   You must link the resulting object file with libf2c:
        on Microsoft Windows system, link with libf2c.lib;
        on Linux or Unix systems, link with .../path/to/libf2c.a -lm
        or, if you install libf2c.a in a standard place, with -lf2c -lm
        -- in that order, at the end of the command line, as in
                cc *.o -lf2c -lm
        Source for libf2c is in /netlib/f2c/libf2c.zip, e.g.,

                http://www.netlib.org/f2c/libf2c.zip
*/

#ifdef __cplusplus
extern "C" {
#endif
#include "v3p_netlib.h"

/* Table of constant values */

static integer c__1 = 1;
static logical c_true = TRUE_;

/*<    >*/
/* Subroutine */ int lmder_(
  void (*fcn)(v3p_netlib_integer*,
              v3p_netlib_integer*,
              v3p_netlib_doublereal*,
              v3p_netlib_doublereal*,
              v3p_netlib_doublereal*,
              v3p_netlib_integer*,
              v3p_netlib_integer*,
              void*),
        integer *m, integer *n, doublereal *x,
        doublereal *fvec, doublereal *fjac, integer *ldfjac, doublereal *ftol,
         doublereal *xtol, doublereal *gtol, integer *maxfev, doublereal *
        diag, integer *mode, doublereal *factor, integer *nprint, integer *
        info, integer *nfev, integer *njev, integer *ipvt, doublereal *qtf, 
        doublereal *wa1, doublereal *wa2, doublereal *wa3, doublereal *wa4,
        void* userdata)
{
    /* Initialized data */

    static doublereal one = 1.; /* constant */
    static doublereal p1 = .1; /* constant */
    static doublereal p5 = .5; /* constant */
    static doublereal p25 = .25; /* constant */
    static doublereal p75 = .75; /* constant */
    static doublereal p0001 = 1e-4; /* constant */
    static doublereal zero = 0.; /* constant */

    /* System generated locals */
    integer fjac_dim1, fjac_offset, i__1, i__2;
    doublereal d__1, d__2, d__3;

    /* Builtin functions */
    double sqrt(doublereal);

    /* Local variables */
    integer i__, j, l;
    doublereal par, sum;
    integer iter;
    doublereal temp=0, temp1, temp2;
    integer iflag;
    doublereal delta;
    extern /* Subroutine */ int qrfac_(integer *, integer *, doublereal *, 
            integer *, logical *, integer *, integer *, doublereal *, 
            doublereal *, doublereal *), lmpar_(integer *, doublereal *, 
            integer *, integer *, doublereal *, doublereal *, doublereal *, 
            doublereal *, doublereal *, doublereal *, doublereal *, 
            doublereal *);
    doublereal ratio;
    extern doublereal enorm_(integer *, doublereal *);
    doublereal fnorm, gnorm, pnorm, xnorm=0, fnorm1, actred, dirder, epsmch, 
            prered;
    extern doublereal dpmpar_(integer *);

/*<       integer m,n,ldfjac,maxfev,mode,nprint,info,nfev,njev >*/
/*<       integer ipvt(n) >*/
/*<       double precision ftol,xtol,gtol,factor >*/
/*<    >*/
/*     ********** */

/*     subroutine lmder */

/*     the purpose of lmder is to minimize the sum of the squares of */
/*     m nonlinear functions in n variables by a modification of */
/*     the levenberg-marquardt algorithm. the user must provide a */
/*     subroutine which calculates the functions and the jacobian. */

/*     the subroutine statement is */

/*       subroutine lmder(fcn,m,n,x,fvec,fjac,ldfjac,ftol,xtol,gtol, */
/*                        maxfev,diag,mode,factor,nprint,info,nfev, */
/*                        njev,ipvt,qtf,wa1,wa2,wa3,wa4) */

/*     where */

/*       fcn is the name of the user-supplied subroutine which */
/*         calculates the functions and the jacobian. fcn must */
/*         be declared in an external statement in the user */
/*         calling program, and should be written as follows. */

/*         subroutine fcn(m,n,x,fvec,fjac,ldfjac,iflag) */
/*         integer m,n,ldfjac,iflag */
/*         double precision x(n),fvec(m),fjac(ldfjac,n) */
/*         ---------- */
/*         if iflag = 1 calculate the functions at x and */
/*         return this vector in fvec. do not alter fjac. */
/*         if iflag = 2 calculate the jacobian at x and */
/*         return this matrix in fjac. do not alter fvec. */
/*         ---------- */
/*         return */
/*         end */

/*         the value of iflag should not be changed by fcn unless */
/*         the user wants to terminate execution of lmder. */
/*         in this case set iflag to a negative integer. */

/*       m is a positive integer input variable set to the number */
/*         of functions. */

/*       n is a positive integer input variable set to the number */
/*         of variables. n must not exceed m. */

/*       x is an array of length n. on input x must contain */
/*         an initial estimate of the solution vector. on output x */
/*         contains the final estimate of the solution vector. */

/*       fvec is an output array of length m which contains */
/*         the functions evaluated at the output x. */

/*       fjac is an output m by n array. the upper n by n submatrix */
/*         of fjac contains an upper triangular matrix r with */
/*         diagonal elements of nonincreasing magnitude such that */

/*                t     t           t */
/*               p *(jac *jac)*p = r *r, */

/*         where p is a permutation matrix and jac is the final */
/*         calculated jacobian. column j of p is column ipvt(j) */
/*         (see below) of the identity matrix. the lower trapezoidal */
/*         part of fjac contains information generated during */
/*         the computation of r. */

/*       ldfjac is a positive integer input variable not less than m */
/*         which specifies the leading dimension of the array fjac. */

/*       ftol is a nonnegative input variable. termination */
/*         occurs when both the actual and predicted relative */
/*         reductions in the sum of squares are at most ftol. */
/*         therefore, ftol measures the relative error desired */
/*         in the sum of squares. */

/*       xtol is a nonnegative input variable. termination */
/*         occurs when the relative error between two consecutive */
/*         iterates is at most xtol. therefore, xtol measures the */
/*         relative error desired in the approximate solution. */

/*       gtol is a nonnegative input variable. termination */
/*         occurs when the cosine of the angle between fvec and */
/*         any column of the jacobian is at most gtol in absolute */
/*         value. therefore, gtol measures the orthogonality */
/*         desired between the function vector and the columns */
/*         of the jacobian. */

/*       maxfev is a positive integer input variable. termination */
/*         occurs when the number of calls to fcn with iflag = 1 */
/*         has reached maxfev. */

/*       diag is an array of length n. if mode = 1 (see */
/*         below), diag is internally set. if mode = 2, diag */
/*         must contain positive entries that serve as */
/*         multiplicative scale factors for the variables. */

/*       mode is an integer input variable. if mode = 1, the */
/*         variables will be scaled internally. if mode = 2, */
/*         the scaling is specified by the input diag. other */
/*         values of mode are equivalent to mode = 1. */

/*       factor is a positive input variable used in determining the */
/*         initial step bound. this bound is set to the product of */
/*         factor and the euclidean norm of diag*x if nonzero, or else */
/*         to factor itself. in most cases factor should lie in the */
/*         interval (.1,100.).100. is a generally recommended value. */

/*       nprint is an integer input variable that enables controlled */
/*         printing of iterates if it is positive. in this case, */
/*         fcn is called with iflag = 0 at the beginning of the first */
/*         iteration and every nprint iterations thereafter and */
/*         immediately prior to return, with x, fvec, and fjac */
/*         available for printing. fvec and fjac should not be */
/*         altered. if nprint is not positive, no special calls */
/*         of fcn with iflag = 0 are made. */

/*       info is an integer output variable. if the user has */
/*         terminated execution, info is set to the (negative) */
/*         value of iflag. see description of fcn. otherwise, */
/*         info is set as follows. */

/*         info = 0  improper input parameters. */

/*         info = 1  both actual and predicted relative reductions */
/*                   in the sum of squares are at most ftol. */

/*         info = 2  relative error between two consecutive iterates */
/*                   is at most xtol. */

/*         info = 3  conditions for info = 1 and info = 2 both hold. */

/*         info = 4  the cosine of the angle between fvec and any */
/*                   column of the jacobian is at most gtol in */
/*                   absolute value. */

/*         info = 5  number of calls to fcn with iflag = 1 has */
/*                   reached maxfev. */

/*         info = 6  ftol is too small. no further reduction in */
/*                   the sum of squares is possible. */

/*         info = 7  xtol is too small. no further improvement in */
/*                   the approximate solution x is possible. */

/*         info = 8  gtol is too small. fvec is orthogonal to the */
/*                   columns of the jacobian to machine precision. */

/*       nfev is an integer output variable set to the number of */
/*         calls to fcn with iflag = 1. */

/*       njev is an integer output variable set to the number of */
/*         calls to fcn with iflag = 2. */

/*       ipvt is an integer output array of length n. ipvt */
/*         defines a permutation matrix p such that jac*p = q*r, */
/*         where jac is the final calculated jacobian, q is */
/*         orthogonal (not stored), and r is upper triangular */
/*         with diagonal elements of nonincreasing magnitude. */
/*         column j of p is column ipvt(j) of the identity matrix. */

/*       qtf is an output array of length n which contains */
/*         the first n elements of the vector (q transpose)*fvec. */

/*       wa1, wa2, and wa3 are work arrays of length n. */

/*       wa4 is a work array of length m. */

/*     subprograms called */

/*       user-supplied ...... fcn */

/*       minpack-supplied ... dpmpar,enorm,lmpar,qrfac */

/*       fortran-supplied ... dabs,dmax1,dmin1,dsqrt,mod */

/*     argonne national laboratory. minpack project. march 1980. */
/*     burton s. garbow, kenneth e. hillstrom, jorge j. more */

/*     ********** */
/*<       integer i,iflag,iter,j,l >*/
/*<    >*/
/*<       double precision dpmpar,enorm >*/
/*<    >*/
    /* Parameter adjustments */
    --wa4;
    --fvec;
    --wa3;
    --wa2;
    --wa1;
    --qtf;
    --ipvt;
    --diag;
    --x;
    fjac_dim1 = *ldfjac;
    fjac_offset = 1 + fjac_dim1;
    fjac -= fjac_offset;

    /* Function Body */

/*     epsmch is the machine precision. */

/*<       epsmch = dpmpar(1) >*/
    epsmch = dpmpar_(&c__1);

/*<       info = 0 >*/
    *info = 0;
/*<       iflag = 0 >*/
    iflag = 0;
/*<       nfev = 0 >*/
    *nfev = 0;
/*<       njev = 0 >*/
    *njev = 0;

/*     check the input parameters for errors. */

/*<    >*/
    if (*n <= 0 || *m < *n || *ldfjac < *m || *ftol < zero || *xtol < zero || 
            *gtol < zero || *maxfev <= 0 || *factor <= zero) {
        goto L300;
    }
/*<       if (mode .ne. 2) go to 20 >*/
    if (*mode != 2) {
        goto L20;
    }
/*<       do 10 j = 1, n >*/
    i__1 = *n;
    for (j = 1; j <= i__1; ++j) {
/*<          if (diag(j) .le. zero) go to 300 >*/
        if (diag[j] <= zero) {
            goto L300;
        }
/*<    10    continue >*/
/* L10: */
    }
/*<    20 continue >*/
L20:

/*     evaluate the function at the starting point */
/*     and calculate its norm. */

/*<       iflag = 1 >*/
    iflag = 1;
/*<       call fcn(m,n,x,fvec,fjac,ldfjac,iflag) >*/
    (*fcn)(m, n, &x[1], &fvec[1], &fjac[fjac_offset], ldfjac, &iflag,
           userdata);
/*<       nfev = 1 >*/
    *nfev = 1;
/*<       if (iflag .lt. 0) go to 300 >*/
    if (iflag < 0) {
        goto L300;
    }
/*<       fnorm = enorm(m,fvec) >*/
    fnorm = enorm_(m, &fvec[1]);

/*     initialize levenberg-marquardt parameter and iteration counter. */

/*<       par = zero >*/
    par = zero;
/*<       iter = 1 >*/
    iter = 1;

/*     beginning of the outer loop. */

/*<    30 continue >*/
L30:

/*        calculate the jacobian matrix. */

/*<          iflag = 2 >*/
    iflag = 2;
/*<          call fcn(m,n,x,fvec,fjac,ldfjac,iflag) >*/
    (*fcn)(m, n, &x[1], &fvec[1], &fjac[fjac_offset], ldfjac, &iflag,
           userdata);
/*<          njev = njev + 1 >*/
    ++(*njev);
/*<          if (iflag .lt. 0) go to 300 >*/
    if (iflag < 0) {
        goto L300;
    }

/*        if requested, call fcn to enable printing of iterates. */

/*<          if (nprint .le. 0) go to 40 >*/
    if (*nprint <= 0) {
        goto L40;
    }
/*<          iflag = 0 >*/
    iflag = 0;
/*<    >*/
    if ((iter - 1) % *nprint == 0) {
        (*fcn)(m, n, &x[1], &fvec[1], &fjac[fjac_offset], ldfjac, &iflag,
               userdata);
    }
/*<          if (iflag .lt. 0) go to 300 >*/
    if (iflag < 0) {
        goto L300;
    }
/*<    40    continue >*/
L40:

/*        compute the qr factorization of the jacobian. */

/*<          call qrfac(m,n,fjac,ldfjac,.true.,ipvt,n,wa1,wa2,wa3) >*/
    qrfac_(m, n, &fjac[fjac_offset], ldfjac, &c_true, &ipvt[1], n, &wa1[1], &
            wa2[1], &wa3[1]);

/*        on the first iteration and if mode is 1, scale according */
/*        to the norms of the columns of the initial jacobian. */

/*<          if (iter .ne. 1) go to 80 >*/
    if (iter != 1) {
        goto L80;
    }
/*<          if (mode .eq. 2) go to 60 >*/
    if (*mode == 2) {
        goto L60;
    }
/*<          do 50 j = 1, n >*/
    i__1 = *n;
    for (j = 1; j <= i__1; ++j) {
/*<             diag(j) = wa2(j) >*/
        diag[j] = wa2[j];
/*<             if (wa2(j) .eq. zero) diag(j) = one >*/
        if (wa2[j] == zero) {
            diag[j] = one;
        }
/*<    50       continue >*/
/* L50: */
    }
/*<    60    continue >*/
L60:

/*        on the first iteration, calculate the norm of the scaled x */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -