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

📄 lmder.c

📁 DTMK软件开发包,此为开源软件,是一款很好的医学图像开发资源.
💻 C
📖 第 1 页 / 共 2 页
字号:
/*        and initialize the step bound delta. */

/*<          do 70 j = 1, n >*/
    i__1 = *n;
    for (j = 1; j <= i__1; ++j) {
/*<             wa3(j) = diag(j)*x(j) >*/
        wa3[j] = diag[j] * x[j];
/*<    70       continue >*/
/* L70: */
    }
/*<          xnorm = enorm(n,wa3) >*/
    xnorm = enorm_(n, &wa3[1]);
/*<          delta = factor*xnorm >*/
    delta = *factor * xnorm;
/*<          if (delta .eq. zero) delta = factor >*/
    if (delta == zero) {
        delta = *factor;
    }
/*<    80    continue >*/
L80:

/*        form (q transpose)*fvec and store the first n components in */
/*        qtf. */

/*<          do 90 i = 1, m >*/
    i__1 = *m;
    for (i__ = 1; i__ <= i__1; ++i__) {
/*<             wa4(i) = fvec(i) >*/
        wa4[i__] = fvec[i__];
/*<    90       continue >*/
/* L90: */
    }
/*<          do 130 j = 1, n >*/
    i__1 = *n;
    for (j = 1; j <= i__1; ++j) {
/*<             if (fjac(j,j) .eq. zero) go to 120 >*/
        if (fjac[j + j * fjac_dim1] == zero) {
            goto L120;
        }
/*<             sum = zero >*/
        sum = zero;
/*<             do 100 i = j, m >*/
        i__2 = *m;
        for (i__ = j; i__ <= i__2; ++i__) {
/*<                sum = sum + fjac(i,j)*wa4(i) >*/
            sum += fjac[i__ + j * fjac_dim1] * wa4[i__];
/*<   100          continue >*/
/* L100: */
        }
/*<             temp = -sum/fjac(j,j) >*/
        temp = -sum / fjac[j + j * fjac_dim1];
/*<             do 110 i = j, m >*/
        i__2 = *m;
        for (i__ = j; i__ <= i__2; ++i__) {
/*<                wa4(i) = wa4(i) + fjac(i,j)*temp >*/
            wa4[i__] += fjac[i__ + j * fjac_dim1] * temp;
/*<   110          continue >*/
/* L110: */
        }
/*<   120       continue >*/
L120:
/*<             fjac(j,j) = wa1(j) >*/
        fjac[j + j * fjac_dim1] = wa1[j];
/*<             qtf(j) = wa4(j) >*/
        qtf[j] = wa4[j];
/*<   130       continue >*/
/* L130: */
    }

/*        compute the norm of the scaled gradient. */

/*<          gnorm = zero >*/
    gnorm = zero;
/*<          if (fnorm .eq. zero) go to 170 >*/
    if (fnorm == zero) {
        goto L170;
    }
/*<          do 160 j = 1, n >*/
    i__1 = *n;
    for (j = 1; j <= i__1; ++j) {
/*<             l = ipvt(j) >*/
        l = ipvt[j];
/*<             if (wa2(l) .eq. zero) go to 150 >*/
        if (wa2[l] == zero) {
            goto L150;
        }
/*<             sum = zero >*/
        sum = zero;
/*<             do 140 i = 1, j >*/
        i__2 = j;
        for (i__ = 1; i__ <= i__2; ++i__) {
/*<                sum = sum + fjac(i,j)*(qtf(i)/fnorm) >*/
            sum += fjac[i__ + j * fjac_dim1] * (qtf[i__] / fnorm);
/*<   140          continue >*/
/* L140: */
        }
/*<             gnorm = dmax1(gnorm,dabs(sum/wa2(l))) >*/
/* Computing MAX */
        d__2 = gnorm, d__3 = (d__1 = sum / wa2[l], abs(d__1));
        gnorm = max(d__2,d__3);
/*<   150       continue >*/
L150:
/*<   160       continue >*/
/* L160: */
        ;
    }
/*<   170    continue >*/
L170:

/*        test for convergence of the gradient norm. */

/*<          if (gnorm .le. gtol) info = 4 >*/
    if (gnorm <= *gtol) {
        *info = 4;
    }
/*<          if (info .ne. 0) go to 300 >*/
    if (*info != 0) {
        goto L300;
    }

/*        rescale if necessary. */

/*<          if (mode .eq. 2) go to 190 >*/
    if (*mode == 2) {
        goto L190;
    }
