subroutine destsv(n,r,ldr,svmin,z) integer ldr, n double precision svmin double precision r(ldr,n), z(n) c ********** c c Subroutine destsv c c Given an n by n upper triangular matrix R, this subroutine c estimates the smallest singular value and the associated c singular vector of R. c c In the algorithm a vector e is selected so that the solution c y to the system R'*y = e is large. The choice of sign for the c components of e cause maximal local growth in the components c of y as the forward substitution proceeds. The vector z is c the solution of the system R*z = y, and the estimate svmin c is norm(y)/norm(z) in the Euclidean norm. c c The subroutine statement is c c subroutine estsv(n,r,ldr,svmin,z) c c where c c n is an integer variable. c On entry n is the order of R. c On exit n is unchanged. c c r is a double precision array of dimension (ldr,n) c On entry the full upper triangle must contain the full c upper triangle of the matrix R. c On exit r is unchanged. c c ldr is an integer variable. c On entry ldr is the leading dimension of r. c On exit ldr is unchanged. c c svmin is a double precision variable. c On entry svmin need not be specified. c On exit svmin contains an estimate for the smallest c singular value of R. c c z is a double precision array of dimension n. c On entry z need not be specified. c On exit z contains a singular vector associated with the c estimate svmin such that norm(R*z) = svmin and c norm(z) = 1 in the Euclidean norm. c c Subprograms called c c Level 1 BLAS ... dasum, daxpy, dnrm2, dscal c c MINPACK-2 Project. October 1993. c Argonne National Laboratory c Brett M. Averick and Jorge J. More'. c c ********** double precision one, p01, zero parameter (zero=0.d0,p01=1.0d-2,one=1.0d0) integer i, j double precision e, s, sm, temp, w, wm, ynorm, znorm double precision dasum, dnrm2 external dasum, daxpy, dnrm2, dscal do 10 i = 1, n z(i) = zero 10 continue c This choice of e makes the algorithm scale invariant. e = abs(r(1,1)) if (e .eq. zero) then svmin = zero z(1) = one return end if c Solve R'*y = e. do 30 i = 1, n e = sign(e,-z(i)) c Scale y. The factor of 0.01 reduces the number of scalings. if (abs(e-z(i)) .gt. abs(r(i,i))) then temp = min(p01,abs(r(i,i))/abs(e-z(i))) call dscal(n,temp,z,1) e = temp*e end if c Determine the two possible choices of y(i). if (r(i,i) .eq. zero) then w = one wm = one else w = (e-z(i))/r(i,i) wm = -(e+z(i))/r(i,i) end if c Choose y(i) based on the predicted value of y(j) for j > i. s = abs(e-z(i)) sm = abs(e+z(i)) do 20 j = i + 1, n sm = sm + abs(z(j)+wm*r(i,j)) 20 continue if (i .lt. n) then call daxpy(n-i,w,r(i,i+1),ldr,z(i+1),1) s = s + dasum(n-i,z(i+1),1) end if if (s .lt. sm) then temp = wm - w w = wm if (i .lt. n) call daxpy(n-i,temp,r(i,i+1),ldr,z(i+1),1) end if z(i) = w 30 continue ynorm = dnrm2(n,z,1) c Solve R*z = y. do 40 j = n, 1, -1 c Scale z. if (abs(z(j)) .gt. abs(r(j,j))) then temp = min(p01,abs(r(j,j))/abs(z(j))) call dscal(n,temp,z,1) ynorm = temp*ynorm end if if (r(j,j) .eq. zero) then z(j) = one else z(j) = z(j)/r(j,j) end if temp = -z(j) call daxpy(j-1,temp,r(1,j),1,z,1) 40 continue c Compute svmin and normalize z. znorm = one/dnrm2(n,z,1) svmin = ynorm*znorm call dscal(n,znorm,z,1) end