c *** all eispack routines needed for real sym double precision *** c c subroutine rs(nm,n,a,w,matz,z,fv1,fv2,ierr) c integer n,nm,ierr,matz double precision a(nm,n),w(n),z(nm,n),fv1(n),fv2(n) c c this subroutine calls the recommended sequence of c subroutines from the eigensystem subroutine package (eispack) c to find the eigenvalues and eigenvectors (if desired) c of a real symmetric matrix. c c on input c c nm must be set to the row dimension of the two-dimensional c array parameters as declared in the calling program c dimension statement. c c n is the order of the matrix a. c c a contains the real symmetric matrix. c c matz is an integer variable set equal to zero if c only eigenvalues are desired. otherwise it is set to c any non-zero integer for both eigenvalues and eigenvectors. c c on output c c w contains the eigenvalues in ascending order. c c z contains the eigenvectors if matz is not zero. c c ierr is an integer output variable set equal to an error c completion code described in the documentation for tqlrat c and tql2. the normal completion code is zero. c c fv1 and fv2 are temporary storage arrays. c c questions and comments should be directed to burton s. garbow, c mathematics and computer science div, argonne national laboratory c c this version dated august 1983. c c ------------------------------------------------------------------ c if (n .le. nm) go to 10 ierr = 10 * n go to 50 c 10 if (matz .ne. 0) go to 20 c .......... find eigenvalues only .......... call tred1(nm,n,a,w,fv1,fv2) * tqlrat encounters catastrophic underflow on the Vax * call tqlrat(n,w,fv2,ierr) call tql1(n,w,fv1,ierr) go to 50 c .......... find both eigenvalues and eigenvectors .......... 20 call tred2(nm,n,a,w,fv1,z) call tql2(nm,n,w,fv1,z,ierr) 50 return end c c c subroutine bisect(n,eps1,d,e,e2,lb,ub,mm,m,w,ind,ierr,rv4,rv5) c integer i,j,k,l,m,n,p,q,r,s,ii,mm,m1,m2,tag,ierr,isturm double precision d(n),e(n),e2(n),w(mm),rv4(n),rv5(n) double precision u,v,lb,t1,t2,ub,xu,x0,x1,eps1,tst1,tst2,epslon integer ind(mm) c c this subroutine is a translation of the bisection technique c in the algol procedure tristurm by peters and wilkinson. c handbook for auto. comp., vol.ii-linear algebra, 418-439(1971). c c this subroutine finds those eigenvalues of a tridiagonal c symmetric matrix which lie in a specified interval, c using bisection. c c on input c c n is the order of the matrix. c c eps1 is an absolute error tolerance for the computed c eigenvalues. if the input eps1 is non-positive, c it is reset for each submatrix to a default value, c namely, minus the product of the relative machine c precision and the 1-norm of the submatrix. 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 lb and ub define the interval to be searched for eigenvalues. c if lb is not less than ub, no eigenvalues will be found. c c mm should be set to an upper bound for the number of c eigenvalues in the interval. warning. if more than c mm eigenvalues are determined to lie in the interval, c an error return is made with no eigenvalues found. c c on output c c eps1 is unaltered unless it has been reset to its c (last) default value. 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 m is the number of eigenvalues determined to lie in (lb,ub). c c w contains the m eigenvalues in ascending order. c c ind contains in its first m positions the submatrix indices c associated with the corresponding eigenvalues in w -- c 1 for eigenvalues belonging to the first submatrix from c the top, 2 for those belonging to the second submatrix, etc.. c c ierr is set to c zero for normal return, c 3*n+1 if m exceeds mm. c c rv4 and rv5 are temporary storage arrays. c c the algol procedure sturmcnt contained in tristurm c appears in bisect in-line. c c note that subroutine tql1 or imtql1 is generally faster than c bisect, if more than n/4 eigenvalues are to be found. c c questions and comments should be directed to burton s. garbow, c mathematics and computer science div, argonne national laboratory c c this version dated august 1983. c c ------------------------------------------------------------------ c ierr = 0 tag = 0 t1 = lb t2 = ub c .......... look for small sub-diagonal entries .......... do 40 i = 1, n if (i .eq. 1) go to 20 tst1 = dabs(d(i)) + dabs(d(i-1)) tst2 = tst1 + dabs(e(i)) if (tst2 .gt. tst1) go to 40 20 e2(i) = 0.0d0 40 continue c .......... determine the number of eigenvalues c in the interval .......... p = 1 q = n x1 = ub isturm = 1 go to 320 60 m = s x1 = lb isturm = 2 go to 320 80 m = m - s if (m .gt. mm) go to 980 q = 0 r = 0 c .......... establish and process next submatrix, refining c interval by the gerschgorin bounds .......... 100 if (r .eq. m) go to 1001 tag = tag + 1 p = q + 1 xu = d(p) x0 = d(p) u = 0.0d0 c do 120 q = p, n x1 = u u = 0.0d0 v = 0.0d0 if (q .eq. n) go to 110 u = dabs(e(q+1)) v = e2(q+1) 110 xu = dmin1(d(q)-(x1+u),xu) x0 = dmax1(d(q)+(x1+u),x0) if (v .eq. 0.0d0) go to 140 120 continue c 140 x1 = epslon(dmax1(dabs(xu),dabs(x0))) if (eps1 .le. 0.0d0) eps1 = -x1 if (p .ne. q) go to 180 c .......... check for isolated root within interval .......... if (t1 .gt. d(p) .or. d(p) .ge. t2) go to 940 m1 = p m2 = p rv5(p) = d(p) go to 900 180 x1 = x1 * (q - p + 1) lb = dmax1(t1,xu-x1) ub = dmin1(t2,x0+x1) x1 = lb isturm = 3 go to 320 200 m1 = s + 1 x1 = ub isturm = 4 go to 320 220 m2 = s if (m1 .gt. m2) go to 940 c .......... find roots by bisection .......... x0 = ub isturm = 5 c do 240 i = m1, m2 rv5(i) = ub rv4(i) = lb 240 continue c .......... loop for k-th eigenvalue c for k=m2 step -1 until m1 do -- c (-do- not used to legalize -computed go to-) .......... k = m2 250 xu = lb c .......... for i=k step -1 until m1 do -- .......... do 260 ii = m1, k i = m1 + k - ii if (xu .ge. rv4(i)) go to 260 xu = rv4(i) go to 280 260 continue c 280 if (x0 .gt. rv5(k)) x0 = rv5(k) c .......... next bisection step .......... 300 x1 = (xu + x0) * 0.5d0 if ((x0 - xu) .le. dabs(eps1)) go to 420 tst1 = 2.0d0 * (dabs(xu) + dabs(x0)) tst2 = tst1 + (x0 - xu) if (tst2 .eq. tst1) go to 420 c .......... in-line procedure for sturm sequence .......... 320 s = p - 1 u = 1.0d0 c do 340 i = p, q if (u .ne. 0.0d0) go to 325 v = dabs(e(i)) / epslon(1.0d0) if (e2(i) .eq. 0.0d0) v = 0.0d0 go to 330 325 v = e2(i) / u 330 u = d(i) - x1 - v if (u .lt. 0.0d0) s = s + 1 340 continue c go to (60,80,200,220,360), isturm c .......... refine intervals .......... 360 if (s .ge. k) go to 400 xu = x1 if (s .ge. m1) go to 380 rv4(m1) = x1 go to 300 380 rv4(s+1) = x1 if (rv5(s) .gt. x1) rv5(s) = x1 go to 300 400 x0 = x1 go to 300 c .......... k-th eigenvalue found .......... 420 rv5(k) = x1 k = k - 1 if (k .ge. m1) go to 250 c .......... order eigenvalues tagged with their c submatrix associations .......... 900 s = r r = r + m2 - m1 + 1 j = 1 k = m1 c do 920 l = 1, r if (j .gt. s) go to 910 if (k .gt. m2) go to 940 if (rv5(k) .ge. w(l)) go to 915 c do 905 ii = j, s i = l + s - ii w(i+1) = w(i) ind(i+1) = ind(i) 905 continue c 910 w(l) = rv5(k) ind(l) = tag k = k + 1 go to 920 915 j = j + 1 920 continue c 940 if (q .lt. n) go to 100 go to 1001 c .......... set error -- underestimate of number of c eigenvalues in interval .......... 980 ierr = 3 * n + 1 1001 lb = t1 ub = t2 return end c c c double precision function epslon (x) double precision x c c estimate unit roundoff in quantities of size x. c double precision a,b,c,eps c c this program should function properly on all systems c satisfying the following two assumptions, c 1. the base used in representing floating point c numbers is not a power of three. c 2. the quantity a in statement 10 is represented to c the accuracy used in floating point variables c that are stored in memory. c the statement number 10 and the go to 10 are intended to c force optimizing compilers to generate code satisfying c assumption 2. c under these assumptions, it should be true that, c a is not exactly equal to four-thirds, c b has a zero for its last bit or digit, c c is not exactly equal to one, c eps measures the separation of 1.0 from c the next larger floating point number. c the developers of eispack would appreciate being informed c about any systems where these assumptions do not hold. c c this version dated 4/6/83. c a = 4.0d0/3.0d0 10 b = a - 1.0d0 c = b + b + b eps = dabs(c-1.0d0) if (eps .eq. 0.0d0) go to 10 epslon = eps*dabs(x) return end c c c subroutine imtql1(n,d,e,ierr) c integer i,j,l,m,n,ii,mml,ierr double precision d(n),e(n) double precision b,c,f,g,p,r,s,tst1,tst2,pythag c c this subroutine is a translation of the algol procedure imtql1, c num. math. 12, 377-383(1968) by martin and wilkinson, c 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 c tridiagonal matrix by the implicit ql method. 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 on output c c d 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 e has been destroyed. 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 calls pythag for dsqrt(a*a + b*b) . c c questions and comments should be directed to burton s. garbow, c mathematics and computer science div, argonne national laboratory c c this version dated august 1983. c c ------------------------------------------------------------------ c ierr = 0 if (n .eq. 1) go to 1001 c do 100 i = 2, n 100 e(i-1) = e(i) c e(n) = 0.0d0 c do 290 l = 1, n j = 0 c .......... look for small sub-diagonal element .......... 105 do 110 m = l, n if (m .eq. n) go to 120 tst1 = dabs(d(m)) + dabs(d(m+1)) tst2 = tst1 + dabs(e(m)) if (tst2 .eq. tst1) go to 120 110 continue c 120 p = d(l) if (m .eq. l) go to 215 if (j .eq. 30) go to 1000 j = j + 1 c .......... form shift .......... g = (d(l+1) - p) / (2.0d0 * e(l)) r = pythag(g,1.0d0) g = d(m) - p + e(l) / (g + dsign(r,g)) s = 1.0d0 c = 1.0d0 p = 0.0d0 mml = m - l c .......... for i=m-1 step -1 until l do -- .......... do 200 ii = 1, mml i = m - ii f = s * e(i) b = c * e(i) r = pythag(f,g) e(i+1) = r if (r .eq. 0.0d0) go to 210 s = f / r c = g / r g = d(i+1) - p r = (d(i) - g) * s + 2.0d0 * c * b p = s * r d(i+1) = g + p g = c * r - b 200 continue c d(l) = d(l) - p e(l) = g e(m) = 0.0d0 go to 105 c .......... recover from underflow .......... 210 d(i+1) = d(i+1) - p e(m) = 0.0d0 go to 105 c .......... order eigenvalues .......... 215 if (l .eq. 1) go to 250 c .......... for i=l step -1 until 2 do -- .......... do 230 ii = 2, l i = l + 2 - ii if (p .ge. d(i-1)) go to 270 d(i) = d(i-1) 230 continue c 250 i = 1 270 d(i) = p 290 continue c go to 1001 c .......... set error -- no convergence to an c eigenvalue after 30 iterations .......... 1000 ierr = l 1001 return end c c c subroutine imtql2(nm,n,d,e,z,ierr) c integer i,j,k,l,m,n,ii,nm,mml,ierr double precision d(n),e(n),z(nm,n) double precision b,c,f,g,p,r,s,tst1,tst2,pythag c c this subroutine is a translation of the algol procedure imtql2, c num. math. 12, 377-383(1968) by martin and wilkinson, c 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 and eigenvectors c of a symmetric tridiagonal matrix by the implicit ql method. c the eigenvectors of a full symmetric matrix can also c be found if tred2 has been used to reduce this c full matrix to tridiagonal form. c c on input c c nm must be set to the row dimension of two-dimensional c array parameters as declared in the calling program c dimension statement. 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 z contains the transformation matrix produced in the c reduction by tred2, if performed. if the eigenvectors c of the tridiagonal matrix are desired, z must contain c the identity matrix. c c on output c c d contains the eigenvalues in ascending order. if an c error exit is made, the eigenvalues are correct but c unordered for indices 1,2,...,ierr-1. c c e has been destroyed. c c z contains orthonormal eigenvectors of the symmetric c tridiagonal (or full) matrix. if an error exit is made, c z contains the eigenvectors associated with the stored c eigenvalues. 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 calls pythag for dsqrt(a*a + b*b) . c c questions and comments should be directed to burton s. garbow, c mathematics and computer science div, argonne national laboratory c c this version dated august 1983. c c ------------------------------------------------------------------ c ierr = 0 if (n .eq. 1) go to 1001 c do 100 i = 2, n 100 e(i-1) = e(i) c e(n) = 0.0d0 c do 240 l = 1, n j = 0 c .......... look for small sub-diagonal element .......... 105 do 110 m = l, n if (m .eq. n) go to 120 tst1 = dabs(d(m)) + dabs(d(m+1)) tst2 = tst1 + dabs(e(m)) if (tst2 .eq. tst1) go to 120 110 continue c 120 p = d(l) if (m .eq. l) go to 240 if (j .eq. 30) go to 1000 j = j + 1 c .......... form shift .......... g = (d(l+1) - p) / (2.0d0 * e(l)) r = pythag(g,1.0d0) g = d(m) - p + e(l) / (g + dsign(r,g)) s = 1.0d0 c = 1.0d0 p = 0.0d0 mml = m - l c .......... for i=m-1 step -1 until l do -- .......... do 200 ii = 1, mml i = m - ii f = s * e(i) b = c * e(i) r = pythag(f,g) e(i+1) = r if (r .eq. 0.0d0) go to 210 s = f / r c = g / r g = d(i+1) - p r = (d(i) - g) * s + 2.0d0 * c * b p = s * r d(i+1) = g + p g = c * r - b c .......... form vector .......... do 180 k = 1, n f = z(k,i+1) z(k,i+1) = s * z(k,i) + c * f z(k,i) = c * z(k,i) - s * f 180 continue c 200 continue c d(l) = d(l) - p e(l) = g e(m) = 0.0d0 go to 105 c .......... recover from underflow .......... 210 d(i+1) = d(i+1) - p e(m) = 0.0d0 go to 105 240 continue c .......... order eigenvalues and eigenvectors .......... do 300 ii = 2, n i = ii - 1 k = i p = d(i) c do 260 j = ii, n if (d(j) .ge. p) go to 260 k = j p = d(j) 260 continue c if (k .eq. i) go to 300 d(k) = d(i) d(i) = p c do 280 j = 1, n p = z(j,i) z(j,i) = z(j,k) z(j,k) = p 280 continue c 300 continue c go to 1001 c .......... set error -- no convergence to an c eigenvalue after 30 iterations .......... 1000 ierr = l 1001 return end c c c subroutine imtqlv(n,d,e,e2,w,ind,ierr,rv1) c integer i,j,k,l,m,n,ii,mml,tag,ierr double precision d(n),e(n),e2(n),w(n),rv1(n) double precision b,c,f,g,p,r,s,tst1,tst2,pythag 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 calls pythag for dsqrt(a*a + b*b) . c c questions and comments should be directed to burton s. garbow, c mathematics and computer science div, argonne national laboratory c c this version dated august 1983. c c ------------------------------------------------------------------ c 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.0d0 rv1(n) = 0.0d0 c do 290 l = 1, n j = 0 c .......... look for small sub-diagonal element .......... 105 do 110 m = l, n if (m .eq. n) go to 120 tst1 = dabs(w(m)) + dabs(w(m+1)) tst2 = tst1 + dabs(rv1(m)) if (tst2 .eq. tst1) go to 120 c .......... guard against underflowed element of e2 .......... if (e2(m+1) .eq. 0.0d0) go to 125 110 continue c 120 if (m .le. k) go to 130 if (m .ne. n) e2(m+1) = 0.0d0 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.0d0 * rv1(l)) r = pythag(g,1.0d0) g = w(m) - p + rv1(l) / (g + dsign(r,g)) s = 1.0d0 c = 1.0d0 p = 0.0d0 mml = m - l c .......... for i=m-1 step -1 until l do -- .......... do 200 ii = 1, mml i = m - ii f = s * rv1(i) b = c * rv1(i) r = pythag(f,g) rv1(i+1) = r if (r .eq. 0.0d0) go to 210 s = f / r c = g / r g = w(i+1) - p r = (w(i) - g) * s + 2.0d0 * 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.0d0 go to 105 c .......... recover from underflow .......... 210 w(i+1) = w(i+1) - p rv1(m) = 0.0d0 go to 105 c .......... order eigenvalues .......... 215 if (l .eq. 1) go to 250 c .......... for i=l step -1 until 2 do -- .......... do 230 ii = 2, l i = l + 2 - ii if (p .ge. w(i-1)) go to 270 w(i) = w(i-1) ind(i) = ind(i-1) 230 continue c 250 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 c c c double precision function pythag(a,b) double precision a,b c c finds dsqrt(a**2+b**2) without overflow or destructive underflow c double precision p,r,s,t,u p = dmax1(dabs(a),dabs(b)) if (p .eq. 0.0d0) go to 20 r = (dmin1(dabs(a),dabs(b))/p)**2 10 continue t = 4.0d0 + r if (t .eq. 4.0d0) go to 20 s = r/t u = 1.0d0 + 2.0d0*s p = u*p r = (s/u)**2 * r go to 10 20 pythag = p return end c c c SUBROUTINE RSWZR(NM,N,M,A,W,Z,NORM,RESDUL) C REAL NORM(M),W(M),A(NM,N),Z(NM,M),NORMA,TNORM,S,SUM, X SUMZ, SUMA, RESDUL C C THIS SUBROUTINE FORMS THE 1-NORM OF THE RESIDUAL MATRIX C A*Z-Z*DIAG(W) WHERE A IS A REAL SYMMETRIC MATRIX, W IS C A VECTOR WHICH CONTAINS M EIGENVALUES OF A, AND Z C IS AN ARRAY WHICH CONTAINS THE M CORRESPONDING EIGENVECTORS OF C OF A. ALL NORMS APPEARING IN THE COMMENTS BELOW ARE 1-NORMS. C C THIS SUBROUTINE IS CATALOGUED AS EISPDRV4(RSWZR). C C INPUT. C C NM IS THE ROW DIMENSION OF TWO-DIMENSIONAL ARRAY PARAMETERS C AS DECLARED IN THE CALLING PROGRAM DIMENSION STATEMENT; C C M IS THE NUMBER OF EIGENVECTORS FOR WHICH RESIDUALS ARE C DESIRED; C C N IS THE ORDER OF THE MATRIX A; C C A(NM,N) IS A REAL SYMMETRIC MATRIX. ONLY THE FULL UPPER C TRIANGLE NEED BE SUPPLIED; C C Z(NM,M) IS A REAL MATRIX WHOSE FIRST M COLUMNS CONTAIN THE C APPROXIMATE EIGENVECTORS OF A; C C W(M) IS A VECTOR WHOSE FIRST M COMPONENTS CONTAIN THE C APPROXIMATE EIGENVALUES OF A. W(I) IS ASSOCIATED WITH THE C I-TH COLUMN OF Z. C C OUTPUT. C C Z(NM,M) IS AN ARRAY WHICH CONTAINS M NORMALIZED C APPROXIMATE EIGENVECTORS OF A. THE EIGENVECTORS ARE C NORMALIZED USING THE 1-NORM IN SUCH A WAY THAT THE FIRST C ELEMENT WHOSE MAGNITUDE IS LARGER THAN THE NORM OF THE C EIGENVECTOR DIVIDED BY N IS POSITIVE; C C A(NM,N) IS ALTERED BY MAKING THE LOWER TRIANGLE OF A C SYMMETRIC WITH THE UPPER TRIANGLE OF A; C C NORM(M) IS AN ARRAY SUCH THAT FOR EACH K, C NORM(K) = !!A*Z(K)-Z(K)*W(K)!!/(!!A!!*!!Z(K)!!) C WHERE Z(K) IS THE K-TH EIGENVECTOR; C C RESDUL IS THE REAL NUMBER C !!A*Z-Z*DIAG(W)!!/(!!A!!*!!Z!!). C C ---------------------------------------------------------------- C RESDUL = 0.0E0 IF( M .EQ. 0 ) RETURN NORMA = 0.0E0 C DO 40 I=1,N SUMA = 0.0E0 IF(I .EQ. 1) GO TO 20 C DO 10 L=2,I A(I,L-1) = A(L-1,I) 10 CONTINUE C 20 DO 30 L=1,N 30 SUMA = SUMA + ABS(A(I,L)) C 40 NORMA = AMAX1(NORMA,SUMA) C IF(NORMA .EQ. 0.0E0) NORMA = 1.0E0 C DO 100 I=1,M S = 0.0E0 SUMZ = 0.0E0 C DO 60 L=1,N SUMZ = SUMZ + ABS(Z(L,I)) SUM = -W(I)*Z(L,I) C DO 50 K=1,N 50 SUM = SUM + A(L,K)*Z(K,I) C 60 S = S + ABS(SUM) C NORM(I) = SUMZ IF( SUMZ .EQ. 0.0E0 ) GO TO 100 C ..........THIS LOOP WILL NEVER BE COMPLETED SINCE THERE C WILL ALWAYS EXIST AN ELEMENT IN THE VECTOR Z(I) C LARGER THAN !!Z(I)!!/N.......... DO 70 L=1,N IF(ABS(Z(L,I)) .GE. NORM(I)/N) GO TO 80 70 CONTINUE C 80 TNORM = SIGN(NORM(I),Z(L,I)) C DO 90 L=1,N 90 Z(L,I) = Z(L,I)/TNORM C NORM(I) = S/(NORM(I)*NORMA) 100 RESDUL = AMAX1(NORM(I), RESDUL) C RETURN END c c c subroutine tinvit(nm,n,d,e,e2,m,w,ind,z, x ierr,rv1,rv2,rv3,rv4,rv6) c integer i,j,m,n,p,q,r,s,ii,ip,jj,nm,its,tag,ierr,group double precision d(n),e(n),e2(n),w(m),z(nm,m), x rv1(n),rv2(n),rv3(n),rv4(n),rv6(n) double precision u,v,uk,xu,x0,x1,eps2,eps3,eps4,norm,order,epslon, x pythag integer ind(m) c c this subroutine is a translation of the inverse iteration tech- c nique in the algol procedure tristurm by peters and wilkinson. c handbook for auto. comp., vol.ii-linear algebra, 418-439(1971). c c this subroutine finds those eigenvectors of a tridiagonal c symmetric matrix corresponding to specified eigenvalues, c using inverse iteration. c c on input c c nm must be set to the row dimension of two-dimensional c array parameters as declared in the calling program c dimension statement. 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 with zeros corresponding to negligible elements of e. c e(i) is considered negligible if it is not larger than c the product of the relative machine precision and the sum c of the magnitudes of d(i) and d(i-1). e2(1) must contain c 0.0d0 if the eigenvalues are in ascending order, or 2.0d0 c if the eigenvalues are in descending order. if bisect, c tridib, or imtqlv has been used to find the eigenvalues, c their output e2 array is exactly what is expected here. c c m is the number of specified eigenvalues. c c w contains the m eigenvalues in ascending or descending order. c c ind contains in its first m positions the submatrix indices c associated with the corresponding eigenvalues in w -- c 1 for eigenvalues belonging to the first submatrix from c the top, 2 for those belonging to the second submatrix, etc. c c on output c c all input arrays are unaltered. c c z contains the associated set of orthonormal eigenvectors. c any vector which fails to converge is set to zero. c c ierr is set to c zero for normal return, c -r if the eigenvector corresponding to the r-th c eigenvalue fails to converge in 5 iterations. c c rv1, rv2, rv3, rv4, and rv6 are temporary storage arrays. c c calls pythag for dsqrt(a*a + b*b) . c c questions and comments should be directed to burton s. garbow, c mathematics and computer science div, argonne national laboratory c c this version dated august 1983. c c ------------------------------------------------------------------ c ierr = 0 if (m .eq. 0) go to 1001 tag = 0 order = 1.0d0 - e2(1) q = 0 c .......... establish and process next submatrix .......... 100 p = q + 1 c do 120 q = p, n if (q .eq. n) go to 140 if (e2(q+1) .eq. 0.0d0) go to 140 120 continue c .......... find vectors by inverse iteration .......... 140 tag = tag + 1 s = 0 c do 920 r = 1, m if (ind(r) .ne. tag) go to 920 its = 1 x1 = w(r) if (s .ne. 0) go to 510 c .......... check for isolated root .......... xu = 1.0d0 if (p .ne. q) go to 490 rv6(p) = 1.0d0 go to 870 490 norm = dabs(d(p)) ip = p + 1 c do 500 i = ip, q 500 norm = dmax1(norm, dabs(d(i))+dabs(e(i))) c .......... eps2 is the criterion for grouping, c eps3 replaces zero pivots and equal c roots are modified by eps3, c eps4 is taken very small to avoid overflow .......... eps2 = 1.0d-3 * norm eps3 = epslon(norm) uk = q - p + 1 eps4 = uk * eps3 uk = eps4 / dsqrt(uk) s = p 505 group = 0 go to 520 c .......... look for close or coincident roots .......... 510 if (dabs(x1-x0) .ge. eps2) go to 505 group = group + 1 if (order * (x1 - x0) .le. 0.0d0) x1 = x0 + order * eps3 c .......... elimination with interchanges and c initialization of vector .......... 520 v = 0.0d0 c do 580 i = p, q rv6(i) = uk if (i .eq. p) go to 560 if (dabs(e(i)) .lt. dabs(u)) go to 540 c .......... warning -- a divide check may occur here if c e2 array has not been specified correctly .......... xu = u / e(i) rv4(i) = xu rv1(i-1) = e(i) rv2(i-1) = d(i) - x1 rv3(i-1) = 0.0d0 if (i .ne. q) rv3(i-1) = e(i+1) u = v - xu * rv2(i-1) v = -xu * rv3(i-1) go to 580 540 xu = e(i) / u rv4(i) = xu rv1(i-1) = u rv2(i-1) = v rv3(i-1) = 0.0d0 560 u = d(i) - x1 - xu * v if (i .ne. q) v = e(i+1) 580 continue c if (u .eq. 0.0d0) u = eps3 rv1(q) = u rv2(q) = 0.0d0 rv3(q) = 0.0d0 c .......... back substitution c for i=q step -1 until p do -- .......... 600 do 620 ii = p, q i = p + q - ii rv6(i) = (rv6(i) - u * rv2(i) - v * rv3(i)) / rv1(i) v = u u = rv6(i) 620 continue c .......... orthogonalize with respect to previous c members of group .......... if (group .eq. 0) go to 700 j = r c do 680 jj = 1, group 630 j = j - 1 if (ind(j) .ne. tag) go to 630 xu = 0.0d0 c do 640 i = p, q 640 xu = xu + rv6(i) * z(i,j) c do 660 i = p, q 660 rv6(i) = rv6(i) - xu * z(i,j) c 680 continue c 700 norm = 0.0d0 c do 720 i = p, q 720 norm = norm + dabs(rv6(i)) c if (norm .ge. 1.0d0) go to 840 c .......... forward substitution .......... if (its .eq. 5) go to 830 if (norm .ne. 0.0d0) go to 740 rv6(s) = eps4 s = s + 1 if (s .gt. q) s = p go to 780 740 xu = eps4 / norm c do 760 i = p, q 760 rv6(i) = rv6(i) * xu c .......... elimination operations on next vector c iterate .......... 780 do 820 i = ip, q u = rv6(i) c .......... if rv1(i-1) .eq. e(i), a row interchange c was performed earlier in the c triangularization process .......... if (rv1(i-1) .ne. e(i)) go to 800 u = rv6(i-1) rv6(i-1) = rv6(i) 800 rv6(i) = u - rv4(i) * rv6(i-1) 820 continue c its = its + 1 go to 600 c .......... set error -- non-converged eigenvector .......... 830 ierr = -r xu = 0.0d0 go to 870 c .......... normalize so that sum of squares is c 1 and expand to full order .......... 840 u = 0.0d0 c do 860 i = p, q 860 u = pythag(u,rv6(i)) c xu = 1.0d0 / u c 870 do 880 i = 1, n 880 z(i,r) = 0.0d0 c do 900 i = p, q 900 z(i,r) = rv6(i) * xu c x0 = x1 920 continue c if (q .lt. n) go to 100 1001 return end c c c subroutine tql1(n,d,e,ierr) c integer i,j,l,m,n,ii,l1,l2,mml,ierr double precision d(n),e(n) double precision c,c2,c3,dl1,el1,f,g,h,p,r,s,s2,tst1,tst2,pythag c c this subroutine is a translation of the algol procedure tql1, c num. math. 11, 293-306(1968) by bowdler, martin, reinsch, and c wilkinson. c handbook for auto. comp., vol.ii-linear algebra, 227-240(1971). c c this subroutine finds the eigenvalues of a symmetric c tridiagonal matrix by the ql method. 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 on output c c d 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 e has been destroyed. 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 calls pythag for dsqrt(a*a + b*b) . c c questions and comments should be directed to burton s. garbow, c mathematics and computer science div, argonne national laboratory c c this version dated august 1983. c c ------------------------------------------------------------------ c ierr = 0 if (n .eq. 1) go to 1001 c do 100 i = 2, n 100 e(i-1) = e(i) c f = 0.0d0 tst1 = 0.0d0 e(n) = 0.0d0 c do 290 l = 1, n j = 0 h = dabs(d(l)) + dabs(e(l)) if (tst1 .lt. h) tst1 = h c .......... look for small sub-diagonal element .......... do 110 m = l, n tst2 = tst1 + dabs(e(m)) if (tst2 .eq. tst1) go to 120 c .......... e(n) is always zero, so there is no exit c through the bottom of the loop .......... 110 continue c 120 if (m .eq. l) go to 210 130 if (j .eq. 30) go to 1000 j = j + 1 c .......... form shift .......... l1 = l + 1 l2 = l1 + 1 g = d(l) p = (d(l1) - g) / (2.0d0 * e(l)) r = pythag(p,1.0d0) d(l) = e(l) / (p + dsign(r,p)) d(l1) = e(l) * (p + dsign(r,p)) dl1 = d(l1) h = g - d(l) if (l2 .gt. n) go to 145 c do 140 i = l2, n 140 d(i) = d(i) - h c 145 f = f + h c .......... ql transformation .......... p = d(m) c = 1.0d0 c2 = c el1 = e(l1) s = 0.0d0 mml = m - l c .......... for i=m-1 step -1 until l do -- .......... do 200 ii = 1, mml c3 = c2 c2 = c s2 = s i = m - ii g = c * e(i) h = c * p r = pythag(p,e(i)) e(i+1) = s * r s = e(i) / r c = p / r p = c * d(i) - s * g d(i+1) = h + s * (c * g + s * d(i)) 200 continue c p = -s * s2 * c3 * el1 * e(l) / dl1 e(l) = s * p d(l) = c * p tst2 = tst1 + dabs(e(l)) if (tst2 .gt. tst1) go to 130 210 p = d(l) + f c .......... order eigenvalues .......... if (l .eq. 1) go to 250 c .......... for i=l step -1 until 2 do -- .......... do 230 ii = 2, l i = l + 2 - ii if (p .ge. d(i-1)) go to 270 d(i) = d(i-1) 230 continue c 250 i = 1 270 d(i) = p 290 continue c go to 1001 c .......... set error -- no convergence to an c eigenvalue after 30 iterations .......... 1000 ierr = l 1001 return end c c c subroutine tql2(nm,n,d,e,z,ierr) c integer i,j,k,l,m,n,ii,l1,l2,nm,mml,ierr double precision d(n),e(n),z(nm,n) double precision c,c2,c3,dl1,el1,f,g,h,p,r,s,s2,tst1,tst2,pythag c c this subroutine is a translation of the algol procedure tql2, c num. math. 11, 293-306(1968) by bowdler, martin, reinsch, and c wilkinson. c handbook for auto. comp., vol.ii-linear algebra, 227-240(1971). c c this subroutine finds the eigenvalues and eigenvectors c of a symmetric tridiagonal matrix by the ql method. c the eigenvectors of a full symmetric matrix can also c be found if tred2 has been used to reduce this c full matrix to tridiagonal form. c c on input c c nm must be set to the row dimension of two-dimensional c array parameters as declared in the calling program c dimension statement. 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 z contains the transformation matrix produced in the c reduction by tred2, if performed. if the eigenvectors c of the tridiagonal matrix are desired, z must contain c the identity matrix. c c on output c c d contains the eigenvalues in ascending order. if an c error exit is made, the eigenvalues are correct but c unordered for indices 1,2,...,ierr-1. c c e has been destroyed. c c z contains orthonormal eigenvectors of the symmetric c tridiagonal (or full) matrix. if an error exit is made, c z contains the eigenvectors associated with the stored c eigenvalues. 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 calls pythag for dsqrt(a*a + b*b) . c c questions and comments should be directed to burton s. garbow, c mathematics and computer science div, argonne national laboratory c c this version dated august 1983. c c ------------------------------------------------------------------ c ierr = 0 if (n .eq. 1) go to 1001 c do 100 i = 2, n 100 e(i-1) = e(i) c f = 0.0d0 tst1 = 0.0d0 e(n) = 0.0d0 c do 240 l = 1, n j = 0 h = dabs(d(l)) + dabs(e(l)) if (tst1 .lt. h) tst1 = h c .......... look for small sub-diagonal element .......... do 110 m = l, n tst2 = tst1 + dabs(e(m)) if (tst2 .eq. tst1) go to 120 c .......... e(n) is always zero, so there is no exit c through the bottom of the loop .......... 110 continue c 120 if (m .eq. l) go to 220 130 if (j .eq. 30) go to 1000 j = j + 1 c .......... form shift .......... l1 = l + 1 l2 = l1 + 1 g = d(l) p = (d(l1) - g) / (2.0d0 * e(l)) r = pythag(p,1.0d0) d(l) = e(l) / (p + dsign(r,p)) d(l1) = e(l) * (p + dsign(r,p)) dl1 = d(l1) h = g - d(l) if (l2 .gt. n) go to 145 c do 140 i = l2, n 140 d(i) = d(i) - h c 145 f = f + h c .......... ql transformation .......... p = d(m) c = 1.0d0 c2 = c el1 = e(l1) s = 0.0d0 mml = m - l c .......... for i=m-1 step -1 until l do -- .......... do 200 ii = 1, mml c3 = c2 c2 = c s2 = s i = m - ii g = c * e(i) h = c * p r = pythag(p,e(i)) e(i+1) = s * r s = e(i) / r c = p / r p = c * d(i) - s * g d(i+1) = h + s * (c * g + s * d(i)) c .......... form vector .......... do 180 k = 1, n h = z(k,i+1) z(k,i+1) = s * z(k,i) + c * h z(k,i) = c * z(k,i) - s * h 180 continue c 200 continue c p = -s * s2 * c3 * el1 * e(l) / dl1 e(l) = s * p d(l) = c * p tst2 = tst1 + dabs(e(l)) if (tst2 .gt. tst1) go to 130 220 d(l) = d(l) + f 240 continue c .......... order eigenvalues and eigenvectors .......... do 300 ii = 2, n i = ii - 1 k = i p = d(i) c do 260 j = ii, n if (d(j) .ge. p) go to 260 k = j p = d(j) 260 continue c if (k .eq. i) go to 300 d(k) = d(i) d(i) = p c do 280 j = 1, n p = z(j,i) z(j,i) = z(j,k) z(j,k) = p 280 continue c 300 continue c go to 1001 c .......... set error -- no convergence to an c eigenvalue after 30 iterations .......... 1000 ierr = l 1001 return end c c c subroutine trbak1(nm,n,a,e,m,z) c integer i,j,k,l,m,n,nm double precision a(nm,n),e(n),z(nm,m) double precision s c c this subroutine is a translation of the algol procedure trbak1, c num. math. 11, 181-195(1968) by martin, reinsch, and wilkinson. c handbook for auto. comp., vol.ii-linear algebra, 212-226(1971). c c this subroutine forms the eigenvectors of a real symmetric c matrix by back transforming those of the corresponding c symmetric tridiagonal matrix determined by tred1. c c on input c c nm must be set to the row dimension of two-dimensional c array parameters as declared in the calling program c dimension statement. c c n is the order of the matrix. c c a contains information about the orthogonal trans- c formations used in the reduction by tred1 c in its strict lower triangle. c c e contains the subdiagonal elements of the tridiagonal c matrix in its last n-1 positions. e(1) is arbitrary. c c m is the number of eigenvectors to be back transformed. c c z contains the eigenvectors to be back transformed c in its first m columns. c c on output c c z contains the transformed eigenvectors c in its first m columns. c c note that trbak1 preserves vector euclidean norms. c c questions and comments should be directed to burton s. garbow, c mathematics and computer science div, argonne national laboratory c c this version dated august 1983. c c ------------------------------------------------------------------ c if (m .eq. 0) go to 200 if (n .eq. 1) go to 200 c do 140 i = 2, n l = i - 1 if (e(i) .eq. 0.0d0) go to 140 c do 130 j = 1, m s = 0.0d0 c do 110 k = 1, l 110 s = s + a(i,k) * z(k,j) c .......... divisor below is negative of h formed in tred1. c double division avoids possible underflow .......... s = (s / a(i,l)) / e(i) c do 120 k = 1, l 120 z(k,j) = z(k,j) + s * a(i,k) c 130 continue c 140 continue c 200 return end c c c subroutine tred1(nm,n,a,d,e,e2) c integer i,j,k,l,n,ii,nm,jp1 double precision a(nm,n),d(n),e(n),e2(n) double precision f,g,h,scale c c this subroutine is a translation of the algol procedure tred1, c num. math. 11, 181-195(1968) by martin, reinsch, and wilkinson. c handbook for auto. comp., vol.ii-linear algebra, 212-226(1971). c c this subroutine reduces a real symmetric matrix c to a symmetric tridiagonal matrix using c orthogonal similarity transformations. c c on input c c nm must be set to the row dimension of two-dimensional c array parameters as declared in the calling program c dimension statement. c c n is the order of the matrix. c c a contains the real symmetric input matrix. only the c lower triangle of the matrix need be supplied. c c on output c c a contains information about the orthogonal trans- c formations used in the reduction in its strict lower c triangle. the full upper triangle of a is unaltered. c c d contains the diagonal elements of the tridiagonal matrix. c c e contains the subdiagonal elements of the tridiagonal c matrix in its last n-1 positions. e(1) is set to zero. c c e2 contains the squares of the corresponding elements of e. c e2 may coincide with e if the squares are not needed. c c questions and comments should be directed to burton s. garbow, c mathematics and computer science div, argonne national laboratory c c this version dated august 1983. c c ------------------------------------------------------------------ c do 100 i = 1, n d(i) = a(n,i) a(n,i) = a(i,i) 100 continue c .......... for i=n step -1 until 1 do -- .......... do 300 ii = 1, n i = n + 1 - ii l = i - 1 h = 0.0d0 scale = 0.0d0 if (l .lt. 1) go to 130 c .......... scale row (algol tol then not needed) .......... do 120 k = 1, l 120 scale = scale + dabs(d(k)) c if (scale .ne. 0.0d0) go to 140 c do 125 j = 1, l d(j) = a(l,j) a(l,j) = a(i,j) a(i,j) = 0.0d0 125 continue c 130 e(i) = 0.0d0 e2(i) = 0.0d0 go to 300 c 140 do 150 k = 1, l d(k) = d(k) / scale h = h + d(k) * d(k) 150 continue c e2(i) = scale * scale * h f = d(l) g = -dsign(dsqrt(h),f) e(i) = scale * g h = h - f * g d(l) = f - g if (l .eq. 1) go to 285 c .......... form a*u .......... do 170 j = 1, l 170 e(j) = 0.0d0 c do 240 j = 1, l f = d(j) g = e(j) + a(j,j) * f jp1 = j + 1 if (l .lt. jp1) go to 220 c do 200 k = jp1, l g = g + a(k,j) * d(k) e(k) = e(k) + a(k,j) * f 200 continue c 220 e(j) = g 240 continue c .......... form p .......... f = 0.0d0 c do 245 j = 1, l e(j) = e(j) / h f = f + e(j) * d(j) 245 continue c h = f / (h + h) c .......... form q .......... do 250 j = 1, l 250 e(j) = e(j) - h * d(j) c .......... form reduced a .......... do 280 j = 1, l f = d(j) g = e(j) c do 260 k = j, l 260 a(k,j) = a(k,j) - f * e(k) - g * d(k) c 280 continue c 285 do 290 j = 1, l f = d(j) d(j) = a(l,j) a(l,j) = a(i,j) a(i,j) = f * scale 290 continue c 300 continue c return end c c c subroutine tred2(nm,n,a,d,e,z) c integer i,j,k,l,n,ii,nm,jp1 double precision a(nm,n),d(n),e(n),z(nm,n) double precision f,g,h,hh,scale c c this subroutine is a translation of the algol procedure tred2, c num. math. 11, 181-195(1968) by martin, reinsch, and wilkinson. c handbook for auto. comp., vol.ii-linear algebra, 212-226(1971). c c this subroutine reduces a real symmetric matrix to a c symmetric tridiagonal matrix using and accumulating c orthogonal similarity transformations. c c on input c c nm must be set to the row dimension of two-dimensional c array parameters as declared in the calling program c dimension statement. c c n is the order of the matrix. c c a contains the real symmetric input matrix. only the c lower triangle of the matrix need be supplied. c c on output c c d contains the diagonal elements of the tridiagonal matrix. c c e contains the subdiagonal elements of the tridiagonal c matrix in its last n-1 positions. e(1) is set to zero. c c z contains the orthogonal transformation matrix c produced in the reduction. c c a and z may coincide. if distinct, a is unaltered. c c questions and comments should be directed to burton s. garbow, c mathematics and computer science div, argonne national laboratory c c this version dated august 1983. c c ------------------------------------------------------------------ c do 100 i = 1, n c do 80 j = i, n 80 z(j,i) = a(j,i) c d(i) = a(n,i) 100 continue c if (n .eq. 1) go to 510 c .......... for i=n step -1 until 2 do -- .......... do 300 ii = 2, n i = n + 2 - ii l = i - 1 h = 0.0d0 scale = 0.0d0 if (l .lt. 2) go to 130 c .......... scale row (algol tol then not needed) .......... do 120 k = 1, l 120 scale = scale + dabs(d(k)) c if (scale .ne. 0.0d0) go to 140 130 e(i) = d(l) c do 135 j = 1, l d(j) = z(l,j) z(i,j) = 0.0d0 z(j,i) = 0.0d0 135 continue c go to 290 c 140 do 150 k = 1, l d(k) = d(k) / scale h = h + d(k) * d(k) 150 continue c f = d(l) g = -dsign(dsqrt(h),f) e(i) = scale * g h = h - f * g d(l) = f - g c .......... form a*u .......... do 170 j = 1, l 170 e(j) = 0.0d0 c do 240 j = 1, l f = d(j) z(j,i) = f g = e(j) + z(j,j) * f jp1 = j + 1 if (l .lt. jp1) go to 220 c do 200 k = jp1, l g = g + z(k,j) * d(k) e(k) = e(k) + z(k,j) * f 200 continue c 220 e(j) = g 240 continue c .......... form p .......... f = 0.0d0 c do 245 j = 1, l e(j) = e(j) / h f = f + e(j) * d(j) 245 continue c hh = f / (h + h) c .......... form q .......... do 250 j = 1, l 250 e(j) = e(j) - hh * d(j) c .......... form reduced a .......... do 280 j = 1, l f = d(j) g = e(j) c do 260 k = j, l 260 z(k,j) = z(k,j) - f * e(k) - g * d(k) c d(j) = z(l,j) z(i,j) = 0.0d0 280 continue c 290 d(i) = h 300 continue c .......... accumulation of transformation matrices .......... do 500 i = 2, n l = i - 1 z(n,l) = z(l,l) z(l,l) = 1.0d0 h = d(i) if (h .eq. 0.0d0) go to 380 c do 330 k = 1, l 330 d(k) = z(k,i) / h c do 360 j = 1, l g = 0.0d0 c do 340 k = 1, l 340 g = g + z(k,i) * z(k,j) c do 360 k = 1, l z(k,j) = z(k,j) - g * d(k) 360 continue c 380 do 400 k = 1, l 400 z(k,i) = 0.0d0 c 500 continue c 510 do 520 i = 1, n d(i) = z(n,i) z(n,i) = 0.0d0 520 continue c z(n,n) = 1.0d0 e(1) = 0.0d0 return end c c c subroutine tridib(n,eps1,d,e,e2,lb,ub,m11,m,w,ind,ierr,rv4,rv5) c integer i,j,k,l,m,n,p,q,r,s,ii,m1,m2,m11,m22,tag,ierr,isturm double precision d(n),e(n),e2(n),w(m),rv4(n),rv5(n) double precision u,v,lb,t1,t2,ub,xu,x0,x1,eps1,tst1,tst2,epslon integer ind(m) c c this subroutine is a translation of the algol procedure bisect, c num. math. 9, 386-393(1967) by barth, martin, and wilkinson. c handbook for auto. comp., vol.ii-linear algebra, 249-256(1971). c c this subroutine finds those eigenvalues of a tridiagonal c symmetric matrix between specified boundary indices, c using bisection. c c on input c c n is the order of the matrix. c c eps1 is an absolute error tolerance for the computed c eigenvalues. if the input eps1 is non-positive, c it is reset for each submatrix to a default value, c namely, minus the product of the relative machine c precision and the 1-norm of the submatrix. 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 m11 specifies the lower boundary index for the desired c eigenvalues. c c m specifies the number of eigenvalues desired. the upper c boundary index m22 is then obtained as m22=m11+m-1. c c on output c c eps1 is unaltered unless it has been reset to its c (last) default value. 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 lb and ub define an interval containing exactly the desired c eigenvalues. c c w contains, in its first m positions, the eigenvalues c between indices m11 and m22 in ascending order. c c ind contains in its first m positions the submatrix indices c associated with the corresponding eigenvalues in w -- c 1 for eigenvalues belonging to the first submatrix from c the top, 2 for those belonging to the second submatrix, etc.. c c ierr is set to c zero for normal return, c 3*n+1 if multiple eigenvalues at index m11 make c unique selection impossible, c 3*n+2 if multiple eigenvalues at index m22 make c unique selection impossible. c c rv4 and rv5 are temporary storage arrays. c c note that subroutine tql1, imtql1, or tqlrat is generally faster c than tridib, if more than n/4 eigenvalues are to be found. c c questions and comments should be directed to burton s. garbow, c mathematics and computer science div, argonne national laboratory c c this version dated august 1983. c c ------------------------------------------------------------------ c ierr = 0 tag = 0 xu = d(1) x0 = d(1) u = 0.0d0 c .......... look for small sub-diagonal entries and determine an c interval containing all the eigenvalues .......... do 40 i = 1, n x1 = u u = 0.0d0 if (i .ne. n) u = dabs(e(i+1)) xu = dmin1(d(i)-(x1+u),xu) x0 = dmax1(d(i)+(x1+u),x0) if (i .eq. 1) go to 20 tst1 = dabs(d(i)) + dabs(d(i-1)) tst2 = tst1 + dabs(e(i)) if (tst2 .gt. tst1) go to 40 20 e2(i) = 0.0d0 40 continue c x1 = n x1 = x1 * epslon(dmax1(dabs(xu),dabs(x0))) xu = xu - x1 t1 = xu x0 = x0 + x1 t2 = x0 c .......... determine an interval containing exactly c the desired eigenvalues .......... p = 1 q = n m1 = m11 - 1 if (m1 .eq. 0) go to 75 isturm = 1 50 v = x1 x1 = xu + (x0 - xu) * 0.5d0 if (x1 .eq. v) go to 980 go to 320 60 if (s - m1) 65, 73, 70 65 xu = x1 go to 50 70 x0 = x1 go to 50 73 xu = x1 t1 = x1 75 m22 = m1 + m if (m22 .eq. n) go to 90 x0 = t2 isturm = 2 go to 50 80 if (s - m22) 65, 85, 70 85 t2 = x1 90 q = 0 r = 0 c .......... establish and process next submatrix, refining c interval by the gerschgorin bounds .......... 100 if (r .eq. m) go to 1001 tag = tag + 1 p = q + 1 xu = d(p) x0 = d(p) u = 0.0d0 c do 120 q = p, n x1 = u u = 0.0d0 v = 0.0d0 if (q .eq. n) go to 110 u = dabs(e(q+1)) v = e2(q+1) 110 xu = dmin1(d(q)-(x1+u),xu) x0 = dmax1(d(q)+(x1+u),x0) if (v .eq. 0.0d0) go to 140 120 continue c 140 x1 = epslon(dmax1(dabs(xu),dabs(x0))) if (eps1 .le. 0.0d0) eps1 = -x1 if (p .ne. q) go to 180 c .......... check for isolated root within interval .......... if (t1 .gt. d(p) .or. d(p) .ge. t2) go to 940 m1 = p m2 = p rv5(p) = d(p) go to 900 180 x1 = x1 * (q - p + 1) lb = dmax1(t1,xu-x1) ub = dmin1(t2,x0+x1) x1 = lb isturm = 3 go to 320 200 m1 = s + 1 x1 = ub isturm = 4 go to 320 220 m2 = s if (m1 .gt. m2) go to 940 c .......... find roots by bisection .......... x0 = ub isturm = 5 c do 240 i = m1, m2 rv5(i) = ub rv4(i) = lb 240 continue c .......... loop for k-th eigenvalue c for k=m2 step -1 until m1 do -- c (-do- not used to legalize -computed go to-) .......... k = m2 250 xu = lb c .......... for i=k step -1 until m1 do -- .......... do 260 ii = m1, k i = m1 + k - ii if (xu .ge. rv4(i)) go to 260 xu = rv4(i) go to 280 260 continue c 280 if (x0 .gt. rv5(k)) x0 = rv5(k) c .......... next bisection step .......... 300 x1 = (xu + x0) * 0.5d0 if ((x0 - xu) .le. dabs(eps1)) go to 420 tst1 = 2.0d0 * (dabs(xu) + dabs(x0)) tst2 = tst1 + (x0 - xu) if (tst2 .eq. tst1) go to 420 c .......... in-line procedure for sturm sequence .......... 320 s = p - 1 u = 1.0d0 c do 340 i = p, q if (u .ne. 0.0d0) go to 325 v = dabs(e(i)) / epslon(1.0d0) if (e2(i) .eq. 0.0d0) v = 0.0d0 go to 330 325 v = e2(i) / u 330 u = d(i) - x1 - v if (u .lt. 0.0d0) s = s + 1 340 continue c go to (60,80,200,220,360), isturm c .......... refine intervals .......... 360 if (s .ge. k) go to 400 xu = x1 if (s .ge. m1) go to 380 rv4(m1) = x1 go to 300 380 rv4(s+1) = x1 if (rv5(s) .gt. x1) rv5(s) = x1 go to 300 400 x0 = x1 go to 300 c .......... k-th eigenvalue found .......... 420 rv5(k) = x1 k = k - 1 if (k .ge. m1) go to 250 c .......... order eigenvalues tagged with their c submatrix associations .......... 900 s = r r = r + m2 - m1 + 1 j = 1 k = m1 c do 920 l = 1, r if (j .gt. s) go to 910 if (k .gt. m2) go to 940 if (rv5(k) .ge. w(l)) go to 915 c do 905 ii = j, s i = l + s - ii w(i+1) = w(i) ind(i+1) = ind(i) 905 continue c 910 w(l) = rv5(k) ind(l) = tag k = k + 1 go to 920 915 j = j + 1 920 continue c 940 if (q .lt. n) go to 100 go to 1001 c .......... set error -- interval cannot be found containing c exactly the desired eigenvalues .......... 980 ierr = 3 * n + isturm 1001 lb = t1 ub = t2 return end c c c subroutine tsturm(nm,n,eps1,d,e,e2,lb,ub,mm,m,w,z, x ierr,rv1,rv2,rv3,rv4,rv5,rv6) c integer i,j,k,m,n,p,q,r,s,ii,ip,jj,mm,m1,m2,nm,its, x ierr,group,isturm double precision d(n),e(n),e2(n),w(mm),z(nm,mm), x rv1(n),rv2(n),rv3(n),rv4(n),rv5(n),rv6(n) double precision u,v,lb,t1,t2,ub,uk,xu,x0,x1,eps1,eps2,eps3,eps4, x norm,tst1,tst2,epslon,pythag c c this subroutine is a translation of the algol procedure tristurm c by peters and wilkinson. c handbook for auto. comp., vol.ii-linear algebra, 418-439(1971). c c this subroutine finds those eigenvalues of a tridiagonal c symmetric matrix which lie in a specified interval and their c associated eigenvectors, using bisection and inverse iteration. c c on input c c nm must be set to the row dimension of two-dimensional c array parameters as declared in the calling program c dimension statement. c c n is the order of the matrix. c c eps1 is an absolute error tolerance for the computed c eigenvalues. it should be chosen commensurate with c relative perturbations in the matrix elements of the c order of the relative machine precision. if the c input eps1 is non-positive, it is reset for each c submatrix to a default value, namely, minus the c product of the relative machine precision and the c 1-norm of the submatrix. 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 lb and ub define the interval to be searched for eigenvalues. c if lb is not less than ub, no eigenvalues will be found. c c mm should be set to an upper bound for the number of c eigenvalues in the interval. warning. if more than c mm eigenvalues are determined to lie in the interval, c an error return is made with no values or vectors found. c c on output c c eps1 is unaltered unless it has been reset to its c (last) default value. 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 m is the number of eigenvalues determined to lie in (lb,ub). c c w contains the m eigenvalues in ascending order if the matrix c does not split. if the matrix splits, the eigenvalues are c in ascending order for each submatrix. if a vector error c exit is made, w contains those values already found. c c z contains the associated set of orthonormal eigenvectors. c if an error exit is made, z contains those vectors c already found. c c ierr is set to c zero for normal return, c 3*n+1 if m exceeds mm. c 4*n+r if the eigenvector corresponding to the r-th c eigenvalue fails to converge in 5 iterations. c c rv1, rv2, rv3, rv4, rv5, and rv6 are temporary storage arrays. c c the algol procedure sturmcnt contained in tristurm c appears in tsturm in-line. c c calls pythag for dsqrt(a*a + b*b) . c c questions and comments should be directed to burton s. garbow, c mathematics and computer science div, argonne national laboratory c c this version dated august 1983. c c ------------------------------------------------------------------ c ierr = 0 t1 = lb t2 = ub c .......... look for small sub-diagonal entries .......... do 40 i = 1, n if (i .eq. 1) go to 20 tst1 = dabs(d(i)) + dabs(d(i-1)) tst2 = tst1 + dabs(e(i)) if (tst2 .gt. tst1) go to 40 20 e2(i) = 0.0d0 40 continue c .......... determine the number of eigenvalues c in the interval .......... p = 1 q = n x1 = ub isturm = 1 go to 320 60 m = s x1 = lb isturm = 2 go to 320 80 m = m - s if (m .gt. mm) go to 980 q = 0 r = 0 c .......... establish and process next submatrix, refining c interval by the gerschgorin bounds .......... 100 if (r .eq. m) go to 1001 p = q + 1 xu = d(p) x0 = d(p) u = 0.0d0 c do 120 q = p, n x1 = u u = 0.0d0 v = 0.0d0 if (q .eq. n) go to 110 u = dabs(e(q+1)) v = e2(q+1) 110 xu = dmin1(d(q)-(x1+u),xu) x0 = dmax1(d(q)+(x1+u),x0) if (v .eq. 0.0d0) go to 140 120 continue c 140 x1 = epslon(dmax1(dabs(xu),dabs(x0))) if (eps1 .le. 0.0d0) eps1 = -x1 if (p .ne. q) go to 180 c .......... check for isolated root within interval .......... if (t1 .gt. d(p) .or. d(p) .ge. t2) go to 940 r = r + 1 c do 160 i = 1, n 160 z(i,r) = 0.0d0 c w(r) = d(p) z(p,r) = 1.0d0 go to 940 180 u = q-p+1 x1 = u * x1 lb = dmax1(t1,xu-x1) ub = dmin1(t2,x0+x1) x1 = lb isturm = 3 go to 320 200 m1 = s + 1 x1 = ub isturm = 4 go to 320 220 m2 = s if (m1 .gt. m2) go to 940 c .......... find roots by bisection .......... x0 = ub isturm = 5 c do 240 i = m1, m2 rv5(i) = ub rv4(i) = lb 240 continue c .......... loop for k-th eigenvalue c for k=m2 step -1 until m1 do -- c (-do- not used to legalize -computed go to-) .......... k = m2 250 xu = lb c .......... for i=k step -1 until m1 do -- .......... do 260 ii = m1, k i = m1 + k - ii if (xu .ge. rv4(i)) go to 260 xu = rv4(i) go to 280 260 continue c 280 if (x0 .gt. rv5(k)) x0 = rv5(k) c .......... next bisection step .......... 300 x1 = (xu + x0) * 0.5d0 if ((x0 - xu) .le. dabs(eps1)) go to 420 tst1 = 2.0d0 * (dabs(xu) + dabs(x0)) tst2 = tst1 + (x0 - xu) if (tst2 .eq. tst1) go to 420 c .......... in-line procedure for sturm sequence .......... 320 s = p - 1 u = 1.0d0 c do 340 i = p, q if (u .ne. 0.0d0) go to 325 v = dabs(e(i)) / epslon(1.0d0) if (e2(i) .eq. 0.0d0) v = 0.0d0 go to 330 325 v = e2(i) / u 330 u = d(i) - x1 - v if (u .lt. 0.0d0) s = s + 1 340 continue c go to (60,80,200,220,360), isturm c .......... refine intervals .......... 360 if (s .ge. k) go to 400 xu = x1 if (s .ge. m1) go to 380 rv4(m1) = x1 go to 300 380 rv4(s+1) = x1 if (rv5(s) .gt. x1) rv5(s) = x1 go to 300 400 x0 = x1 go to 300 c .......... k-th eigenvalue found .......... 420 rv5(k) = x1 k = k - 1 if (k .ge. m1) go to 250 c .......... find vectors by inverse iteration .......... norm = dabs(d(p)) ip = p + 1 c do 500 i = ip, q 500 norm = dmax1(norm, dabs(d(i)) + dabs(e(i))) c .......... eps2 is the criterion for grouping, c eps3 replaces zero pivots and equal c roots are modified by eps3, c eps4 is taken very small to avoid overflow .......... eps2 = 1.0d-3 * norm eps3 = epslon(norm) uk = q - p + 1 eps4 = uk * eps3 uk = eps4 / dsqrt(uk) group = 0 s = p c do 920 k = m1, m2 r = r + 1 its = 1 w(r) = rv5(k) x1 = rv5(k) c .......... look for close or coincident roots .......... if (k .eq. m1) go to 520 if (x1 - x0 .ge. eps2) group = -1 group = group + 1 if (x1 .le. x0) x1 = x0 + eps3 c .......... elimination with interchanges and c initialization of vector .......... 520 v = 0.0d0 c do 580 i = p, q rv6(i) = uk if (i .eq. p) go to 560 if (dabs(e(i)) .lt. dabs(u)) go to 540 xu = u / e(i) rv4(i) = xu rv1(i-1) = e(i) rv2(i-1) = d(i) - x1 rv3(i-1) = 0.0d0 if (i .ne. q) rv3(i-1) = e(i+1) u = v - xu * rv2(i-1) v = -xu * rv3(i-1) go to 580 540 xu = e(i) / u rv4(i) = xu rv1(i-1) = u rv2(i-1) = v rv3(i-1) = 0.0d0 560 u = d(i) - x1 - xu * v if (i .ne. q) v = e(i+1) 580 continue c if (u .eq. 0.0d0) u = eps3 rv1(q) = u rv2(q) = 0.0d0 rv3(q) = 0.0d0 c .......... back substitution c for i=q step -1 until p do -- .......... 600 do 620 ii = p, q i = p + q - ii rv6(i) = (rv6(i) - u * rv2(i) - v * rv3(i)) / rv1(i) v = u u = rv6(i) 620 continue c .......... orthogonalize with respect to previous c members of group .......... if (group .eq. 0) go to 700 c do 680 jj = 1, group j = r - group - 1 + jj xu = 0.0d0 c do 640 i = p, q 640 xu = xu + rv6(i) * z(i,j) c do 660 i = p, q 660 rv6(i) = rv6(i) - xu * z(i,j) c 680 continue c 700 norm = 0.0d0 c do 720 i = p, q 720 norm = norm + dabs(rv6(i)) c if (norm .ge. 1.0d0) go to 840 c .......... forward substitution .......... if (its .eq. 5) go to 960 if (norm .ne. 0.0d0) go to 740 rv6(s) = eps4 s = s + 1 if (s .gt. q) s = p go to 780 740 xu = eps4 / norm c do 760 i = p, q 760 rv6(i) = rv6(i) * xu c .......... elimination operations on next vector c iterate .......... 780 do 820 i = ip, q u = rv6(i) c .......... if rv1(i-1) .eq. e(i), a row interchange c was performed earlier in the c triangularization process .......... if (rv1(i-1) .ne. e(i)) go to 800 u = rv6(i-1) rv6(i-1) = rv6(i) 800 rv6(i) = u - rv4(i) * rv6(i-1) 820 continue c its = its + 1 go to 600 c .......... normalize so that sum of squares is c 1 and expand to full order .......... 840 u = 0.0d0 c do 860 i = p, q 860 u = pythag(u,rv6(i)) c xu = 1.0d0 / u c do 880 i = 1, n 880 z(i,r) = 0.0d0 c do 900 i = p, q 900 z(i,r) = rv6(i) * xu c x0 = x1 920 continue c 940 if (q .lt. n) go to 100 go to 1001 c .......... set error -- non-converged eigenvector .......... 960 ierr = 4 * n + r go to 1001 c .......... set error -- underestimate of number of c eigenvalues in interval .......... 980 ierr = 3 * n + 1 1001 lb = t1 ub = t2 return end