source: CIVL/examples/fortran/nek5000/core/calcz.f

main
Last change on this file was ea777aa, checked in by Alex Wilton <awilton@…>, 3 years ago

Moved examples, include, build_default.properties, common.xml, and README out from dev.civl.com into the root of the repo.

git-svn-id: svn://vsl.cis.udel.edu/civl/trunk@5704 fb995dde-84ed-4084-dfe6-e5aef3e2452c

  • Property mode set to 100755
File size: 3.9 KB
Line 
1c-----------------------------------------------------------------------
2 subroutine calcz(d,e,n,dmax,dmin,z,ierr)
3c
4c Num. Rec. 2nd Ed., p.473
5c
6c Note: d(1:n) is the diagonal of the sym. tridiagonal matrix
7c e(1:n) is the upper diagonal of the tridiagonal matrix,
8c WITH e(n) ARBITRARY (a slight shift from Num.Rec.)
9c
10c z(n:n) is the packed array of eigenvectors
11c
12 real d(n),e(n),z(n,n)
13 real smalln,small
14c
15 call ident(z,n)
16 one = 1.
17c
18c Find smallest number (pff mod to Num. Rec. 2nd Ed., p.473)
19c
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
36c write(6,*) 'this is small:',small
37c
38 do 15 l=1,n
39 iter = 0
40c
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)
45c 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
50c
51 2 if ( m .ne. l ) then
52 if ( iter .eq. 600 ) then
53 write (6,*) 'too many iterations in calc'
54c n10 = min(n,10)
55c do i=1,n
56c write(6,9) d(i),(z(i,j),j=1,n10)
57c enddo
58c 9 format(1pe12.4,' e:',1p10e12.4)
59c call exitt
60 ierr=1
61 return
62 endif
63c
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
71c
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
89c ... 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
95c ... end of eigenvector section ...
96 14 continue
97c
98 d(l) = d(l) - p
99 e(l) = g
100 e(m) = 0.0
101 goto 1
102 endif
103c
104 15 continue
105c
106c write (8,8) (d(j),j=1,n)
107c 8 format('eig:',8f10.4)
108c
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
115c
116c Output eigenvectors
117c
118c n10 = min(n,10)
119c do i=1,n
120c write(6,9) d(i),(z(i,j),j=1,n10)
121c enddo
122c 9 format(1pe12.4,' e:',1p10e12.4)
123c
124 ierr=0
125 return
126 end
127c-----------------------------------------------------------------------
128 function pythag(a,b)
129c
130c Compute sqrt(a*a + b*b) w/o under- or over-flow.
131c
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
145c-----------------------------------------------------------------------
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
154c-----------------------------------------------------------------------
Note: See TracBrowser for help on using the repository browser.