/*<          do 180 j = 1, n >*/
    i__1 = *n;
    for (j = 1; j <= i__1; ++j) {
/*<             diag(j) = dmax1(diag(j),wa2(j)) >*/
/* Computing MAX */
        d__1 = diag[j], d__2 = wa2[j];
        diag[j] = max(d__1,d__2);
/*<   180       continue >*/
/* L180: */
    }
/*<   190    continue >*/
L190:

/*        beginning of the inner loop. */

/*<   200    continue >*/
L200:

/*           determine the levenberg-marquardt parameter. */

/*<    >*/
    lmpar_(n, &fjac[fjac_offset], ldfjac, &ipvt[1], &diag[1], &qtf[1], &delta,
             &par, &wa1[1], &wa2[1], &wa3[1], &wa4[1]);

/*           store the direction p and x + p. calculate the norm of p. */

/*<             do 210 j = 1, n >*/
    i__1 = *n;
    for (j = 1; j <= i__1; ++j) {
/*<                wa1(j) = -wa1(j) >*/
        wa1[j] = -wa1[j];
/*<                wa2(j) = x(j) + wa1(j) >*/
        wa2[j] = x[j] + wa1[j];
/*<                wa3(j) = diag(j)*wa1(j) >*/
        wa3[j] = diag[j] * wa1[j];
/*<   210          continue >*/
/* L210: */
    }
/*<             pnorm = enorm(n,wa3) >*/
    pnorm = enorm_(n, &wa3[1]);

/*           on the first iteration, adjust the initial step bound. */

/*<             if (iter .eq. 1) delta = dmin1(delta,pnorm) >*/
    if (iter == 1) {
        delta = min(delta,pnorm);
    }

/*           evaluate the function at x + p and calculate its norm. */

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

/*           compute the scaled actual reduction. */

/*<             actred = -one >*/
    actred = -one;
/*<             if (p1*fnorm1 .lt. fnorm) actred = one - (fnorm1/fnorm)**2 >*/
    if (p1 * fnorm1 < fnorm) {
/* Computing 2nd power */
        d__1 = fnorm1 / fnorm;
        actred = one - d__1 * d__1;
    }

/*           compute the scaled predicted reduction and */
/*           the scaled directional derivative. */

/*<             do 230 j = 1, n >*/
    i__1 = *n;
    for (j = 1; j <= i__1; ++j) {
/*<                wa3(j) = zero >*/
        wa3[j] = zero;
/*<                l = ipvt(j) >*/
        l = ipvt[j];
/*<                temp = wa1(l) >*/
        temp = wa1[l];
/*<                do 220 i = 1, j >*/
        i__2 = j;
        for (i__ = 1; i__ <= i__2; ++i__) {
/*<                   wa3(i) = wa3(i) + fjac(i,j)*temp >*/
            wa3[i__] += fjac[i__ + j * fjac_dim1] * temp;
/*<   220             continue >*/
/* L220: */
        }
/*<   230          continue >*/
/* L230: */
    }
/*<             temp1 = enorm(n,wa3)/fnorm >*/
    temp1 = enorm_(n, &wa3[1]) / fnorm;
/*<             temp2 = (dsqrt(par)*pnorm)/fnorm >*/
    temp2 = sqrt(par) * pnorm / fnorm;
/*<             prered = temp1**2 + temp2**2/p5 >*/
/* Computing 2nd power */
    d__1 = temp1;
/* Computing 2nd power */
    d__2 = temp2;
    prered = d__1 * d__1 + d__2 * d__2 / p5;
/*<             dirder = -(temp1**2 + temp2**2) >*/
/* Computing 2nd power */
    d__1 = temp1;
/* Computing 2nd power */
    d__2 = temp2;
    dirder = -(d__1 * d__1 + d__2 * d__2);

/*           compute the ratio of the actual to the predicted */
/*           reduction. */

/*<             ratio = zero >*/
    ratio = zero;
/*<             if (prered .ne. zero) ratio = actred/prered >*/
    if (prered != zero) {
        ratio = actred / prered;
    }

/*           update the step bound. */

/*<             if (ratio .gt. p25) go to 240 >*/
    if (ratio > p25) {
        goto L240;
    }
/*<                if (actred .ge. zero) temp = p5 >*/
    if (actred >= zero) {
        temp = p5;
    }
/*<    >*/
    if (actred < zero) {
        temp = p5 * dirder / (dirder + p5 * actred);
    }
