home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Geek Gadgets 1
/
ADE-1.bin
/
ade-dist
/
eispack-1.0-src.tgz
/
tar.out
/
contrib
/
eispack
/
tsturm.f
< prev
Wrap
Text File
|
1996-09-28
|
11KB
|
369 lines
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