KTH framework for Nek5000 toolboxes; testing version  0.0.1
dhseqr.f
Go to the documentation of this file.
1  SUBROUTINE dhseqr( JOB, COMPZ, N, ILO, IHI, H, LDH, WR, WI, Z,
2  $ LDZ, WORK, LWORK, INFO )
3 *
4 * -- LAPACK routine (version 3.0) --
5 * Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd.,
6 * Courant Institute, Argonne National Lab, and Rice University
7 * June 30, 1999
8 *
9 * .. Scalar Arguments ..
10  CHARACTER COMPZ, JOB
11  INTEGER IHI, ILO, INFO, LDH, LDZ, LWORK, N
12 * ..
13 * .. Array Arguments ..
14  DOUBLE PRECISION H( LDH, * ), WI( * ), WORK( * ), WR( * ),
15  $ z( ldz, * )
16 * ..
17 *
18 * Purpose
19 * =======
20 *
21 * DHSEQR computes the eigenvalues of a real upper Hessenberg matrix H
22 * and, optionally, the matrices T and Z from the Schur decomposition
23 * H = Z T Z**T, where T is an upper quasi-triangular matrix (the Schur
24 * form), and Z is the orthogonal matrix of Schur vectors.
25 *
26 * Optionally Z may be postmultiplied into an input orthogonal matrix Q,
27 * so that this routine can give the Schur factorization of a matrix A
28 * which has been reduced to the Hessenberg form H by the orthogonal
29 * matrix Q: A = Q*H*Q**T = (QZ)*T*(QZ)**T.
30 *
31 * Arguments
32 * =========
33 *
34 * JOB (input) CHARACTER*1
35 * = 'E': compute eigenvalues only;
36 * = 'S': compute eigenvalues and the Schur form T.
37 *
38 * COMPZ (input) CHARACTER*1
39 * = 'N': no Schur vectors are computed;
40 * = 'I': Z is initialized to the unit matrix and the matrix Z
41 * of Schur vectors of H is returned;
42 * = 'V': Z must contain an orthogonal matrix Q on entry, and
43 * the product Q*Z is returned.
44 *
45 * N (input) INTEGER
46 * The order of the matrix H. N >= 0.
47 *
48 * ILO (input) INTEGER
49 * IHI (input) INTEGER
50 * It is assumed that H is already upper triangular in rows
51 * and columns 1:ILO-1 and IHI+1:N. ILO and IHI are normally
52 * set by a previous call to DGEBAL, and then passed to SGEHRD
53 * when the matrix output by DGEBAL is reduced to Hessenberg
54 * form. Otherwise ILO and IHI should be set to 1 and N
55 * respectively.
56 * 1 <= ILO <= IHI <= N, if N > 0; ILO=1 and IHI=0, if N=0.
57 *
58 * H (input/output) DOUBLE PRECISION array, dimension (LDH,N)
59 * On entry, the upper Hessenberg matrix H.
60 * On exit, if JOB = 'S', H contains the upper quasi-triangular
61 * matrix T from the Schur decomposition (the Schur form);
62 * 2-by-2 diagonal blocks (corresponding to complex conjugate
63 * pairs of eigenvalues) are returned in standard form, with
64 * H(i,i) = H(i+1,i+1) and H(i+1,i)*H(i,i+1) < 0. If JOB = 'E',
65 * the contents of H are unspecified on exit.
66 *
67 * LDH (input) INTEGER
68 * The leading dimension of the array H. LDH >= max(1,N).
69 *
70 * WR (output) DOUBLE PRECISION array, dimension (N)
71 * WI (output) DOUBLE PRECISION array, dimension (N)
72 * The real and imaginary parts, respectively, of the computed
73 * eigenvalues. If two eigenvalues are computed as a complex
74 * conjugate pair, they are stored in consecutive elements of
75 * WR and WI, say the i-th and (i+1)th, with WI(i) > 0 and
76 * WI(i+1) < 0. If JOB = 'S', the eigenvalues are stored in the
77 * same order as on the diagonal of the Schur form returned in
78 * H, with WR(i) = H(i,i) and, if H(i:i+1,i:i+1) is a 2-by-2
79 * diagonal block, WI(i) = sqrt(H(i+1,i)*H(i,i+1)) and
80 * WI(i+1) = -WI(i).
81 *
82 * Z (input/output) DOUBLE PRECISION array, dimension (LDZ,N)
83 * If COMPZ = 'N': Z is not referenced.
84 * If COMPZ = 'I': on entry, Z need not be set, and on exit, Z
85 * contains the orthogonal matrix Z of the Schur vectors of H.
86 * If COMPZ = 'V': on entry Z must contain an N-by-N matrix Q,
87 * which is assumed to be equal to the unit matrix except for
88 * the submatrix Z(ILO:IHI,ILO:IHI); on exit Z contains Q*Z.
89 * Normally Q is the orthogonal matrix generated by DORGHR after
90 * the call to DGEHRD which formed the Hessenberg matrix H.
91 *
92 * LDZ (input) INTEGER
93 * The leading dimension of the array Z.
94 * LDZ >= max(1,N) if COMPZ = 'I' or 'V'; LDZ >= 1 otherwise.
95 *
96 * WORK (workspace/output) DOUBLE PRECISION array, dimension (LWORK)
97 * On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
98 *
99 * LWORK (input) INTEGER
100 * The dimension of the array WORK. LWORK >= max(1,N).
101 *
102 * If LWORK = -1, then a workspace query is assumed; the routine
103 * only calculates the optimal size of the WORK array, returns
104 * this value as the first entry of the WORK array, and no error
105 * message related to LWORK is issued by XERBLA.
106 *
107 * INFO (output) INTEGER
108 * = 0: successful exit
109 * < 0: if INFO = -i, the i-th argument had an illegal value
110 * > 0: if INFO = i, DHSEQR failed to compute all of the
111 * eigenvalues in a total of 30*(IHI-ILO+1) iterations;
112 * elements 1:ilo-1 and i+1:n of WR and WI contain those
113 * eigenvalues which have been successfully computed.
114 *
115 * =====================================================================
116 *
117 * .. Parameters ..
118  DOUBLE PRECISION ZERO, ONE, TWO
119  parameter( zero = 0.0d+0, one = 1.0d+0, two = 2.0d+0 )
120  DOUBLE PRECISION CONST
121  parameter( const = 1.5d+0 )
122  INTEGER NSMAX, LDS
123  parameter( nsmax = 15, lds = nsmax )
124 * ..
125 * .. Local Scalars ..
126  LOGICAL INITZ, LQUERY, WANTT, WANTZ
127  INTEGER I, I1, I2, IERR, II, ITEMP, ITN, ITS, J, K, L,
128  $ maxb, nh, nr, ns, nv
129  DOUBLE PRECISION ABSW, OVFL, SMLNUM, TAU, TEMP, TST1, ULP, UNFL
130 * ..
131 * .. Local Arrays ..
132  DOUBLE PRECISION S( LDS, NSMAX ), V( NSMAX+1 ), VV( NSMAX+1 )
133 * ..
134 * .. External Functions ..
135  LOGICAL LSAME
136  INTEGER IDAMAX, ILAENV
137  DOUBLE PRECISION DLAMCH, DLANHS, DLAPY2
138  EXTERNAL lsame, idamax, ilaenv, dlamch, dlanhs, dlapy2
139 * ..
140 * .. External Subroutines ..
141  EXTERNAL dcopy, dgemv, dlacpy, dlahqr, dlarfg, dlarfx,
142  $ dlaset, dscal, xerbla
143 * ..
144 * .. Intrinsic Functions ..
145  INTRINSIC abs, max, min
146 * ..
147 * .. Executable Statements ..
148 *
149 * Decode and test the input parameters
150 *
151  wantt = lsame( job, 'S' )
152  initz = lsame( compz, 'I' )
153  wantz = initz .OR. lsame( compz, 'V' )
154 *
155  info = 0
156  work( 1 ) = max( 1, n )
157  lquery = ( lwork.EQ.-1 )
158  IF( .NOT.lsame( job, 'E' ) .AND. .NOT.wantt ) THEN
159  info = -1
160  ELSE IF( .NOT.lsame( compz, 'N' ) .AND. .NOT.wantz ) THEN
161  info = -2
162  ELSE IF( n.LT.0 ) THEN
163  info = -3
164  ELSE IF( ilo.LT.1 .OR. ilo.GT.max( 1, n ) ) THEN
165  info = -4
166  ELSE IF( ihi.LT.min( ilo, n ) .OR. ihi.GT.n ) THEN
167  info = -5
168  ELSE IF( ldh.LT.max( 1, n ) ) THEN
169  info = -7
170  ELSE IF( ldz.LT.1 .OR. wantz .AND. ldz.LT.max( 1, n ) ) THEN
171  info = -11
172  ELSE IF( lwork.LT.max( 1, n ) .AND. .NOT.lquery ) THEN
173  info = -13
174  END IF
175  IF( info.NE.0 ) THEN
176  CALL xerbla( 'DHSEQR', -info )
177  RETURN
178  ELSE IF( lquery ) THEN
179  RETURN
180  END IF
181 *
182 * Initialize Z, if necessary
183 *
184  IF( initz )
185  $ CALL dlaset( 'Full', n, n, zero, one, z, ldz )
186 *
187 * Store the eigenvalues isolated by DGEBAL.
188 *
189  DO 10 i = 1, ilo - 1
190  wr( i ) = h( i, i )
191  wi( i ) = zero
192  10 CONTINUE
193  DO 20 i = ihi + 1, n
194  wr( i ) = h( i, i )
195  wi( i ) = zero
196  20 CONTINUE
197 *
198 * Quick return if possible.
199 *
200  IF( n.EQ.0 )
201  $ RETURN
202  IF( ilo.EQ.ihi ) THEN
203  wr( ilo ) = h( ilo, ilo )
204  wi( ilo ) = zero
205  RETURN
206  END IF
207 *
208 * Set rows and columns ILO to IHI to zero below the first
209 * subdiagonal.
210 *
211  DO 40 j = ilo, ihi - 2
212  DO 30 i = j + 2, n
213  h( i, j ) = zero
214  30 CONTINUE
215  40 CONTINUE
216  nh = ihi - ilo + 1
217 *
218 * Determine the order of the multi-shift QR algorithm to be used.
219 *
220  ns = ilaenv( 4, 'DHSEQR', job // compz, n, ilo, ihi, -1 )
221  maxb = ilaenv( 8, 'DHSEQR', job // compz, n, ilo, ihi, -1 )
222  IF( ns.LE.2 .OR. ns.GT.nh .OR. maxb.GE.nh ) THEN
223 *
224 * Use the standard double-shift algorithm
225 *
226  CALL dlahqr( wantt, wantz, n, ilo, ihi, h, ldh, wr, wi, ilo,
227  $ ihi, z, ldz, info )
228  RETURN
229  END IF
230  maxb = max( 3, maxb )
231  ns = min( ns, maxb, nsmax )
232 *
233 * Now 2 < NS <= MAXB < NH.
234 *
235 * Set machine-dependent constants for the stopping criterion.
236 * If norm(H) <= sqrt(OVFL), overflow should not occur.
237 *
238  unfl = dlamch( 'Safe minimum' )
239  ovfl = one / unfl
240  CALL dlabad( unfl, ovfl )
241  ulp = dlamch( 'Precision' )
242  smlnum = unfl*( nh / ulp )
243 *
244 * I1 and I2 are the indices of the first row and last column of H
245 * to which transformations must be applied. If eigenvalues only are
246 * being computed, I1 and I2 are set inside the main loop.
247 *
248  IF( wantt ) THEN
249  i1 = 1
250  i2 = n
251  END IF
252 *
253 * ITN is the total number of multiple-shift QR iterations allowed.
254 *
255  itn = 30*nh
256 *
257 * The main loop begins here. I is the loop index and decreases from
258 * IHI to ILO in steps of at most MAXB. Each iteration of the loop
259 * works with the active submatrix in rows and columns L to I.
260 * Eigenvalues I+1 to IHI have already converged. Either L = ILO or
261 * H(L,L-1) is negligible so that the matrix splits.
262 *
263  i = ihi
264  50 CONTINUE
265  l = ilo
266  IF( i.LT.ilo )
267  $ GO TO 170
268 *
269 * Perform multiple-shift QR iterations on rows and columns ILO to I
270 * until a submatrix of order at most MAXB splits off at the bottom
271 * because a subdiagonal element has become negligible.
272 *
273  DO 150 its = 0, itn
274 *
275 * Look for a single small subdiagonal element.
276 *
277  DO 60 k = i, l + 1, -1
278  tst1 = abs( h( k-1, k-1 ) ) + abs( h( k, k ) )
279  IF( tst1.EQ.zero )
280  $ tst1 = dlanhs( '1', i-l+1, h( l, l ), ldh, work )
281  IF( abs( h( k, k-1 ) ).LE.max( ulp*tst1, smlnum ) )
282  $ GO TO 70
283  60 CONTINUE
284  70 CONTINUE
285  l = k
286  IF( l.GT.ilo ) THEN
287 *
288 * H(L,L-1) is negligible.
289 *
290  h( l, l-1 ) = zero
291  END IF
292 *
293 * Exit from loop if a submatrix of order <= MAXB has split off.
294 *
295  IF( l.GE.i-maxb+1 )
296  $ GO TO 160
297 *
298 * Now the active submatrix is in rows and columns L to I. If
299 * eigenvalues only are being computed, only the active submatrix
300 * need be transformed.
301 *
302  IF( .NOT.wantt ) THEN
303  i1 = l
304  i2 = i
305  END IF
306 *
307  IF( its.EQ.20 .OR. its.EQ.30 ) THEN
308 *
309 * Exceptional shifts.
310 *
311  DO 80 ii = i - ns + 1, i
312  wr( ii ) = const*( abs( h( ii, ii-1 ) )+
313  $ abs( h( ii, ii ) ) )
314  wi( ii ) = zero
315  80 CONTINUE
316  ELSE
317 *
318 * Use eigenvalues of trailing submatrix of order NS as shifts.
319 *
320  CALL dlacpy( 'Full', ns, ns, h( i-ns+1, i-ns+1 ), ldh, s,
321  $ lds )
322  CALL dlahqr( .false., .false., ns, 1, ns, s, lds,
323  $ wr( i-ns+1 ), wi( i-ns+1 ), 1, ns, z, ldz,
324  $ ierr )
325  IF( ierr.GT.0 ) THEN
326 *
327 * If DLAHQR failed to compute all NS eigenvalues, use the
328 * unconverged diagonal elements as the remaining shifts.
329 *
330  DO 90 ii = 1, ierr
331  wr( i-ns+ii ) = s( ii, ii )
332  wi( i-ns+ii ) = zero
333  90 CONTINUE
334  END IF
335  END IF
336 *
337 * Form the first column of (G-w(1)) (G-w(2)) . . . (G-w(ns))
338 * where G is the Hessenberg submatrix H(L:I,L:I) and w is
339 * the vector of shifts (stored in WR and WI). The result is
340 * stored in the local array V.
341 *
342  v( 1 ) = one
343  DO 100 ii = 2, ns + 1
344  v( ii ) = zero
345  100 CONTINUE
346  nv = 1
347  DO 120 j = i - ns + 1, i
348  IF( wi( j ).GE.zero ) THEN
349  IF( wi( j ).EQ.zero ) THEN
350 *
351 * real shift
352 *
353  CALL dcopy( nv+1, v, 1, vv, 1 )
354  CALL dgemv( 'No transpose', nv+1, nv, one, h( l, l ),
355  $ ldh, vv, 1, -wr( j ), v, 1 )
356  nv = nv + 1
357  ELSE IF( wi( j ).GT.zero ) THEN
358 *
359 * complex conjugate pair of shifts
360 *
361  CALL dcopy( nv+1, v, 1, vv, 1 )
362  CALL dgemv( 'No transpose', nv+1, nv, one, h( l, l ),
363  $ ldh, v, 1, -two*wr( j ), vv, 1 )
364  itemp = idamax( nv+1, vv, 1 )
365  temp = one / max( abs( vv( itemp ) ), smlnum )
366  CALL dscal( nv+1, temp, vv, 1 )
367  absw = dlapy2( wr( j ), wi( j ) )
368  temp = ( temp*absw )*absw
369  CALL dgemv( 'No transpose', nv+2, nv+1, one,
370  $ h( l, l ), ldh, vv, 1, temp, v, 1 )
371  nv = nv + 2
372  END IF
373 *
374 * Scale V(1:NV) so that max(abs(V(i))) = 1. If V is zero,
375 * reset it to the unit vector.
376 *
377  itemp = idamax( nv, v, 1 )
378  temp = abs( v( itemp ) )
379  IF( temp.EQ.zero ) THEN
380  v( 1 ) = one
381  DO 110 ii = 2, nv
382  v( ii ) = zero
383  110 CONTINUE
384  ELSE
385  temp = max( temp, smlnum )
386  CALL dscal( nv, one / temp, v, 1 )
387  END IF
388  END IF
389  120 CONTINUE
390 *
391 * Multiple-shift QR step
392 *
393  DO 140 k = l, i - 1
394 *
395 * The first iteration of this loop determines a reflection G
396 * from the vector V and applies it from left and right to H,
397 * thus creating a nonzero bulge below the subdiagonal.
398 *
399 * Each subsequent iteration determines a reflection G to
400 * restore the Hessenberg form in the (K-1)th column, and thus
401 * chases the bulge one step toward the bottom of the active
402 * submatrix. NR is the order of G.
403 *
404  nr = min( ns+1, i-k+1 )
405  IF( k.GT.l )
406  $ CALL dcopy( nr, h( k, k-1 ), 1, v, 1 )
407  CALL dlarfg( nr, v( 1 ), v( 2 ), 1, tau )
408  IF( k.GT.l ) THEN
409  h( k, k-1 ) = v( 1 )
410  DO 130 ii = k + 1, i
411  h( ii, k-1 ) = zero
412  130 CONTINUE
413  END IF
414  v( 1 ) = one
415 *
416 * Apply G from the left to transform the rows of the matrix in
417 * columns K to I2.
418 *
419  CALL dlarfx( 'Left', nr, i2-k+1, v, tau, h( k, k ), ldh,
420  $ work )
421 *
422 * Apply G from the right to transform the columns of the
423 * matrix in rows I1 to min(K+NR,I).
424 *
425  CALL dlarfx( 'Right', min( k+nr, i )-i1+1, nr, v, tau,
426  $ h( i1, k ), ldh, work )
427 *
428  IF( wantz ) THEN
429 *
430 * Accumulate transformations in the matrix Z
431 *
432  CALL dlarfx( 'Right', nh, nr, v, tau, z( ilo, k ), ldz,
433  $ work )
434  END IF
435  140 CONTINUE
436 *
437  150 CONTINUE
438 *
439 * Failure to converge in remaining number of iterations
440 *
441  info = i
442  RETURN
443 *
444  160 CONTINUE
445 *
446 * A submatrix of order <= MAXB in rows and columns L to I has split
447 * off. Use the double-shift QR algorithm to handle it.
448 *
449  CALL dlahqr( wantt, wantz, n, l, i, h, ldh, wr, wi, ilo, ihi, z,
450  $ ldz, info )
451  IF( info.GT.0 )
452  $ RETURN
453 *
454 * Decrement number of remaining iterations, and return to start of
455 * the main loop with a new value of I.
456 *
457  itn = itn - its
458  i = l - 1
459  GO TO 50
460 *
461  170 CONTINUE
462  work( 1 ) = max( 1, n )
463  RETURN
464 *
465 * End of DHSEQR
466 *
467  END
subroutine dcopy(n, dx, incx, dy, incy)
Definition: dcopy.f:2
subroutine dgemv(TRANS, M, N, ALPHA, A, LDA, X, INCX, BETA, Y, INCY)
Definition: dgemv.f:3
subroutine dhseqr(JOB, COMPZ, N, ILO, IHI, H, LDH, WR, WI, Z, LDZ, WORK, LWORK, INFO)
Definition: dhseqr.f:3
subroutine dlabad(SMALL, LARGE)
Definition: dlabad.f:2
subroutine dlacpy(UPLO, M, N, A, LDA, B, LDB)
Definition: dlacpy.f:2
subroutine dlahqr(WANTT, WANTZ, N, ILO, IHI, H, LDH, WR, WI, ILOZ, IHIZ, Z, LDZ, INFO)
Definition: dlahqr.f:3
subroutine dlarfg(N, ALPHA, X, INCX, TAU)
Definition: dlarfg.f:2
subroutine dlarfx(SIDE, M, N, V, TAU, C, LDC, WORK)
Definition: dlarfx.f:2
subroutine dlaset(UPLO, M, N, ALPHA, BETA, A, LDA)
Definition: dlaset.f:2
subroutine dscal(n, da, dx, incx)
Definition: dscal.f:2
subroutine xerbla(SRNAME, INFO)
Definition: xerbla.f:2