Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
ElmerCSC
GitHub Repository: ElmerCSC/elmerfem
Path: blob/devel/mathlibs/src/arpack/dneigh.f
5224 views
1
c-----------------------------------------------------------------------
2
c\BeginDoc
3
c
4
c\Name: dneigh
5
c
6
c\Description:
7
c Compute the eigenvalues of the current upper Hessenberg matrix
8
c and the corresponding Ritz estimates given the current residual norm.
9
c
10
c\Usage:
11
c call dneigh
12
c ( RNORM, N, H, LDH, RITZR, RITZI, BOUNDS, Q, LDQ, WORKL, IERR )
13
c
14
c\Arguments
15
c RNORM Double precision scalar. (INPUT)
16
c Residual norm corresponding to the current upper Hessenberg
17
c matrix H.
18
c
19
c N Integer. (INPUT)
20
c Size of the matrix H.
21
c
22
c H Double precision N by N array. (INPUT)
23
c H contains the current upper Hessenberg matrix.
24
c
25
c LDH Integer. (INPUT)
26
c Leading dimension of H exactly as declared in the calling
27
c program.
28
c
29
c RITZR, Double precision arrays of length N. (OUTPUT)
30
c RITZI On output, RITZR(1:N) (resp. RITZI(1:N)) contains the real
31
c (respectively imaginary) parts of the eigenvalues of H.
32
c
33
c BOUNDS Double precision array of length N. (OUTPUT)
34
c On output, BOUNDS contains the Ritz estimates associated with
35
c the eigenvalues RITZR and RITZI. This is equal to RNORM
36
c times the last components of the eigenvectors corresponding
37
c to the eigenvalues in RITZR and RITZI.
38
c
39
c Q Double precision N by N array. (WORKSPACE)
40
c Workspace needed to store the eigenvectors of H.
41
c
42
c LDQ Integer. (INPUT)
43
c Leading dimension of Q exactly as declared in the calling
44
c program.
45
c
46
c WORKL Double precision work array of length N**2 + 3*N. (WORKSPACE)
47
c Private (replicated) array on each PE or array allocated on
48
c the front end. This is needed to keep the full Schur form
49
c of H and also in the calculation of the eigenvectors of H.
50
c
51
c IERR Integer. (OUTPUT)
52
c Error exit flag from dlaqrb or dtrevc.
53
c
54
c\EndDoc
55
c
56
c-----------------------------------------------------------------------
57
c
58
c\BeginLib
59
c
60
c\Local variables:
61
c xxxxxx real
62
c
63
c\Routines called:
64
c dlaqrb ARPACK routine to compute the real Schur form of an
65
c upper Hessenberg matrix and last row of the Schur vectors.
66
c second ARPACK utility routine for timing.
67
c dmout ARPACK utility routine that prints matrices
68
c dvout ARPACK utility routine that prints vectors.
69
c dlacpy LAPACK matrix copy routine.
70
c dlapy2 LAPACK routine to compute sqrt(x**2+y**2) carefully.
71
c dtrevc LAPACK routine to compute the eigenvectors of a matrix
72
c in upper quasi-triangular form
73
c dgemv Level 2 BLAS routine for matrix vector multiplication.
74
c dcopy Level 1 BLAS that copies one vector to another .
75
c dnrm2 Level 1 BLAS that computes the norm of a vector.
76
c dscal Level 1 BLAS that scales a vector.
77
c
78
c
79
c\Author
80
c Danny Sorensen Phuong Vu
81
c Richard Lehoucq CRPC / Rice University
82
c Dept. of Computational & Houston, Texas
83
c Applied Mathematics
84
c Rice University
85
c Houston, Texas
86
c
87
c\Revision history:
88
c xx/xx/92: Version ' 2.1'
89
c
90
c\SCCS Information: @(#)
91
c FILE: neigh.F SID: 2.3 DATE OF SID: 4/20/96 RELEASE: 2
92
c
93
c\Remarks
94
c None
95
c
96
c\EndLib
97
c
98
c-----------------------------------------------------------------------
99
c
100
subroutine dneigh (rnorm, n, h, ldh, ritzr, ritzi, bounds,
101
& q, ldq, workl, ierr)
102
c
103
c %----------------------------------------------------%
104
c | Include files for debugging and timing information |
105
c %----------------------------------------------------%
106
c
107
include 'debug.h'
108
include 'stat.h'
109
c
110
c %------------------%
111
c | Scalar Arguments |
112
c %------------------%
113
c
114
integer ierr, n, ldh, ldq
115
Double precision
116
& rnorm
117
c
118
c %-----------------%
119
c | Array Arguments |
120
c %-----------------%
121
c
122
Double precision
123
& bounds(n), h(ldh,n), q(ldq,n), ritzi(n), ritzr(n),
124
& workl(n*(n+3))
125
c
126
c %------------%
127
c | Parameters |
128
c %------------%
129
c
130
Double precision
131
& one, zero
132
parameter (one = 1.0D+0, zero = 0.0D+0)
133
c
134
c %------------------------%
135
c | Local Scalars & Arrays |
136
c %------------------------%
137
c
138
logical select(1)
139
integer i, iconj, msglvl
140
Double precision
141
& temp, vl(1)
142
c
143
c %----------------------%
144
c | External Subroutines |
145
c %----------------------%
146
c
147
external dcopy, dlacpy, dlaqrb, dtrevc, dvout, second
148
c
149
c %--------------------%
150
c | External Functions |
151
c %--------------------%
152
c
153
Double precision
154
& dlapy2, dnrm2
155
external dlapy2, dnrm2
156
c
157
c %---------------------%
158
c | Intrinsic Functions |
159
c %---------------------%
160
c
161
intrinsic abs
162
c
163
c %-----------------------%
164
c | Executable Statements |
165
c %-----------------------%
166
c
167
c
168
c %-------------------------------%
169
c | Initialize timing statistics |
170
c | & message level for debugging |
171
c %-------------------------------%
172
c
173
call second (t0)
174
msglvl = mneigh
175
c
176
if (msglvl .gt. 2) then
177
call dmout (logfil, n, n, h, ldh, ndigit,
178
& '_neigh: Entering upper Hessenberg matrix H ')
179
end if
180
c
181
c %-----------------------------------------------------------%
182
c | 1. Compute the eigenvalues, the last components of the |
183
c | corresponding Schur vectors and the full Schur form T |
184
c | of the current upper Hessenberg matrix H. |
185
c | dlaqrb returns the full Schur form of H in WORKL(1:N**2) |
186
c | and the last components of the Schur vectors in BOUNDS. |
187
c %-----------------------------------------------------------%
188
c
189
call dlacpy ('All', n, n, h, ldh, workl, n)
190
call dlaqrb (.true., n, 1, n, workl, n, ritzr, ritzi, bounds,
191
& ierr)
192
if (ierr .ne. 0) go to 9000
193
c
194
if (msglvl .gt. 1) then
195
call dvout (logfil, n, bounds, ndigit,
196
& '_neigh: last row of the Schur matrix for H')
197
end if
198
c
199
c %-----------------------------------------------------------%
200
c | 2. Compute the eigenvectors of the full Schur form T and |
201
c | apply the last components of the Schur vectors to get |
202
c | the last components of the corresponding eigenvectors. |
203
c | Remember that if the i-th and (i+1)-st eigenvalues are |
204
c | complex conjugate pairs, then the real & imaginary part |
205
c | of the eigenvector components are split across adjacent |
206
c | columns of Q. |
207
c %-----------------------------------------------------------%
208
c
209
call dtrevc ('R', 'A', select, n, workl, n, vl, n, q, ldq,
210
& n, n, workl(n*n+1), ierr)
211
c
212
if (ierr .ne. 0) go to 9000
213
c
214
c %------------------------------------------------%
215
c | Scale the returning eigenvectors so that their |
216
c | euclidean norms are all one. LAPACK subroutine |
217
c | dtrevc returns each eigenvector normalized so |
218
c | that the element of largest magnitude has |
219
c | magnitude 1; here the magnitude of a complex |
220
c | number (x,y) is taken to be |x| + |y|. |
221
c %------------------------------------------------%
222
c
223
iconj = 0
224
do 10 i=1, n
225
if ( abs( ritzi(i) ) .le. zero ) then
226
c
227
c %----------------------%
228
c | Real eigenvalue case |
229
c %----------------------%
230
c
231
temp = dnrm2( n, q(1,i), 1 )
232
call dscal ( n, one / temp, q(1,i), 1 )
233
else
234
c
235
c %-------------------------------------------%
236
c | Complex conjugate pair case. Note that |
237
c | since the real and imaginary part of |
238
c | the eigenvector are stored in consecutive |
239
c | columns, we further normalize by the |
240
c | square root of two. |
241
c %-------------------------------------------%
242
c
243
if (iconj .eq. 0) then
244
temp = dlapy2( dnrm2( n, q(1,i), 1 ),
245
& dnrm2( n, q(1,i+1), 1 ) )
246
call dscal ( n, one / temp, q(1,i), 1 )
247
call dscal ( n, one / temp, q(1,i+1), 1 )
248
iconj = 1
249
else
250
iconj = 0
251
end if
252
end if
253
10 continue
254
c
255
call dgemv ('T', n, n, one, q, ldq, bounds, 1, zero, workl, 1)
256
c
257
if (msglvl .gt. 1) then
258
call dvout (logfil, n, workl, ndigit,
259
& '_neigh: Last row of the eigenvector matrix for H')
260
end if
261
c
262
c %----------------------------%
263
c | Compute the Ritz estimates |
264
c %----------------------------%
265
c
266
iconj = 0
267
do 20 i = 1, n
268
if ( abs( ritzi(i) ) .le. zero ) then
269
c
270
c %----------------------%
271
c | Real eigenvalue case |
272
c %----------------------%
273
c
274
bounds(i) = rnorm * abs( workl(i) )
275
else
276
c
277
c %-------------------------------------------%
278
c | Complex conjugate pair case. Note that |
279
c | since the real and imaginary part of |
280
c | the eigenvector are stored in consecutive |
281
c | columns, we need to take the magnitude |
282
c | of the last components of the two vectors |
283
c %-------------------------------------------%
284
c
285
if (iconj .eq. 0) then
286
bounds(i) = rnorm * dlapy2( workl(i), workl(i+1) )
287
bounds(i+1) = bounds(i)
288
iconj = 1
289
else
290
iconj = 0
291
end if
292
end if
293
20 continue
294
c
295
if (msglvl .gt. 2) then
296
call dvout (logfil, n, ritzr, ndigit,
297
& '_neigh: Real part of the eigenvalues of H')
298
call dvout (logfil, n, ritzi, ndigit,
299
& '_neigh: Imaginary part of the eigenvalues of H')
300
call dvout (logfil, n, bounds, ndigit,
301
& '_neigh: Ritz estimates for the eigenvalues of H')
302
end if
303
c
304
call second (t1)
305
tneigh = tneigh + (t1 - t0)
306
c
307
9000 continue
308
return
309
c
310
c %---------------%
311
c | End of dneigh |
312
c %---------------%
313
c
314
end
315
316