19 subroutine lmnls(fcn,m,n,x,fvec,fjac,ldfjac,ftol,xtol,gtol,
20 * maxfev,maxitr,diag,scale,
factor,nprint,
21 *
info,nfev,njev,ipvt,qtf,gnvec,gradf,
32 integer m,n,ldfjac,maxfev,maxitr,nprint,info,istep,nfev,njev
34 double precision ftol,xtol,gtol,factor
35 double precision x(n),fvec(m),fjac(ldfjac,
njcol),diag(
njcol),
221 double precision actred,delta,dirder,epsmch,fnorm1,gnorm,par,
222 * pnorm,prered,ratio,sum,temp,temp1,temp2,xnorm
224 double precision enorm
226 double precision ONE,P1,P5,P25,P75,P0001,ZERO
234 data one,p1,p5,p25,p75,p0001,zero
235 * /1.0d0,1.0d-1,5.0d-1,2.5d-1,7.5d-1,1.0d-4,0.0d0/
250 if (n.le.0 .or. m.lt.n .or. ldfjac.lt.m
251 * .or. ftol.lt.zero .or. xtol.lt.zero .or. gtol.lt.zero
252 * .or. maxfev.le.0 .or.maxitr.le.0 .or. factor.le.zero)
268 call fcn(m,n,x,fvec,fjac,ldfjac,iflag)
270 if (iflag.lt.0)
go to 300
283 call fcn(m,n,x,fvec,fjac,ldfjac,iflag)
286 if (iflag.lt.0)
go to 300
291 if (nprint.gt.0)
then
293 if (mod(
iter-1,nprint).eq.0)
294 *
call fcn(m,n,x,fvec,fjac,ldfjac,iflag)
295 if (iflag.lt.0)
go to 300
302 call qrfac(m,
njcol,fjac,ldfjac,.true.,ipvt,n,wa1,wa2,wa3)
311 if (scale(j).le.zero)
then
314 diag(j)=wa2(j)/scale(j)
316 if (diag(j).eq.zero) diag(j)=one
321 write(
itrace,1001) (wa2(j),j=1,n)
322 write(
itrace,1002) (diag(j),j=1,n)
334 if (delta.eq.zero) delta=factor
347 if (fjac(j,j).ne.zero)
then
350 sum=sum + fjac(i,j)*wa4(i)
354 wa4(i)=wa4(i) + fjac(i,j)*temp
366 if (
fnorm.ne.zero)
then
369 if (wa2(l).ne.zero)
then
372 sum=sum + fjac(i,j)*(qtf(i)/
fnorm)
374 gnorm=dmax1(gnorm,dabs(sum/wa2(l)))
382 if (gnorm.le.gtol) info=4
383 if (info.ne.0)
go to 300
389 if (scale(j).gt.zero)
then
391 diag(j)=dmax1(diag(j),temp)
405 call lmpar(n,fjac,ldfjac,ipvt,diag,qtf,delta,par,wa1,wa2,
406 * wa3,wa4,gnvec,gradf)
408 grdclc=grdclc.or.(par.ne.zero)
415 wa3(j)=diag(j)*wa1(j)
425 if (delta.gt.pnorm)
then
430 delta=dmin1(delta,pnorm)
433 if (istep.eq.0 .and.
itrace.ne.0)
then
442 call fcn(m,n,wa2,wa4,fjac,ldfjac,iflag)
444 if (iflag.lt.0)
go to 300
452 if (p1*fnorm1.lt.
fnorm) actred=one-(fnorm1/
fnorm)**2
463 wa3(i)=wa3(i) + fjac(i,j)*temp
466 temp1=enorm(n,wa3)/
fnorm
467 temp2=(dsqrt(par)*pnorm)/
fnorm
468 prered=temp1**2 + temp2**2/p5
469 dirder=-(temp1**2 + temp2**2)
476 if (prered.ne.zero) ratio=actred/prered
489 if (ratio.le.p25)
then
490 if (actred.ge.zero) temp=p5
491 if (actred.lt.zero) temp=p5*dirder/(dirder + p5*actred)
492 if (p1*fnorm1.ge.
fnorm .or. temp.lt.p1) temp=p1
493 if (delta.gt.pnorm/p1)
then
510 if (par.eq.zero .or. ratio.ge.p75)
then
520 # one/temp,trstr,fnorm1,(wa2(j)-x(j),j=1,n)
525 if (ratio.ge.p0001)
then
542 write(
itrace,1006) (diag(j),j=1,n)
543 if (grdclc)
write(
itrace,1007) (gradf(j),j=1,n)
544 write(
itrace,1008) (gnvec(j),j=1,n)
553 if (dabs(actred).le.ftol .and. prered.le.ftol
554 * .and. p5*ratio.le.one) info=1
555 if (delta.le.xtol*xnorm) info=info + 2
556 if (info.ne.0)
go to 300
561 if (nfev.ge.maxfev) info=5
562 if (
iter.ge.maxitr) info=6
563 if (dabs(actred).le.epsmch .and. prered.le.epsmch
564 * .and. p5*ratio.le.one) info=7
565 if (delta.le.epsmch*xnorm) info=8
566 if (gnorm.le.epsmch) info=9
567 if (info.ne.0)
go to 300
571 if (ratio.lt.p0001)
go to 200
580 if (iflag.lt.0) info=10
582 if (info.gt.4) iflag=-iflag
583 if (info.ne.0.and.info.ne.10.and.nprint.gt.0)
584 #
call fcn(m,n,x,fvec,fjac,ldfjac,iflag)
589 1000
format(/10x,41(
'=')/10x,
590 #
'TRACE OF LEVENBERG-MARQUARDT MINIMIZATION'/
591 # 10x,41(
'=')//
'INITIAL SCALING:'/13x,10(1x,a9,2x))
592 1001
format(
'Col norms of J:',10(2x,g10.4)/)
593 1002
format(9x,
'Scale:',10(2x,g10.4))
594 1003
format(/10x,
'Scaled X norm: ',g11.5/6x,
'Trust region (TR):',
595 # g11.5,
' =(Xnorm*',g9.3,
')')
596 1006
format(79(
'-')/t26,
'Scale:',10(1x,g10.4))
597 1007
format(t23,
'Gradient:',10(1x,g10.4))
598 1008
format(t21,
'G-N vector:',10(1x,g10.4))
599 1012
format(/
'##### Iteration',i3,1x,59(
'#')/
600 #
'Stp LMpar Ratio Trscl Fnorm ',12(2x,a9))
601 1013
format(79(
'-')/
' 0',t22,g11.5,12g11.4)
602 1014
format(i3,2f6.2,f5.2,a1,g11.5,sp,12g11.4)
603 1015
format(t23,
'Final TR: ',g10.4)
subroutine qrfac(m, n, a, lda, pivot, ipvt, lipvt, rdiag, acnorm, wa)
double precision, save fnorm
subroutine lmpar(n, r, ldr, ipvt, diag, qtf, delta, par, x, sdiag, wa1, wa2, gnvec, gradf)
subroutine lmnls(fcn, m, n, x, fvec, fjac, ldfjac, ftol, xtol, gtol, maxfev, maxitr, diag, scale, factor, nprint, info, nfev, njev, ipvt, qtf, gnvec, gradf, wa1, wa2, wa3, wa4)
(L)evenberg-(M)arquardt (N)onlinear (L)east (S)quares This is a modification of the original lmder su...
character *9, dimension(mxjcol), save tag
double precision, parameter rndoff