lmdif1.f
1567 lines
| 48.2 KiB
| text/x-fortran
|
FortranFixedLexer
r1601 | ||||
subroutine lmdif1(fcn,m,n,x,fvec,tol,info,iwa,wa,lwa) | ||||
integer m,n,info,lwa | ||||
integer iwa(n) | ||||
real tol | ||||
real x(n),fvec(m),wa(lwa) | ||||
external fcn | ||||
c ********** | ||||
c | ||||
c subroutine lmdif1 | ||||
c | ||||
c the purpose of lmdif1 is to minimize the sum of the squares of | ||||
c m nonlinear functions in n variables by a modification of the | ||||
c levenberg-marquardt algorithm. this is done by using the more | ||||
c general least-squares solver lmdif. the user must provide a | ||||
c subroutine which calculates the functions. the jacobian is | ||||
c then calculated by a forward-difference approximation. | ||||
c | ||||
c the subroutine statement is | ||||
c | ||||
c subroutine lmdif1(fcn,m,n,x,fvec,tol,info,iwa,wa,lwa) | ||||
c | ||||
c where | ||||
c | ||||
c fcn is the name of the user-supplied subroutine which | ||||
c calculates the functions. fcn must be declared | ||||
c in an external statement in the user calling | ||||
c program, and should be written as follows. | ||||
c | ||||
c subroutine fcn(m,n,x,fvec,iflag | ||||
c integer m,n,iflag | ||||
c real x(n),fvec(m) | ||||
c ---------- | ||||
c calculate the functions at x and | ||||
c return this vector in fvec. | ||||
c ---------- | ||||
c return | ||||
c end | ||||
c | ||||
c the value of iflag should not be changed by fcn unless | ||||
c the user wants to terminate execution of lmdif1. | ||||
c in this case set iflag to a negative integer. | ||||
c | ||||
c m is a positive integer input variable set to the number | ||||
c of functions. | ||||
c | ||||
c n is a positive integer input variable set to the number | ||||
c of variables. n must not exceed m. | ||||
c | ||||
c x is an array of length n. on input x must contain | ||||
c an initial estimate of the solution vector. on output x | ||||
c contains the final estimate of the solution vector. | ||||
c | ||||
c fvec is an output array of length m which contains | ||||
c the functions evaluated at the output x. | ||||
c | ||||
c tol is a nonnegative input variable. termination occurs | ||||
c when the algorithm estimates either that the relative | ||||
c error in the sum of squares is at most tol or that | ||||
c the relative error between x and the solution is at | ||||
c most tol. | ||||
c | ||||
c info is an integer output variable. if the user has | ||||
c terminated execution, info is set to the (negative) | ||||
c value of iflag. see description of fcn. otherwise, | ||||
c info is set as follows. | ||||
c | ||||
c info = 0 improper input parameters. | ||||
c | ||||
c info = 1 algorithm estimates that the relative error | ||||
c in the sum of squares is at most tol. | ||||
c | ||||
c info = 2 algorithm estimates that the relative error | ||||
c between x and the solution is at most tol. | ||||
c | ||||
c info = 3 conditions for info = 1 and info = 2 both hold. | ||||
c | ||||
c info = 4 fvec is orthogonal to the columns of the | ||||
c jacobian to machine precision. | ||||
c | ||||
c info = 5 number of calls to fcn has reached or | ||||
c exceeded 200*(n+1). | ||||
c | ||||
c info = 6 tol is too small. no further reduction in | ||||
c the sum of squares is possible. | ||||
c | ||||
c info = 7 tol is too small. no further improvement in | ||||
c the approximate solution x is possible. | ||||
c | ||||
c iwa is an integer work array of length n. | ||||
c | ||||
c wa is a work array of length lwa. | ||||
c | ||||
c lwa is a positive integer input variable not less than | ||||
c m*n+5*n+m. | ||||
c | ||||
c subprograms called | ||||
c | ||||
c user-supplied ...... fcn | ||||
c | ||||
c minpack-supplied ... lmdif | ||||
c | ||||
c argonne national laboratory. minpack project. march 1980. | ||||
c burton s. garbow, kenneth e. hillstrom, jorge j. more | ||||
c | ||||
c ********** | ||||
integer maxfev,mode,mp5n,nfev,nprint | ||||
real epsfcn,factor,ftol,gtol,xtol,zero | ||||
data factor,zero /1.0e2,0.0e0/ | ||||
info = 0 | ||||
c | ||||
c check the input parameters for errors. | ||||
c | ||||
if (n .le. 0 .or. m .lt. n .or. tol .lt. zero | ||||
* .or. lwa .lt. m*n + 5*n + m) go to 10 | ||||
c | ||||
c call lmdif. | ||||
c | ||||
maxfev = 200*(n + 1) | ||||
ftol = tol | ||||
xtol = tol | ||||
gtol = zero | ||||
epsfcn = zero | ||||
mode = 1 | ||||
nprint = 0 | ||||
mp5n = m + 5*n | ||||
call lmdif(fcn,m,n,x,fvec,ftol,xtol,gtol,maxfev,epsfcn,wa(1), | ||||
* mode,factor,nprint,info,nfev,wa(mp5n+1),m,iwa, | ||||
* wa(n+1),wa(2*n+1),wa(3*n+1),wa(4*n+1),wa(5*n+1)) | ||||
if (info .eq. 8) info = 4 | ||||
10 continue | ||||
return | ||||
c | ||||
c last card of subroutine lmdif1. | ||||
c | ||||
end | ||||
real function enorm(n,x) | ||||
integer n | ||||
real x(n) | ||||
c ********** | ||||
c | ||||
c function enorm | ||||
c | ||||
c given an n-vector x, this function calculates the | ||||
c euclidean norm of x. | ||||
c | ||||
c the euclidean norm is computed by accumulating the sum of | ||||
c squares in three different sums. the sums of squares for the | ||||
c small and large components are scaled so that no overflows | ||||
c occur. non-destructive underflows are permitted. underflows | ||||
c and overflows do not occur in the computation of the unscaled | ||||
c sum of squares for the intermediate components. | ||||
c the definitions of small, intermediate and large components | ||||
c depend on two constants, rdwarf and rgiant. the main | ||||
c restrictions on these constants are that rdwarf**2 not | ||||
c underflow and rgiant**2 not overflow. the constants | ||||
c given here are suitable for every known computer. | ||||
c | ||||
c the function statement is | ||||
c | ||||
c real function enorm(n,x) | ||||
c | ||||
c where | ||||
c | ||||
c n is a positive integer input variable. | ||||
c | ||||
c x is an input array of length n. | ||||
c | ||||
c subprograms called | ||||
c | ||||
c fortran-supplied ... abs,sqrt | ||||
c | ||||
c argonne national laboratory. minpack project. march 1980. | ||||
c burton s. garbow, kenneth e. hillstrom, jorge j. more | ||||
c | ||||
c ********** | ||||
integer i | ||||
real agiant,floatn,one,rdwarf,rgiant,s1,s2,s3,xabs,x1max,x3max, | ||||
* zero | ||||
data one,zero,rdwarf,rgiant /1.0e0,0.0e0,3.834e-20,1.304e19/ | ||||
s1 = zero | ||||
s2 = zero | ||||
s3 = zero | ||||
x1max = zero | ||||
x3max = zero | ||||
floatn = n | ||||
agiant = rgiant/floatn | ||||
do 90 i = 1, n | ||||
xabs = abs(x(i)) | ||||
if (xabs .gt. rdwarf .and. xabs .lt. agiant) go to 70 | ||||
if (xabs .le. rdwarf) go to 30 | ||||
c | ||||
c sum for large components. | ||||
c | ||||
if (xabs .le. x1max) go to 10 | ||||
s1 = one + s1*(x1max/xabs)**2 | ||||
x1max = xabs | ||||
go to 20 | ||||
10 continue | ||||
s1 = s1 + (xabs/x1max)**2 | ||||
20 continue | ||||
go to 60 | ||||
30 continue | ||||
c | ||||
c sum for small components. | ||||
c | ||||
if (xabs .le. x3max) go to 40 | ||||
s3 = one + s3*(x3max/xabs)**2 | ||||
x3max = xabs | ||||
go to 50 | ||||
40 continue | ||||
if (xabs .ne. zero) s3 = s3 + (xabs/x3max)**2 | ||||
50 continue | ||||
60 continue | ||||
go to 80 | ||||
70 continue | ||||
c | ||||
c sum for intermediate components. | ||||
c | ||||
s2 = s2 + xabs**2 | ||||
80 continue | ||||
90 continue | ||||
c | ||||
c calculation of norm. | ||||
c | ||||
if (s1 .eq. zero) go to 100 | ||||
enorm = x1max*sqrt(s1+(s2/x1max)/x1max) | ||||
go to 130 | ||||
100 continue | ||||
if (s2 .eq. zero) go to 110 | ||||
if (s2 .ge. x3max) | ||||
* enorm = sqrt(s2*(one+(x3max/s2)*(x3max*s3))) | ||||
if (s2 .lt. x3max) | ||||
* enorm = sqrt(x3max*((s2/x3max)+(x3max*s3))) | ||||
go to 120 | ||||
110 continue | ||||
enorm = x3max*sqrt(s3) | ||||
120 continue | ||||
130 continue | ||||
return | ||||
c | ||||
c last card of function enorm. | ||||
c | ||||
end | ||||
subroutine fdjac2(fcn,m,n,x,fvec,fjac,ldfjac,iflag,epsfcn,wa) | ||||
integer m,n,ldfjac,iflag | ||||
real epsfcn | ||||
real x(n),fvec(m),fjac(ldfjac,n),wa(m) | ||||
c ********** | ||||
c | ||||
c subroutine fdjac2 | ||||
c | ||||
c this subroutine computes a forward-difference approximation | ||||
c to the m by n jacobian matrix associated with a specified | ||||
c problem of m functions in n variables. | ||||
c | ||||
c the subroutine statement is | ||||
c | ||||
c subroutine fdjac2(fcn,m,n,x,fvec,fjac,ldfjac,iflag,epsfcn,wa) | ||||
c | ||||
c where | ||||
c | ||||
c fcn is the name of the user-supplied subroutine which | ||||
c calculates the functions. fcn must be declared | ||||
c in an external statement in the user calling | ||||
c program, and should be written as follows. | ||||
c | ||||
c subroutine fcn(m,n,x,fvec,iflag) | ||||
c integer m,n,iflag | ||||
c real x(n),fvec(m) | ||||
c ---------- | ||||
c calculate the functions at x and | ||||
c return this vector in fvec. | ||||
c ---------- | ||||
c return | ||||
c end | ||||
c | ||||
c the value of iflag should not be changed by fcn unless | ||||
c the user wants to terminate execution of fdjac2. | ||||
c in this case set iflag to a negative integer. | ||||
c | ||||
c m is a positive integer input variable set to the number | ||||
c of functions. | ||||
c | ||||
c n is a positive integer input variable set to the number | ||||
c of variables. n must not exceed m. | ||||
c | ||||
c x is an input array of length n. | ||||
c | ||||
c fvec is an input array of length m which must contain the | ||||
c functions evaluated at x. | ||||
c | ||||
c fjac is an output m by n array which contains the | ||||
c approximation to the jacobian matrix evaluated at x. | ||||
c | ||||
c ldfjac is a positive integer input variable not less than m | ||||
c which specifies the leading dimension of the array fjac. | ||||
c | ||||
c iflag is an integer variable which can be used to terminate | ||||
c the execution of fdjac2. see description of fcn. | ||||
c | ||||
c epsfcn is an input variable used in determining a suitable | ||||
c step length for the forward-difference approximation. this | ||||
c approximation assumes that the relative errors in the | ||||
c functions are of the order of epsfcn. if epsfcn is less | ||||
c than the machine precision, it is assumed that the relative | ||||
c errors in the functions are of the order of the machine | ||||
c precision. | ||||
c | ||||
c wa is a work array of length m. | ||||
c | ||||
c subprograms called | ||||
c | ||||
c user-supplied ...... fcn | ||||
c | ||||
c minpack-supplied ... spmpar | ||||
c | ||||
c fortran-supplied ... abs,amax1,sqrt | ||||
c | ||||
c argonne national laboratory. minpack project. march 1980. | ||||
c burton s. garbow, kenneth e. hillstrom, jorge j. more | ||||
c | ||||
c ********** | ||||
integer i,j | ||||
real eps,epsmch,h,temp,zero | ||||
real spmpar | ||||
data zero /0.0e0/ | ||||
c | ||||
c epsmch is the machine precision. | ||||
c | ||||
epsmch = spmpar(1) | ||||
write(*,*) "epsfcn,epsmch",epsfcn,epsmch | ||||
c call exit | ||||
c | ||||
c epsmch=1.18999999e-07 | ||||
eps = sqrt(amax1(epsfcn,epsmch)) | ||||
do 20 j = 1, n | ||||
temp = x(j) | ||||
h = eps*abs(temp) | ||||
c write(*,*) h,eps,temp | ||||
c call exit | ||||
if (h .eq. zero) h = eps | ||||
x(j) = temp + h | ||||
call fcn(m,n,x,wa,iflag) | ||||
if (iflag .lt. 0) go to 30 | ||||
x(j) = temp | ||||
do 10 i = 1, m | ||||
fjac(i,j) = (wa(i) - fvec(i))/h | ||||
c if (j .eq. n) then | ||||
c write(*,*) j,i,wa(i),fvec(i),h,fjac(i,j) | ||||
c end if | ||||
10 continue | ||||
c call exit | ||||
c write(*,*) fjac(:,1) | ||||
c call exit | ||||
20 continue | ||||
30 continue | ||||
c write(*,*) fjac(m-26,n) | ||||
c call exit | ||||
return | ||||
c | ||||
c last card of subroutine fdjac2. | ||||
c | ||||
end | ||||
subroutine lmdif(fcn,m,n,x,fvec,ftol,xtol,gtol,maxfev,epsfcn, | ||||
* diag,mode,factor,nprint,info,nfev,fjac,ldfjac, | ||||
* ipvt,qtf,wa1,wa2,wa3,wa4) | ||||
integer m,n,maxfev,mode,nprint,info,nfev,ldfjac | ||||
integer ipvt(n) | ||||
real ftol,xtol,gtol,epsfcn,factor,err(20) | ||||
real x(n),fvec(m),diag(n),fjac(ldfjac,n),qtf(n),wa1(n),wa2(n), | ||||
* wa3(n),wa4(m) | ||||
external fcn | ||||
c ********** | ||||
c | ||||
c subroutine lmdif | ||||
c | ||||
c the purpose of lmdif is to minimize the sum of the squares of | ||||
c m nonlinear functions in n variables by a modification of | ||||
c the levenberg-marquardt algorithm. the user must provide a | ||||
c subroutine which calculates the functions. the jacobian is | ||||
c then calculated by a forward-difference approximation. | ||||
c | ||||
c the subroutine statement is | ||||
c | ||||
c subroutine lmdif(fcn,m,n,x,fvec,ftol,xtol,gtol,maxfev,epsfcn, | ||||
c diag,mode,factor,nprint,info,nfev,fjac, | ||||
c ldfjac,ipvt,qtf,wa1,wa2,wa3,wa4) | ||||
c | ||||
c where | ||||
c | ||||
c fcn is the name of the user-supplied subroutine which | ||||
c calculates the functions. fcn must be declared | ||||
c in an external statement in the user calling | ||||
c program, and should be written as follows. | ||||
c | ||||
c subroutine fcn(m,n,x,fvec,iflag) | ||||
c integer m,n,iflag | ||||
c real x(n),fvec(m) | ||||
c ---------- | ||||
c calculate the functions at x and | ||||
c return this vector in fvec. | ||||
c ---------- | ||||
c return | ||||
c end | ||||
c | ||||
c the value of iflag should not be changed by fcn unless | ||||
c the user wants to terminate execution of lmdif. | ||||
c in this case set iflag to a negative integer. | ||||
c | ||||
c m is a positive integer input variable set to the number | ||||
c of functions. | ||||
c | ||||
c n is a positive integer input variable set to the number | ||||
c of variables. n must not exceed m. | ||||
c | ||||
c x is an array of length n. on input x must contain | ||||
c an initial estimate of the solution vector. on output x | ||||
c contains the final estimate of the solution vector. | ||||
c | ||||
c fvec is an output array of length m which contains | ||||
c the functions evaluated at the output x. | ||||
c | ||||
c ftol is a nonnegative input variable. termination | ||||
c occurs when both the actual and predicted relative | ||||
c reductions in the sum of squares are at most ftol. | ||||
c therefore, ftol measures the relative error desired | ||||
c in the sum of squares. | ||||
c | ||||
c xtol is a nonnegative input variable. termination | ||||
c occurs when the relative error between two consecutive | ||||
c iterates is at most xtol. therefore, xtol measures the | ||||
c relative error desired in the approximate solution. | ||||
c | ||||
c gtol is a nonnegative input variable. termination | ||||
c occurs when the cosine of the angle between fvec and | ||||
c any column of the jacobian is at most gtol in absolute | ||||
c value. therefore, gtol measures the orthogonality | ||||
c desired between the function vector and the columns | ||||
c of the jacobian. | ||||
c | ||||
c maxfev is a positive integer input variable. termination | ||||
c occurs when the number of calls to fcn is at least | ||||
c maxfev by the end of an iteration. | ||||
c | ||||
c epsfcn is an input variable used in determining a suitable | ||||
c step length for the forward-difference approximation. this | ||||
c approximation assumes that the relative errors in the | ||||
c functions are of the order of epsfcn. if epsfcn is less | ||||
c than the machine precision, it is assumed that the relative | ||||
c errors in the functions are of the order of the machine | ||||
c precision. | ||||
c | ||||
c diag is an array of length n. if mode = 1 (see | ||||
c below), diag is internally set. if mode = 2, diag | ||||
c must contain positive entries that serve as | ||||
c multiplicative scale factors for the variables. | ||||
c | ||||
c mode is an integer input variable. if mode = 1, the | ||||
c variables will be scaled internally. if mode = 2, | ||||
c the scaling is specified by the input diag. other | ||||
c values of mode are equivalent to mode = 1. | ||||
c | ||||
c factor is a positive input variable used in determining the | ||||
c initial step bound. this bound is set to the product of | ||||
c factor and the euclidean norm of diag*x if nonzero, or else | ||||
c to factor itself. in most cases factor should lie in the | ||||
c interval (.1,100.). 100. is a generally recommended value. | ||||
c | ||||
c nprint is an integer input variable that enables controlled | ||||
c printing of iterates if it is positive. in this case, | ||||
c fcn is called with iflag = 0 at the beginning of the first | ||||
c iteration and every nprint iterations thereafter and | ||||
c immediately prior to return, with x and fvec available | ||||
c for printing. if nprint is not positive, no special calls | ||||
c of fcn with iflag = 0 are made. | ||||
c | ||||
c info is an integer output variable. if the user has | ||||
c terminated execution, info is set to the (negative) | ||||
c value of iflag. see description of fcn. otherwise, | ||||
c info is set as follows. | ||||
c | ||||
c info = 0 improper input parameters. | ||||
c | ||||
c info = 1 both actual and predicted relative reductions | ||||
c in the sum of squares are at most ftol. | ||||
c | ||||
c info = 2 relative error between two consecutive iterates | ||||
c is at most xtol. | ||||
c | ||||
c info = 3 conditions for info = 1 and info = 2 both hold. | ||||
c | ||||
c info = 4 the cosine of the angle between fvec and any | ||||
c column of the jacobian is at most gtol in | ||||
c absolute value. | ||||
c | ||||
c info = 5 number of calls to fcn has reached or | ||||
c exceeded maxfev. | ||||
c | ||||
c info = 6 ftol is too small. no further reduction in | ||||
c the sum of squares is possible. | ||||
c | ||||
c info = 7 xtol is too small. no further improvement in | ||||
c the approximate solution x is possible. | ||||
c | ||||
c info = 8 gtol is too small. fvec is orthogonal to the | ||||
c columns of the jacobian to machine precision. | ||||
c | ||||
c nfev is an integer output variable set to the number of | ||||
c calls to fcn. | ||||
c | ||||
c fjac is an output m by n array. the upper n by n submatrix | ||||
c of fjac contains an upper triangular matrix r with | ||||
c diagonal elements of nonincreasing magnitude such that | ||||
c | ||||
c t t t | ||||
c p *(jac *jac)*p = r *r, | ||||
c | ||||
c where p is a permutation matrix and jac is the final | ||||
c calculated jacobian. column j of p is column ipvt(j) | ||||
c (see below) of the identity matrix. the lower trapezoidal | ||||
c part of fjac contains information generated during | ||||
c the computation of r. | ||||
c | ||||
c ldfjac is a positive integer input variable not less than m | ||||
c which specifies the leading dimension of the array fjac. | ||||
c | ||||
c ipvt is an integer output array of length n. ipvt | ||||
c defines a permutation matrix p such that jac*p = q*r, | ||||
c where jac is the final calculated jacobian, q is | ||||
c orthogonal (not stored), and r is upper triangular | ||||
c with diagonal elements of nonincreasing magnitude. | ||||
c column j of p is column ipvt(j) of the identity matrix. | ||||
c | ||||
c qtf is an output array of length n which contains | ||||
c the first n elements of the vector (q transpose)*fvec. | ||||
c | ||||
c wa1, wa2, and wa3 are work arrays of length n. | ||||
c | ||||
c wa4 is a work array of length m. | ||||
c | ||||
c subprograms called | ||||
c | ||||
c user-supplied ...... fcn | ||||
c | ||||
c minpack-supplied ... spmpar,enorm,fdjac2,lmpar,qrfac | ||||
c | ||||
c fortran-supplied ... abs,amax1,amin1,sqrt,mod | ||||
c | ||||
c argonne national laboratory. minpack project. march 1980. | ||||
c burton s. garbow, kenneth e. hillstrom, jorge j. more | ||||
c | ||||
c ********** | ||||
integer i,iflag,iter,j,l | ||||
real actred,delta,dirder,epsmch,fnorm,fnorm1,gnorm,one,par, | ||||
* pnorm,prered,p1,p5,p25,p75,p0001,ratio,sum,temp,temp1, | ||||
* temp2,xnorm,zero | ||||
real spmpar,enorm | ||||
C common /errors/err | ||||
data one,p1,p5,p25,p75,p0001,zero | ||||
* /1.0e0,1.0e-1,5.0e-1,2.5e-1,7.5e-1,1.0e-4,0.0e0/ | ||||
c | ||||
c epsmch is the machine precision. | ||||
c | ||||
epsmch = spmpar(1) | ||||
c | ||||
info = 0 | ||||
iflag = 0 | ||||
nfev = 0 | ||||
c | ||||
c check the input parameters for errors. | ||||
c | ||||
if (n .le. 0 .or. m .lt. n .or. ldfjac .lt. m | ||||
* .or. ftol .lt. zero .or. xtol .lt. zero .or. gtol .lt. zero | ||||
* .or. maxfev .le. 0 .or. factor .le. zero) go to 300 | ||||
if (mode .ne. 2) go to 20 | ||||
do 10 j = 1, n | ||||
if (diag(j) .le. zero) go to 300 | ||||
10 continue | ||||
20 continue | ||||
c | ||||
c evaluate the function at the starting point | ||||
c and calculate its norm. | ||||
c | ||||
iflag = 1 | ||||
c write(*,*) "before calling fcn" | ||||
c write(*,*) "fvec_before: ",fvec(222) | ||||
c write(*,*) "x_before: ",x | ||||
c write(*,*) fjac(1,1) | ||||
c call exit | ||||
call fcn(m,n,x,fvec,iflag) | ||||
c write(*,*) "x_after: ",x | ||||
c write(*,*) "fvec(2): ",fvec(222) | ||||
c write(*,*) fjac(1,1) | ||||
c call exit | ||||
c call exit | ||||
c write(*,*) "fvec_after: ",fvec(1) | ||||
c write(*,*) "after calling fcn" | ||||
c call exit | ||||
nfev = 1 | ||||
if (iflag .lt. 0) go to 300 | ||||
fnorm = enorm(m,fvec) | ||||
c | ||||
c initialize levenberg-marquardt parameter and iteration counter. | ||||
c | ||||
par = zero | ||||
iter = 1 | ||||
c | ||||
c beginning of the outer loop. | ||||
c | ||||
30 continue | ||||
c | ||||
c calculate the jacobian matrix. | ||||
c | ||||
c write(*,*) "x",x | ||||
c call exit | ||||
iflag = 2 | ||||
write(*,*) fjac(1,1) | ||||
call fdjac2(fcn,m,n,x,fvec,fjac,ldfjac,iflag,epsfcn,wa4) | ||||
nfev = nfev + n | ||||
write(*,*) "2",fjac(1,1) | ||||
c write(*,*) wa4 | ||||
c call exit | ||||
c write(*,*) "fvec(2): ",fvec(2) | ||||
c call exit | ||||
if (iflag .lt. 0) go to 300 | ||||
c | ||||
c if requested, call fcn to enable printing of iterates. | ||||
c | ||||
if (nprint .le. 0) go to 40 | ||||
iflag = 0 | ||||
if (mod(iter-1,nprint) .eq. 0) call fcn(m,n,x,fvec,iflag) | ||||
if (iflag .lt. 0) go to 300 | ||||
40 continue | ||||
c | ||||
c compute the qr factorization of the jacobian. | ||||
c | ||||
c write(*,*) fjac(1,1) | ||||
c call exit | ||||
call qrfac(m,n,fjac,ldfjac,.true.,ipvt,n,wa1,wa2,wa3) | ||||
c write(*,*) fjac(12,13) | ||||
c write(*,*) "after qrfac" | ||||
c call exit | ||||
c | ||||
c on the first iteration and if mode is 1, scale according | ||||
c to the norms of the columns of the initial jacobian. | ||||
c | ||||
if (iter .ne. 1) go to 80 | ||||
if (mode .eq. 2) go to 60 | ||||
do 50 j = 1, n | ||||
diag(j) = wa2(j) | ||||
if (wa2(j) .eq. zero) diag(j) = one | ||||
50 continue | ||||
60 continue | ||||
c | ||||
c on the first iteration, calculate the norm of the scaled x | ||||
c and initialize the step bound delta. | ||||
c | ||||
do 70 j = 1, n | ||||
wa3(j) = diag(j)*x(j) | ||||
70 continue | ||||
xnorm = enorm(n,wa3) | ||||
delta = factor*xnorm | ||||
if (delta .eq. zero) delta = factor | ||||
80 continue | ||||
c | ||||
c form (q transpose)*fvec and store the first n components in | ||||
c qtf. | ||||
c | ||||
c write(*,*) fjac(12,13) | ||||
c call exit | ||||
do 90 i = 1, m | ||||
wa4(i) = fvec(i) | ||||
90 continue | ||||
c write(*,*) wa4(222) | ||||
c call exit | ||||
do 130 j = 1, n | ||||
if (fjac(j,j) .eq. zero) go to 120 | ||||
sum = zero | ||||
do 100 i = j, m | ||||
c write(*,*) fjac(i,j),wa4(i) | ||||
c call exit | ||||
sum = sum + fjac(i,j)*wa4(i) | ||||
100 continue | ||||
temp = -sum/fjac(j,j) | ||||
c write(*,*) sum | ||||
c call exit | ||||
do 110 i = j, m | ||||
wa4(i) = wa4(i) + fjac(i,j)*temp | ||||
110 continue | ||||
120 continue | ||||
fjac(j,j) = wa1(j) | ||||
qtf(j) = wa4(j) | ||||
130 continue | ||||
c write(*,*) wa4(222) | ||||
c call exit | ||||
c | ||||
c compute the norm of the scaled gradient. | ||||
c | ||||
gnorm = zero | ||||
if (fnorm .eq. zero) go to 170 | ||||
do 160 j = 1, n | ||||
l = ipvt(j) | ||||
if (wa2(l) .eq. zero) go to 150 | ||||
sum = zero | ||||
do 140 i = 1, j | ||||
sum = sum + fjac(i,j)*(qtf(i)/fnorm) | ||||
140 continue | ||||
gnorm = amax1(gnorm,abs(sum/wa2(l))) | ||||
150 continue | ||||
160 continue | ||||
170 continue | ||||
c | ||||
c test for convergence of the gradient norm. | ||||
c | ||||
if (gnorm .le. gtol) info = 4 | ||||
if (info .ne. 0) go to 300 | ||||
c | ||||
c rescale if necessary. | ||||
c | ||||
if (mode .eq. 2) go to 190 | ||||
do 180 j = 1, n | ||||
diag(j) = amax1(diag(j),wa2(j)) | ||||
180 continue | ||||
190 continue | ||||
c | ||||
c beginning of the inner loop. | ||||
c | ||||
200 continue | ||||
c | ||||
c determine the levenberg-marquardt parameter. | ||||
c | ||||
write(*,*) "Starting lmpar" | ||||
write(*,*) "x(2)",x(2),"wa4(222)",wa4(222) | ||||
call lmpar(n,fjac,ldfjac,ipvt,diag,qtf,delta,par,wa1,wa2, | ||||
* wa3,wa4) | ||||
c | ||||
c store the direction p and x + p. calculate the norm of p. | ||||
c | ||||
do 210 j = 1, n | ||||
wa1(j) = -wa1(j) | ||||
wa2(j) = x(j) + wa1(j) | ||||
wa3(j) = diag(j)*wa1(j) | ||||
210 continue | ||||
pnorm = enorm(n,wa3) | ||||
c | ||||
c on the first iteration, adjust the initial step bound. | ||||
c | ||||
if (iter .eq. 1) delta = amin1(delta,pnorm) | ||||
c | ||||
c evaluate the function at x + p and calculate its norm. | ||||
c | ||||
iflag = 1 | ||||
write(*,*) "starting last-1 fcn" | ||||
write(*,*) "wa4_before",wa4(222) | ||||
call fcn(m,n,wa2,wa4,iflag) | ||||
nfev = nfev + 1 | ||||
c call exit | ||||
if (iflag .lt. 0) go to 300 | ||||
fnorm1 = enorm(m,wa4) | ||||
write(*,*) "wa4",wa4(222) | ||||
c call exit | ||||
c | ||||
c compute the scaled actual reduction. | ||||
c | ||||
write(*,*) "fnorm",fnorm,"fnorm1",fnorm1 | ||||
actred = -one | ||||
if (p1*fnorm1 .lt. fnorm) actred = one - (fnorm1/fnorm)**2 | ||||
c | ||||
c compute the scaled predicted reduction and | ||||
c the scaled directional derivative. | ||||
c | ||||
do 230 j = 1, n | ||||
wa3(j) = zero | ||||
l = ipvt(j) | ||||
temp = wa1(l) | ||||
do 220 i = 1, j | ||||
wa3(i) = wa3(i) + fjac(i,j)*temp | ||||
220 continue | ||||
230 continue | ||||
temp1 = enorm(n,wa3)/fnorm | ||||
temp2 = (sqrt(par)*pnorm)/fnorm | ||||
prered = temp1**2 + temp2**2/p5 | ||||
dirder = -(temp1**2 + temp2**2) | ||||
c | ||||
c compute the ratio of the actual to the predicted | ||||
c reduction. | ||||
c | ||||
write(*,*) "ratio",ratio | ||||
ratio = zero | ||||
write(*,*) "ratio2",ratio | ||||
c call exit | ||||
if (prered .ne. zero) ratio = actred/prered | ||||
write(*,*) "ratio3",ratio,actred,prered | ||||
c | ||||
c update the step bound. | ||||
c | ||||
if (ratio .gt. p25) go to 240 | ||||
if (actred .ge. zero) temp = p5 | ||||
if (actred .lt. zero) | ||||
* temp = p5*dirder/(dirder + p5*actred) | ||||
if (p1*fnorm1 .ge. fnorm .or. temp .lt. p1) temp = p1 | ||||
delta = temp*amin1(delta,pnorm/p1) | ||||
par = par/temp | ||||
go to 260 | ||||
240 continue | ||||
if (par .ne. zero .and. ratio .lt. p75) go to 250 | ||||
delta = pnorm/p5 | ||||
par = p5*par | ||||
250 continue | ||||
260 continue | ||||
c | ||||
c test for successful iteration. | ||||
c | ||||
if (ratio .lt. p0001) go to 290 | ||||
c | ||||
c successful iteration. update x, fvec, and their norms. | ||||
c | ||||
do 270 j = 1, n | ||||
C err(j)=abs(wa2(j)-x(j)) | ||||
x(j) = wa2(j) | ||||
wa2(j) = diag(j)*x(j) | ||||
270 continue | ||||
do 280 i = 1, m | ||||
fvec(i) = wa4(i) | ||||
280 continue | ||||
xnorm = enorm(n,wa2) | ||||
fnorm = fnorm1 | ||||
iter = iter + 1 | ||||
290 continue | ||||
c | ||||
c tests for convergence. | ||||
c | ||||
if (abs(actred) .le. ftol .and. prered .le. ftol | ||||
* .and. p5*ratio .le. one) info = 1 | ||||
if (delta .le. xtol*xnorm) info = 2 | ||||
if (abs(actred) .le. ftol .and. prered .le. ftol | ||||
* .and. p5*ratio .le. one .and. info .eq. 2) info = 3 | ||||
write(*,*) "info",info | ||||
if (info .ne. 0) go to 300 | ||||
c | ||||
c tests for termination and stringent tolerances. | ||||
c | ||||
write(*,*) delta,epsmch,xnorm | ||||
if (nfev .ge. maxfev) info = 5 | ||||
if (abs(actred) .le. epsmch .and. prered .le. epsmch | ||||
* .and. p5*ratio .le. one) info = 6 | ||||
if (delta .le. epsmch*xnorm) info = 7 | ||||
if (gnorm .le. epsmch) info = 8 | ||||
write(*,*) "info2",info | ||||
if (info .ne. 0) go to 300 | ||||
c | ||||
c end of the inner loop. repeat if iteration unsuccessful. | ||||
c | ||||
if (ratio .lt. p0001) go to 200 | ||||
c | ||||
c end of the outer loop. | ||||
c | ||||
go to 30 | ||||
300 continue | ||||
c | ||||
c termination, either normal or user imposed. | ||||
c | ||||
write(*,*) "starting last fcn" | ||||
if (iflag .lt. 0) info = iflag | ||||
iflag = 0 | ||||
if (nprint .gt. 0) call fcn(m,n,x,fvec,iflag) | ||||
c call exit | ||||
return | ||||
c | ||||
c last card of subroutine lmdif. | ||||
c | ||||
end | ||||
subroutine lmpar(n,r,ldr,ipvt,diag,qtb,delta,par,x,sdiag,wa1, | ||||
* wa2) | ||||
integer n,ldr | ||||
integer ipvt(n) | ||||
real delta,par | ||||
real r(ldr,n),diag(n),qtb(n),x(n),sdiag(n),wa1(n),wa2(n) | ||||
c ********** | ||||
c | ||||
c subroutine lmpar | ||||
c | ||||
c given an m by n matrix a, an n by n nonsingular diagonal | ||||
c matrix d, an m-vector b, and a positive number delta, | ||||
c the problem is to determine a value for the parameter | ||||
c par such that if x solves the system | ||||
c | ||||
c a*x = b , sqrt(par)*d*x = 0 , | ||||
c | ||||
c in the least squares sense, and dxnorm is the euclidean | ||||
c norm of d*x, then either par is zero and | ||||
c | ||||
c (dxnorm-delta) .le. 0.1*delta , | ||||
c | ||||
c or par is positive and | ||||
c | ||||
c abs(dxnorm-delta) .le. 0.1*delta . | ||||
c | ||||
c this subroutine completes the solution of the problem | ||||
c if it is provided with the necessary information from the | ||||
c qr factorization, with column pivoting, of a. that is, if | ||||
c a*p = q*r, where p is a permutation matrix, q has orthogonal | ||||
c columns, and r is an upper triangular matrix with diagonal | ||||
c elements of nonincreasing magnitude, then lmpar expects | ||||
c the full upper triangle of r, the permutation matrix p, | ||||
c and the first n components of (q transpose)*b. on output | ||||
c lmpar also provides an upper triangular matrix s such that | ||||
c | ||||
c t t t | ||||
c p *(a *a + par*d*d)*p = s *s . | ||||
c | ||||
c s is employed within lmpar and may be of separate interest. | ||||
c | ||||
c only a few iterations are generally needed for convergence | ||||
c of the algorithm. if, however, the limit of 10 iterations | ||||
c is reached, then the output par will contain the best | ||||
c value obtained so far. | ||||
c | ||||
c the subroutine statement is | ||||
c | ||||
c subroutine lmpar(n,r,ldr,ipvt,diag,qtb,delta,par,x,sdiag, | ||||
c wa1,wa2) | ||||
c | ||||
c where | ||||
c | ||||
c n is a positive integer input variable set to the order of r. | ||||
c | ||||
c r is an n by n array. on input the full upper triangle | ||||
c must contain the full upper triangle of the matrix r. | ||||
c on output the full upper triangle is unaltered, and the | ||||
c strict lower triangle contains the strict upper triangle | ||||
c (transposed) of the upper triangular matrix s. | ||||
c | ||||
c ldr is a positive integer input variable not less than n | ||||
c which specifies the leading dimension of the array r. | ||||
c | ||||
c ipvt is an integer input array of length n which defines the | ||||
c permutation matrix p such that a*p = q*r. column j of p | ||||
c is column ipvt(j) of the identity matrix. | ||||
c | ||||
c diag is an input array of length n which must contain the | ||||
c diagonal elements of the matrix d. | ||||
c | ||||
c qtb is an input array of length n which must contain the first | ||||
c n elements of the vector (q transpose)*b. | ||||
c | ||||
c delta is a positive input variable which specifies an upper | ||||
c bound on the euclidean norm of d*x. | ||||
c | ||||
c par is a nonnegative variable. on input par contains an | ||||
c initial estimate of the levenberg-marquardt parameter. | ||||
c on output par contains the final estimate. | ||||
c | ||||
c x is an output array of length n which contains the least | ||||
c squares solution of the system a*x = b, sqrt(par)*d*x = 0, | ||||
c for the output par. | ||||
c | ||||
c sdiag is an output array of length n which contains the | ||||
c diagonal elements of the upper triangular matrix s. | ||||
c | ||||
c wa1 and wa2 are work arrays of length n. | ||||
c | ||||
c subprograms called | ||||
c | ||||
c minpack-supplied ... spmpar,enorm,qrsolv | ||||
c | ||||
c fortran-supplied ... abs,amax1,amin1,sqrt | ||||
c | ||||
c argonne national laboratory. minpack project. march 1980. | ||||
c burton s. garbow, kenneth e. hillstrom, jorge j. more | ||||
c | ||||
c ********** | ||||
integer i,iter,j,jm1,jp1,k,l,nsing | ||||
real dxnorm,dwarf,fp,gnorm,parc,parl,paru,p1,p001,sum,temp,zero | ||||
real spmpar,enorm | ||||
data p1,p001,zero /1.0e-1,1.0e-3,0.0e0/ | ||||
c | ||||
c dwarf is the smallest positive magnitude. | ||||
c | ||||
dwarf = spmpar(2) | ||||
c | ||||
c compute and store in x the gauss-newton direction. if the | ||||
c jacobian is rank-deficient, obtain a least squares solution. | ||||
c | ||||
nsing = n | ||||
do 10 j = 1, n | ||||
wa1(j) = qtb(j) | ||||
if (r(j,j) .eq. zero .and. nsing .eq. n) nsing = j - 1 | ||||
if (nsing .lt. n) wa1(j) = zero | ||||
10 continue | ||||
if (nsing .lt. 1) go to 50 | ||||
do 40 k = 1, nsing | ||||
j = nsing - k + 1 | ||||
wa1(j) = wa1(j)/r(j,j) | ||||
temp = wa1(j) | ||||
jm1 = j - 1 | ||||
if (jm1 .lt. 1) go to 30 | ||||
do 20 i = 1, jm1 | ||||
wa1(i) = wa1(i) - r(i,j)*temp | ||||
20 continue | ||||
30 continue | ||||
40 continue | ||||
50 continue | ||||
do 60 j = 1, n | ||||
l = ipvt(j) | ||||
x(l) = wa1(j) | ||||
60 continue | ||||
c | ||||
c initialize the iteration counter. | ||||
c evaluate the function at the origin, and test | ||||
c for acceptance of the gauss-newton direction. | ||||
c | ||||
iter = 0 | ||||
do 70 j = 1, n | ||||
wa2(j) = diag(j)*x(j) | ||||
70 continue | ||||
dxnorm = enorm(n,wa2) | ||||
fp = dxnorm - delta | ||||
if (fp .le. p1*delta) go to 220 | ||||
c | ||||
c if the jacobian is not rank deficient, the newton | ||||
c step provides a lower bound, parl, for the zero of | ||||
c the function. otherwise set this bound to zero. | ||||
c | ||||
parl = zero | ||||
if (nsing .lt. n) go to 120 | ||||
do 80 j = 1, n | ||||
l = ipvt(j) | ||||
wa1(j) = diag(l)*(wa2(l)/dxnorm) | ||||
80 continue | ||||
do 110 j = 1, n | ||||
sum = zero | ||||
jm1 = j - 1 | ||||
if (jm1 .lt. 1) go to 100 | ||||
do 90 i = 1, jm1 | ||||
sum = sum + r(i,j)*wa1(i) | ||||
90 continue | ||||
100 continue | ||||
wa1(j) = (wa1(j) - sum)/r(j,j) | ||||
110 continue | ||||
temp = enorm(n,wa1) | ||||
parl = ((fp/delta)/temp)/temp | ||||
120 continue | ||||
c | ||||
c calculate an upper bound, paru, for the zero of the function. | ||||
c | ||||
do 140 j = 1, n | ||||
sum = zero | ||||
do 130 i = 1, j | ||||
sum = sum + r(i,j)*qtb(i) | ||||
130 continue | ||||
l = ipvt(j) | ||||
wa1(j) = sum/diag(l) | ||||
140 continue | ||||
gnorm = enorm(n,wa1) | ||||
paru = gnorm/delta | ||||
if (paru .eq. zero) paru = dwarf/amin1(delta,p1) | ||||
c | ||||
c if the input par lies outside of the interval (parl,paru), | ||||
c set par to the closer endpoint. | ||||
c | ||||
par = amax1(par,parl) | ||||
par = amin1(par,paru) | ||||
if (par .eq. zero) par = gnorm/dxnorm | ||||
c | ||||
c beginning of an iteration. | ||||
c | ||||
150 continue | ||||
iter = iter + 1 | ||||
c | ||||
c evaluate the function at the current value of par. | ||||
c | ||||
if (par .eq. zero) par = amax1(dwarf,p001*paru) | ||||
temp = sqrt(par) | ||||
do 160 j = 1, n | ||||
wa1(j) = temp*diag(j) | ||||
160 continue | ||||
call qrsolv(n,r,ldr,ipvt,wa1,qtb,x,sdiag,wa2) | ||||
do 170 j = 1, n | ||||
wa2(j) = diag(j)*x(j) | ||||
170 continue | ||||
dxnorm = enorm(n,wa2) | ||||
temp = fp | ||||
fp = dxnorm - delta | ||||
c | ||||
c if the function is small enough, accept the current value | ||||
c of par. also test for the exceptional cases where parl | ||||
c is zero or the number of iterations has reached 10. | ||||
c | ||||
if (abs(fp) .le. p1*delta | ||||
* .or. parl .eq. zero .and. fp .le. temp | ||||
* .and. temp .lt. zero .or. iter .eq. 10) go to 220 | ||||
c | ||||
c compute the newton correction. | ||||
c | ||||
do 180 j = 1, n | ||||
l = ipvt(j) | ||||
wa1(j) = diag(l)*(wa2(l)/dxnorm) | ||||
180 continue | ||||
do 210 j = 1, n | ||||
wa1(j) = wa1(j)/sdiag(j) | ||||
temp = wa1(j) | ||||
jp1 = j + 1 | ||||
if (n .lt. jp1) go to 200 | ||||
do 190 i = jp1, n | ||||
wa1(i) = wa1(i) - r(i,j)*temp | ||||
190 continue | ||||
200 continue | ||||
210 continue | ||||
temp = enorm(n,wa1) | ||||
parc = ((fp/delta)/temp)/temp | ||||
c | ||||
c depending on the sign of the function, update parl or paru. | ||||
c | ||||
if (fp .gt. zero) parl = amax1(parl,par) | ||||
if (fp .lt. zero) paru = amin1(paru,par) | ||||
c | ||||
c compute an improved estimate for par. | ||||
c | ||||
par = amax1(parl,par+parc) | ||||
c | ||||
c end of an iteration. | ||||
c | ||||
go to 150 | ||||
220 continue | ||||
c | ||||
c termination. | ||||
c | ||||
if (iter .eq. 0) par = zero | ||||
return | ||||
c | ||||
c last card of subroutine lmpar. | ||||
c | ||||
end | ||||
subroutine qrfac(m,n,a,lda,pivot,ipvt,lipvt,rdiag,acnorm,wa) | ||||
integer m,n,lda,lipvt | ||||
integer ipvt(lipvt) | ||||
logical pivot | ||||
real a(lda,n),rdiag(n),acnorm(n),wa(n) | ||||
c ********** | ||||
c | ||||
c subroutine qrfac | ||||
c | ||||
c this subroutine uses householder transformations with column | ||||
c pivoting (optional) to compute a qr factorization of the | ||||
c m by n matrix a. that is, qrfac determines an orthogonal | ||||
c matrix q, a permutation matrix p, and an upper trapezoidal | ||||
c matrix r with diagonal elements of nonincreasing magnitude, | ||||
c such that a*p = q*r. the householder transformation for | ||||
c column k, k = 1,2,...,min(m,n), is of the form | ||||
c | ||||
c t | ||||
c i - (1/u(k))*u*u | ||||
c | ||||
c where u has zeros in the first k-1 positions. the form of | ||||
c this transformation and the method of pivoting first | ||||
c appeared in the corresponding linpack subroutine. | ||||
c | ||||
c the subroutine statement is | ||||
c | ||||
c subroutine qrfac(m,n,a,lda,pivot,ipvt,lipvt,rdiag,acnorm,wa) | ||||
c | ||||
c where | ||||
c | ||||
c m is a positive integer input variable set to the number | ||||
c of rows of a. | ||||
c | ||||
c n is a positive integer input variable set to the number | ||||
c of columns of a. | ||||
c | ||||
c a is an m by n array. on input a contains the matrix for | ||||
c which the qr factorization is to be computed. on output | ||||
c the strict upper trapezoidal part of a contains the strict | ||||
c upper trapezoidal part of r, and the lower trapezoidal | ||||
c part of a contains a factored form of q (the non-trivial | ||||
c elements of the u vectors described above). | ||||
c | ||||
c lda is a positive integer input variable not less than m | ||||
c which specifies the leading dimension of the array a. | ||||
c | ||||
c pivot is a logical input variable. if pivot is set true, | ||||
c then column pivoting is enforced. if pivot is set false, | ||||
c then no column pivoting is done. | ||||
c | ||||
c ipvt is an integer output array of length lipvt. ipvt | ||||
c defines the permutation matrix p such that a*p = q*r. | ||||
c column j of p is column ipvt(j) of the identity matrix. | ||||
c if pivot is false, ipvt is not referenced. | ||||
c | ||||
c lipvt is a positive integer input variable. if pivot is false, | ||||
c then lipvt may be as small as 1. if pivot is true, then | ||||
c lipvt must be at least n. | ||||
c | ||||
c rdiag is an output array of length n which contains the | ||||
c diagonal elements of r. | ||||
c | ||||
c acnorm is an output array of length n which contains the | ||||
c norms of the corresponding columns of the input matrix a. | ||||
c if this information is not needed, then acnorm can coincide | ||||
c with rdiag. | ||||
c | ||||
c wa is a work array of length n. if pivot is false, then wa | ||||
c can coincide with rdiag. | ||||
c | ||||
c subprograms called | ||||
c | ||||
c minpack-supplied ... spmpar,enorm | ||||
c | ||||
c fortran-supplied ... amax1,sqrt,min0 | ||||
c | ||||
c argonne national laboratory. minpack project. march 1980. | ||||
c burton s. garbow, kenneth e. hillstrom, jorge j. more | ||||
c | ||||
c ********** | ||||
integer i,j,jp1,k,kmax,minmn | ||||
real ajnorm,epsmch,one,p05,sum,temp,zero | ||||
real spmpar,enorm | ||||
data one,p05,zero /1.0e0,5.0e-2,0.0e0/ | ||||
c | ||||
c epsmch is the machine precision. | ||||
c | ||||
epsmch = spmpar(1) | ||||
c epsmch=1.18999999e-07 | ||||
c | ||||
c compute the initial column norms and initialize several arrays. | ||||
c | ||||
c write(*,*) a(1,1) | ||||
c a(1,1)=12.0003815 | ||||
c write(*,*) a(1,1) | ||||
c write(*,*) enorm(m,a(1,1)),a(1,1) | ||||
c call exit | ||||
do 10 j = 1, n | ||||
c write(*,*) m,a(1,j),enorm(m,a(1,j)) | ||||
acnorm(j) = enorm(m,a(1,j)) | ||||
c write(*,*) acnorm(j) | ||||
rdiag(j) = acnorm(j) | ||||
c write(*,*) "rdiag",rdiag(j) | ||||
wa(j) = rdiag(j) | ||||
if (pivot) ipvt(j) = j | ||||
10 continue | ||||
c | ||||
c reduce a to r with householder transformations. | ||||
c | ||||
c call exit | ||||
minmn = min0(m,n) | ||||
do 110 j = 1, minmn | ||||
if (.not.pivot) go to 40 | ||||
c | ||||
c bring the column of largest norm into the pivot position. | ||||
c | ||||
c if (j .eq. 9) then | ||||
c write(*,*) "a(j,j)",a(j,j) | ||||
c call exit | ||||
c end if | ||||
kmax = j | ||||
do 20 k = j, n | ||||
c write(*,*) k,kmax,rdiag(k),rdiag(kmax) | ||||
if (rdiag(k) .gt. rdiag(kmax)) kmax = k | ||||
20 continue | ||||
c write(*,*) "kmax",kmax | ||||
c if (j .eq. 12) then | ||||
c kmax=88 | ||||
c call exit | ||||
c end if | ||||
if (kmax .eq. j) go to 40 | ||||
do 30 i = 1, m | ||||
c write(*,*) a(i,j),a(i,kmax) | ||||
temp = a(i,j) | ||||
a(i,j) = a(i,kmax) | ||||
a(i,kmax) = temp | ||||
30 continue | ||||
c write(*,*) "a(j,j)_2",a(j,j) | ||||
c if (j .eq. 13) then | ||||
c write(*,*) "a(j,j)_2",a(j,j) | ||||
c call exit | ||||
c end if | ||||
rdiag(kmax) = rdiag(j) | ||||
wa(kmax) = wa(j) | ||||
k = ipvt(j) | ||||
ipvt(j) = ipvt(kmax) | ||||
ipvt(kmax) = k | ||||
40 continue | ||||
c | ||||
c compute the householder transformation to reduce the | ||||
c j-th column of a to a multiple of the j-th unit vector. | ||||
c | ||||
ajnorm = enorm(m-j+1,a(j,j)) | ||||
c write(*,*) "ajnorm",ajnorm,a(j,j) | ||||
if (ajnorm .eq. zero) go to 100 | ||||
if (a(j,j) .lt. zero) ajnorm = -ajnorm | ||||
c write(*,*) "ajnorm",ajnorm | ||||
do 50 i = j, m | ||||
a(i,j) = a(i,j)/ajnorm | ||||
c if (j .eq. 13) then | ||||
c write(*,*) "a(12,13)",a(12,13) | ||||
c call exit | ||||
c end if | ||||
50 continue | ||||
a(j,j) = a(j,j) + one | ||||
c call exit | ||||
c | ||||
c apply the transformation to the remaining columns | ||||
c and update the norms. | ||||
c | ||||
jp1 = j + 1 | ||||
if (n .lt. jp1) go to 100 | ||||
do 90 k = jp1, n | ||||
sum = zero | ||||
do 60 i = j, m | ||||
sum = sum + a(i,j)*a(i,k) | ||||
60 continue | ||||
temp = sum/a(j,j) | ||||
do 70 i = j, m | ||||
a(i,k) = a(i,k) - temp*a(i,j) | ||||
70 continue | ||||
if (.not.pivot .or. rdiag(k) .eq. zero) go to 80 | ||||
temp = a(j,k)/rdiag(k) | ||||
rdiag(k) = rdiag(k)*sqrt(amax1(zero,one-temp**2)) | ||||
if (p05*(rdiag(k)/wa(k))**2 .gt. epsmch) go to 80 | ||||
rdiag(k) = enorm(m-j,a(jp1,k)) | ||||
wa(k) = rdiag(k) | ||||
80 continue | ||||
90 continue | ||||
100 continue | ||||
rdiag(j) = -ajnorm | ||||
110 continue | ||||
c write(*,*) "a_3",a(12,13) | ||||
c call exit | ||||
return | ||||
c | ||||
c last card of subroutine qrfac. | ||||
c | ||||
end | ||||
subroutine qrsolv(n,r,ldr,ipvt,diag,qtb,x,sdiag,wa) | ||||
integer n,ldr | ||||
integer ipvt(n) | ||||
real r(ldr,n),diag(n),qtb(n),x(n),sdiag(n),wa(n) | ||||
c ********** | ||||
c | ||||
c subroutine qrsolv | ||||
c | ||||
c given an m by n matrix a, an n by n diagonal matrix d, | ||||
c and an m-vector b, the problem is to determine an x which | ||||
c solves the system | ||||
c | ||||
c a*x = b , d*x = 0 , | ||||
c | ||||
c in the least squares sense. | ||||
c | ||||
c this subroutine completes the solution of the problem | ||||
c if it is provided with the necessary information from the | ||||
c qr factorization, with column pivoting, of a. that is, if | ||||
c a*p = q*r, where p is a permutation matrix, q has orthogonal | ||||
c columns, and r is an upper triangular matrix with diagonal | ||||
c elements of nonincreasing magnitude, then qrsolv expects | ||||
c the full upper triangle of r, the permutation matrix p, | ||||
c and the first n components of (q transpose)*b. the system | ||||
c a*x = b, d*x = 0, is then equivalent to | ||||
c | ||||
c t t | ||||
c r*z = q *b , p *d*p*z = 0 , | ||||
c | ||||
c where x = p*z. if this system does not have full rank, | ||||
c then a least squares solution is obtained. on output qrsolv | ||||
c also provides an upper triangular matrix s such that | ||||
c | ||||
c t t t | ||||
c p *(a *a + d*d)*p = s *s . | ||||
c | ||||
c s is computed within qrsolv and may be of separate interest. | ||||
c | ||||
c the subroutine statement is | ||||
c | ||||
c subroutine qrsolv(n,r,ldr,ipvt,diag,qtb,x,sdiag,wa) | ||||
c | ||||
c where | ||||
c | ||||
c n is a positive integer input variable set to the order of r. | ||||
c | ||||
c r is an n by n array. on input the full upper triangle | ||||
c must contain the full upper triangle of the matrix r. | ||||
c on output the full upper triangle is unaltered, and the | ||||
c strict lower triangle contains the strict upper triangle | ||||
c (transposed) of the upper triangular matrix s. | ||||
c | ||||
c ldr is a positive integer input variable not less than n | ||||
c which specifies the leading dimension of the array r. | ||||
c | ||||
c ipvt is an integer input array of length n which defines the | ||||
c permutation matrix p such that a*p = q*r. column j of p | ||||
c is column ipvt(j) of the identity matrix. | ||||
c | ||||
c diag is an input array of length n which must contain the | ||||
c diagonal elements of the matrix d. | ||||
c | ||||
c qtb is an input array of length n which must contain the first | ||||
c n elements of the vector (q transpose)*b. | ||||
c | ||||
c x is an output array of length n which contains the least | ||||
c squares solution of the system a*x = b, d*x = 0. | ||||
c | ||||
c sdiag is an output array of length n which contains the | ||||
c diagonal elements of the upper triangular matrix s. | ||||
c | ||||
c wa is a work array of length n. | ||||
c | ||||
c subprograms called | ||||
c | ||||
c fortran-supplied ... abs,sqrt | ||||
c | ||||
c argonne national laboratory. minpack project. march 1980. | ||||
c burton s. garbow, kenneth e. hillstrom, jorge j. more | ||||
c | ||||
c ********** | ||||
integer i,j,jp1,k,kp1,l,nsing | ||||
real cos,cotan,p5,p25,qtbpj,sin,sum,tan,temp,zero | ||||
data p5,p25,zero /5.0e-1,2.5e-1,0.0e0/ | ||||
c | ||||
c copy r and (q transpose)*b to preserve input and initialize s. | ||||
c in particular, save the diagonal elements of r in x. | ||||
c | ||||
do 20 j = 1, n | ||||
do 10 i = j, n | ||||
r(i,j) = r(j,i) | ||||
10 continue | ||||
x(j) = r(j,j) | ||||
wa(j) = qtb(j) | ||||
20 continue | ||||
c | ||||
c eliminate the diagonal matrix d using a givens rotation. | ||||
c | ||||
do 100 j = 1, n | ||||
c | ||||
c prepare the row of d to be eliminated, locating the | ||||
c diagonal element using p from the qr factorization. | ||||
c | ||||
l = ipvt(j) | ||||
if (diag(l) .eq. zero) go to 90 | ||||
do 30 k = j, n | ||||
sdiag(k) = zero | ||||
30 continue | ||||
sdiag(j) = diag(l) | ||||
c | ||||
c the transformations to eliminate the row of d | ||||
c modify only a single element of (q transpose)*b | ||||
c beyond the first n, which is initially zero. | ||||
c | ||||
qtbpj = zero | ||||
do 80 k = j, n | ||||
c | ||||
c determine a givens rotation which eliminates the | ||||
c appropriate element in the current row of d. | ||||
c | ||||
if (sdiag(k) .eq. zero) go to 70 | ||||
if (abs(r(k,k)) .ge. abs(sdiag(k))) go to 40 | ||||
cotan = r(k,k)/sdiag(k) | ||||
sin = p5/sqrt(p25+p25*cotan**2) | ||||
cos = sin*cotan | ||||
go to 50 | ||||
40 continue | ||||
tan = sdiag(k)/r(k,k) | ||||
cos = p5/sqrt(p25+p25*tan**2) | ||||
sin = cos*tan | ||||
50 continue | ||||
c | ||||
c compute the modified diagonal element of r and | ||||
c the modified element of ((q transpose)*b,0). | ||||
c | ||||
r(k,k) = cos*r(k,k) + sin*sdiag(k) | ||||
temp = cos*wa(k) + sin*qtbpj | ||||
qtbpj = -sin*wa(k) + cos*qtbpj | ||||
wa(k) = temp | ||||
c | ||||
c accumulate the tranformation in the row of s. | ||||
c | ||||
kp1 = k + 1 | ||||
if (n .lt. kp1) go to 70 | ||||
do 60 i = kp1, n | ||||
temp = cos*r(i,k) + sin*sdiag(i) | ||||
sdiag(i) = -sin*r(i,k) + cos*sdiag(i) | ||||
r(i,k) = temp | ||||
60 continue | ||||
70 continue | ||||
80 continue | ||||
90 continue | ||||
c | ||||
c store the diagonal element of s and restore | ||||
c the corresponding diagonal element of r. | ||||
c | ||||
sdiag(j) = r(j,j) | ||||
r(j,j) = x(j) | ||||
100 continue | ||||
c | ||||
c solve the triangular system for z. if the system is | ||||
c singular, then obtain a least squares solution. | ||||
c | ||||
nsing = n | ||||
do 110 j = 1, n | ||||
if (sdiag(j) .eq. zero .and. nsing .eq. n) nsing = j - 1 | ||||
if (nsing .lt. n) wa(j) = zero | ||||
110 continue | ||||
if (nsing .lt. 1) go to 150 | ||||
do 140 k = 1, nsing | ||||
j = nsing - k + 1 | ||||
sum = zero | ||||
jp1 = j + 1 | ||||
if (nsing .lt. jp1) go to 130 | ||||
do 120 i = jp1, nsing | ||||
sum = sum + r(i,j)*wa(i) | ||||
120 continue | ||||
130 continue | ||||
wa(j) = (wa(j) - sum)/sdiag(j) | ||||
140 continue | ||||
150 continue | ||||
c | ||||
c permute the components of z back to components of x. | ||||
c | ||||
do 160 j = 1, n | ||||
l = ipvt(j) | ||||
x(l) = wa(j) | ||||
160 continue | ||||
return | ||||
c | ||||
c last card of subroutine qrsolv. | ||||
c | ||||
end | ||||
real function spmpar(i) | ||||
integer i,j | ||||
if(i.eq.1) then | ||||
j=4 | ||||
else if(i.eq.2) then | ||||
j=1 | ||||
else if(i.eq.3) then | ||||
j=2 | ||||
else | ||||
stop | ||||
end if | ||||
spmpar=r1mach(j) | ||||
c write(*,*) spmpar,j | ||||
c call exit | ||||
return | ||||
end | ||||