subroutine imtqlv(n,d,e,e2,w,ind,ierr,rv1) c integer i,j,k,l,m,n,tag,ierr real d(n),e(n),e2(n),w(n),rv1(n) real b,c,f,g,p,r,s,tst1,tst2 integer ind(n) c c this subroutine is a variant of imtql1 which is a translation of c algol procedure imtql1, num. math. 12, 377-383(1968) by martin and c wilkinson, as modified in num. math. 15, 450(1970) by dubrulle. c handbook for auto. comp., vol.ii-linear algebra, 241-248(1971). c c this subroutine finds the eigenvalues of a symmetric tridiagonal c matrix by the implicit ql method and associates with them c their corresponding submatrix indices. c c on input c c n is the order of the matrix. c c d contains the diagonal elements of the input matrix. c c e contains the subdiagonal elements of the input matrix c in its last n-1 positions. e(1) is arbitrary. c c e2 contains the squares of the corresponding elements of e. c e2(1) is arbitrary. c c on output c c d and e are unaltered. c c elements of e2, corresponding to elements of e regarded c as negligible, have been replaced by zero causing the c matrix to split into a direct sum of submatrices. c e2(1) is also set to zero. c c w contains the eigenvalues in ascending order. if an c error exit is made, the eigenvalues are correct and c ordered for indices 1,2,...ierr-1, but may not be c the smallest eigenvalues. c c ind contains the submatrix indices associated with the c corresponding eigenvalues in w -- 1 for eigenvalues c belonging to the first submatrix from the top, c 2 for those belonging to the second submatrix, etc.. c c ierr is set to c zero for normal return, c j if the j-th eigenvalue has not been c determined after 30 iterations. c c rv1 is a temporary storage array. c c Questions and comments should be directed to Alan K. Cline, c Pleasant Valley Software, 8603 Altus Cove, Austin, TX 78759. c Electronic mail to cline@cs.utexas.edu. c c this version dated january 1989. (for the IBM 3090vf) c c ------------------------------------------------------------------ c call xuflow(0) ierr = 0 k = 0 tag = 0 c do 100 i = 1, n w(i) = d(i) if (i .ne. 1) rv1(i-1) = e(i) 100 continue c e2(1) = 0.0e0 rv1(n) = 0.0e0 c do 290 l = 1, n j = 0 c .......... look for small sub-diagonal element .......... 105 do 110 m = l, n-1 tst1 = abs(w(m)) + abs(w(m+1)) tst2 = tst1 + abs(rv1(m)) if (tst2 .eq. tst1) go to 120 c .......... guard against underflowed element of e2 .......... if (e2(m+1) .eq. 0.0e0) go to 125 110 continue c 120 if (m .le. k) go to 130 if (m .ne. n) e2(m+1) = 0.0e0 125 k = m tag = tag + 1 130 p = w(l) if (m .eq. l) go to 215 if (j .eq. 30) go to 1000 j = j + 1 c .......... form shift .......... g = (w(l+1) - p) / (2.0e0 * rv1(l)) cccccccccccccccccccccccccccccccccccccccccccccccccccc c * r = pythag(g,1.0d0) cccccccccccccccccccccccccccccccccccccccccccccccccccc if (abs(g).le.1.0e0) then r = sqrt(1.0e0 + g*g) else r = g * sqrt(1.0e0 + (1.0e0/g)**2) endif cccccccccccccccccccccccccccccccccccccccccccccccccccc g = w(m) - p + rv1(l) / (g + sign(r,g)) s = 1.0e0 c = 1.0e0 p = 0.0e0 c .......... for i=m-1 step -1 until l do -- .......... do 200 i = m-1, l, -1 f = s * rv1(i) b = c * rv1(i) cccccccccccccccccccccccccccccccccccccccccccccccccccc c * r = pythag(f,g) cccccccccccccccccccccccccccccccccccccccccccccccccccc if (abs(f).ge.abs(g)) then r = abs(f) * sqrt(1.0e0 + (g/f)**2) else if (g .ne. 0.0e0) then r = abs(g) * sqrt((f/g)**2 + 1.0e0) else r = abs(f) endif cccccccccccccccccccccccccccccccccccccccccccccccccccc rv1(i+1) = r if (r .eq. 0.0e0) then c .......... recover from underflow .......... d(i+1) = d(i+1) - p e(m) = 0.0e0 go to 105 endif s = f / r c = g / r g = w(i+1) - p r = (w(i) - g) * s + 2.0e0 * c * b p = s * r w(i+1) = g + p g = c * r - b 200 continue c w(l) = w(l) - p rv1(l) = g rv1(m) = 0.0e0 go to 105 c .......... order eigenvalues .......... c .......... for i=l step -1 until 2 do -- .......... 215 do 230 i = l, 2, -1 if (p .ge. w(i-1)) go to 270 w(i) = w(i-1) ind(i) = ind(i-1) 230 continue c i = 1 270 w(i) = p ind(i) = tag 290 continue c go to 1001 c .......... set error -- no convergence to an c eigenvalue after 30 iterations .......... 1000 ierr = l 1001 return end