KTH framework for Nek5000 toolboxes; testing version  0.0.1
calcz.f
Go to the documentation of this file.
1 c-----------------------------------------------------------------------
2  subroutine calcz(d,e,n,dmax,dmin,z,ierr)
3 c
4 c Num. Rec. 2nd Ed., p.473
5 c
6 c Note: d(1:n) is the diagonal of the sym. tridiagonal matrix
7 c e(1:n) is the upper diagonal of the tridiagonal matrix,
8 c WITH e(n) ARBITRARY (a slight shift from Num.Rec.)
9 c
10 c z(n:n) is the packed array of eigenvectors
11 c
12  real d(n),e(n),z(n,n)
13  real smalln,small
14 c
15  call ident(z,n)
16  one = 1.
17 c
18 c Find smallest number (pff mod to Num. Rec. 2nd Ed., p.473)
19 c
20  small = 0.5
21  do i = 1,100
22  smalln = small * small
23  if (smalln .eq.0) then
24  do j=1,1000
25  smalln = 0.5*small
26  if (smalln .eq.0) goto 10
27  small = smalln
28  enddo
29  endif
30  small = smalln
31  enddo
32  10 continue
33  small = 10.*small
34  small = max(small,1e-99)
35 
36 c write(6,*) 'this is small:',small
37 c
38  do 15 l=1,n
39  iter = 0
40 c
41  1 do 12 m=l,n-1
42  dd = abs( d(m) ) + abs( d(m+1) )
43  de = e(m) + dd
44  df = abs(dd - de)
45 c write(6,112) iter,m,'de:',dd,de,df,small
46  if ( df .le. small ) goto 2
47  12 continue
48  112 format(i3,i9,1x,a3,1p4e16.8)
49  m = n
50 c
51  2 if ( m .ne. l ) then
52  if ( iter .eq. 600 ) then
53  write (6,*) 'too many iterations in calc'
54 c n10 = min(n,10)
55 c do i=1,n
56 c write(6,9) d(i),(z(i,j),j=1,n10)
57 c enddo
58 c 9 format(1pe12.4,' e:',1p10e12.4)
59 c call exitt
60  ierr=1
61  return
62  endif
63 c
64  iter = iter + 1
65  g = ( d(l+1) - d(l) ) / ( 2.0 * e(l) )
66  r = pythag(g,one)
67  g = d(m) - d(l) + e(l)/(g+sign(r,g))
68  s = 1.0
69  c = 1.0
70  p = 0.0
71 c
72  do 14 i = m-1,l,-1
73  f = s * e(i)
74  b = c * e(i)
75  r = pythag(f,g)
76  e(i+1) = r
77  if ( abs(r) .le. small ) then
78  d(i+1) = d(i+1) - p
79  e(m) = 0.
80  goto 1
81  endif
82  s = f/r
83  c = g/r
84  g = d(i+1) - p
85  r = ( d(i)-g )*s + 2.*c*b
86  p = s*r
87  d(i+1) = g + p
88  g = c*r - b
89 c ... find eigenvectors ... (new, 11/19/94, pff, p.363. Num.Rec.I.)
90  do 13 k=1,n
91  f = z(k,i+1)
92  z(k,i+1) = s*z(k,i)+c*f
93  z(k,i ) = c*z(k,i)-s*f
94  13 continue
95 c ... end of eigenvector section ...
96  14 continue
97 c
98  d(l) = d(l) - p
99  e(l) = g
100  e(m) = 0.0
101  goto 1
102  endif
103 c
104  15 continue
105 c
106 c write (8,8) (d(j),j=1,n)
107 c 8 format('eig:',8f10.4)
108 c
109  dmin = d(1)
110  dmax = d(1)
111  do 40 i = 1 , n
112  dmin = min( d(i) , dmin )
113  dmax = max( d(i) , dmax )
114  40 continue
115 c
116 c Output eigenvectors
117 c
118 c n10 = min(n,10)
119 c do i=1,n
120 c write(6,9) d(i),(z(i,j),j=1,n10)
121 c enddo
122 c 9 format(1pe12.4,' e:',1p10e12.4)
123 c
124  ierr=0
125  return
126  end
127 c-----------------------------------------------------------------------
128  function pythag(a,b)
129 c
130 c Compute sqrt(a*a + b*b) w/o under- or over-flow.
131 c
132  absa=abs(a)
133  absb=abs(b)
134  if (absa.gt.absb) then
135  pythag = absa*sqrt(1. + (absb/absa)**2 )
136  else
137  if (absb.eq.0.) then
138  pythag = 0.
139  else
140  pythag = absb*sqrt(1. + (absa/absb)**2 )
141  endif
142  endif
143  return
144  end
145 c-----------------------------------------------------------------------
146  subroutine ident(a,n)
147  real a(n,n)
148  call rzero(a,n*n)
149  do i=1,n
150  a(i,i) = 1.0
151  enddo
152  return
153  end
154 c-----------------------------------------------------------------------
subroutine calcz(d, e, n, dmax, dmin, z, ierr)
Definition: calcz.f:3
subroutine ident(a, n)
Definition: calcz.f:147
function pythag(a, b)
Definition: calcz.f:129
subroutine rzero(a, n)
Definition: math.f:208