/*<                if (p1*fnorm1 .ge. fnorm .or. temp .lt. p1) temp = p1 >*/
    if (p1 * fnorm1 >= fnorm || temp < p1) {
        temp = p1;
    }
/*<                delta = temp*dmin1(delta,pnorm/p1) >*/
/* Computing MIN */
    d__1 = delta, d__2 = pnorm / p1;
    delta = temp * min(d__1,d__2);
/*<                par = par/temp >*/
    par /= temp;
/*<                go to 260 >*/
    goto L260;
/*<   240       continue >*/
L240:
/*<                if (par .ne. zero .and. ratio .lt. p75) go to 250 >*/
    if (par != zero && ratio < p75) {
        goto L250;
    }
/*<                delta = pnorm/p5 >*/
    delta = pnorm / p5;
/*<                par = p5*par >*/
    par = p5 * par;
/*<   250          continue >*/
L250:
/*<   260       continue >*/
L260:

/*           test for successful iteration. */

/*<             if (ratio .lt. p0001) go to 290 >*/
    if (ratio < p0001) {
        goto L290;
    }

/*           successful iteration. update x, fvec, and their norms. */

/*<             do 270 j = 1, n >*/
    i__1 = *n;
    for (j = 1; j <= i__1; ++j) {
/*<                x(j) = wa2(j) >*/
        x[j] = wa2[j];
/*<                wa2(j) = diag(j)*x(j) >*/
        wa2[j] = diag[j] * x[j];
/*<   270          continue >*/
/* L270: */
    }
/*<             do 280 i = 1, m >*/
    i__1 = *m;
    for (i__ = 1; i__ <= i__1; ++i__) {
/*<                fvec(i) = wa4(i) >*/
        fvec[i__] = wa4[i__];
/*<   280          continue >*/
/* L280: */
    }
/*<             xnorm = enorm(n,wa2) >*/
    xnorm = enorm_(n, &wa2[1]);
/*<             fnorm = fnorm1 >*/
    fnorm = fnorm1;
/*<             iter = iter + 1 >*/
    ++iter;
/*<   290       continue >*/
L290:

/*           tests for convergence. */

/*<    >*/
    if (abs(actred) <= *ftol && prered <= *ftol && p5 * ratio <= one) {
        *info = 1;
    }
/*<             if (delta .le. xtol*xnorm) info = 2 >*/
    if (delta <= *xtol * xnorm) {
        *info = 2;
    }
/*<    >*/
    if (abs(actred) <= *ftol && prered <= *ftol && p5 * ratio <= one && *info 
            == 2) {
        *info = 3;
    }
/*<             if (info .ne. 0) go to 300 >*/
    if (*info != 0) {
        goto L300;
    }

/*           tests for termination and stringent tolerances. */

/*<             if (nfev .ge. maxfev) info = 5 >*/
    if (*nfev >= *maxfev) {
        *info = 5;
    }
/*<    >*/
    if (abs(actred) <= epsmch && prered <= epsmch && p5 * ratio <= one) {
        *info = 6;
    }
/*<             if (delta .le. epsmch*xnorm) info = 7 >*/
    if (delta <= epsmch * xnorm) {
        *info = 7;
    }
/*<             if (gnorm .le. epsmch) info = 8 >*/
    if (gnorm <= epsmch) {
        *info = 8;
    }
/*<             if (info .ne. 0) go to 300 >*/
    if (*info != 0) {
        goto L300;
    }

/*           end of the inner loop. repeat if iteration unsuccessful. */

/*<             if (ratio .lt. p0001) go to 200 >*/
    if (ratio < p0001) {
        goto L200;
    }

/*        end of the outer loop. */

/*<          go to 30 >*/
    goto L30;
/*<   300 continue >*/
L300:

/*     termination, either normal or user imposed. */

/*<       if (iflag .lt. 0) info = iflag >*/
    if (iflag < 0) {
        *info = iflag;
    }
/*<       iflag = 0 >*/
    iflag = 0;
/*<       if (nprint .gt. 0) call fcn(m,n,x,fvec,fjac,ldfjac,iflag) >*/
    if (*nprint > 0) {
        (*fcn)(m, n, &x[1], &fvec[1], &fjac[fjac_offset], ldfjac, &iflag,
               userdata);
    }
/*<       return >*/
    return 0;

/*     last card of subroutine lmder. */

/*<       end >*/
} /* lmder_ */

#ifdef __cplusplus
        }
#endif

⌨️ 快捷键说明

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