Annotation of rpl/lapack/lapack/dhsein.f, revision 1.18
1.8 bertrand 1: *> \brief \b DHSEIN
2: *
3: * =========== DOCUMENTATION ===========
4: *
1.15 bertrand 5: * Online html documentation available at
6: * http://www.netlib.org/lapack/explore-html/
1.8 bertrand 7: *
8: *> \htmlonly
1.15 bertrand 9: *> Download DHSEIN + dependencies
10: *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dhsein.f">
11: *> [TGZ]</a>
12: *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dhsein.f">
13: *> [ZIP]</a>
14: *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dhsein.f">
1.8 bertrand 15: *> [TXT]</a>
1.15 bertrand 16: *> \endhtmlonly
1.8 bertrand 17: *
18: * Definition:
19: * ===========
20: *
21: * SUBROUTINE DHSEIN( SIDE, EIGSRC, INITV, SELECT, N, H, LDH, WR, WI,
22: * VL, LDVL, VR, LDVR, MM, M, WORK, IFAILL,
23: * IFAILR, INFO )
1.15 bertrand 24: *
1.8 bertrand 25: * .. Scalar Arguments ..
26: * CHARACTER EIGSRC, INITV, SIDE
27: * INTEGER INFO, LDH, LDVL, LDVR, M, MM, N
28: * ..
29: * .. Array Arguments ..
30: * LOGICAL SELECT( * )
31: * INTEGER IFAILL( * ), IFAILR( * )
32: * DOUBLE PRECISION H( LDH, * ), VL( LDVL, * ), VR( LDVR, * ),
33: * $ WI( * ), WORK( * ), WR( * )
34: * ..
1.15 bertrand 35: *
1.8 bertrand 36: *
37: *> \par Purpose:
38: * =============
39: *>
40: *> \verbatim
41: *>
42: *> DHSEIN uses inverse iteration to find specified right and/or left
43: *> eigenvectors of a real upper Hessenberg matrix H.
44: *>
45: *> The right eigenvector x and the left eigenvector y of the matrix H
46: *> corresponding to an eigenvalue w are defined by:
47: *>
48: *> H * x = w * x, y**h * H = w * y**h
49: *>
50: *> where y**h denotes the conjugate transpose of the vector y.
51: *> \endverbatim
52: *
53: * Arguments:
54: * ==========
55: *
56: *> \param[in] SIDE
57: *> \verbatim
58: *> SIDE is CHARACTER*1
59: *> = 'R': compute right eigenvectors only;
60: *> = 'L': compute left eigenvectors only;
61: *> = 'B': compute both right and left eigenvectors.
62: *> \endverbatim
63: *>
64: *> \param[in] EIGSRC
65: *> \verbatim
66: *> EIGSRC is CHARACTER*1
67: *> Specifies the source of eigenvalues supplied in (WR,WI):
68: *> = 'Q': the eigenvalues were found using DHSEQR; thus, if
69: *> H has zero subdiagonal elements, and so is
70: *> block-triangular, then the j-th eigenvalue can be
71: *> assumed to be an eigenvalue of the block containing
72: *> the j-th row/column. This property allows DHSEIN to
73: *> perform inverse iteration on just one diagonal block.
74: *> = 'N': no assumptions are made on the correspondence
75: *> between eigenvalues and diagonal blocks. In this
76: *> case, DHSEIN must always perform inverse iteration
77: *> using the whole matrix H.
78: *> \endverbatim
79: *>
80: *> \param[in] INITV
81: *> \verbatim
82: *> INITV is CHARACTER*1
83: *> = 'N': no initial vectors are supplied;
84: *> = 'U': user-supplied initial vectors are stored in the arrays
85: *> VL and/or VR.
86: *> \endverbatim
87: *>
88: *> \param[in,out] SELECT
89: *> \verbatim
90: *> SELECT is LOGICAL array, dimension (N)
91: *> Specifies the eigenvectors to be computed. To select the
92: *> real eigenvector corresponding to a real eigenvalue WR(j),
93: *> SELECT(j) must be set to .TRUE.. To select the complex
94: *> eigenvector corresponding to a complex eigenvalue
95: *> (WR(j),WI(j)), with complex conjugate (WR(j+1),WI(j+1)),
96: *> either SELECT(j) or SELECT(j+1) or both must be set to
97: *> .TRUE.; then on exit SELECT(j) is .TRUE. and SELECT(j+1) is
98: *> .FALSE..
99: *> \endverbatim
100: *>
101: *> \param[in] N
102: *> \verbatim
103: *> N is INTEGER
104: *> The order of the matrix H. N >= 0.
105: *> \endverbatim
106: *>
107: *> \param[in] H
108: *> \verbatim
109: *> H is DOUBLE PRECISION array, dimension (LDH,N)
110: *> The upper Hessenberg matrix H.
1.12 bertrand 111: *> If a NaN is detected in H, the routine will return with INFO=-6.
1.8 bertrand 112: *> \endverbatim
113: *>
114: *> \param[in] LDH
115: *> \verbatim
116: *> LDH is INTEGER
117: *> The leading dimension of the array H. LDH >= max(1,N).
118: *> \endverbatim
119: *>
120: *> \param[in,out] WR
121: *> \verbatim
122: *> WR is DOUBLE PRECISION array, dimension (N)
123: *> \endverbatim
124: *>
125: *> \param[in] WI
126: *> \verbatim
127: *> WI is DOUBLE PRECISION array, dimension (N)
128: *>
129: *> On entry, the real and imaginary parts of the eigenvalues of
130: *> H; a complex conjugate pair of eigenvalues must be stored in
131: *> consecutive elements of WR and WI.
132: *> On exit, WR may have been altered since close eigenvalues
133: *> are perturbed slightly in searching for independent
134: *> eigenvectors.
135: *> \endverbatim
136: *>
137: *> \param[in,out] VL
138: *> \verbatim
139: *> VL is DOUBLE PRECISION array, dimension (LDVL,MM)
140: *> On entry, if INITV = 'U' and SIDE = 'L' or 'B', VL must
141: *> contain starting vectors for the inverse iteration for the
142: *> left eigenvectors; the starting vector for each eigenvector
143: *> must be in the same column(s) in which the eigenvector will
144: *> be stored.
145: *> On exit, if SIDE = 'L' or 'B', the left eigenvectors
146: *> specified by SELECT will be stored consecutively in the
147: *> columns of VL, in the same order as their eigenvalues. A
148: *> complex eigenvector corresponding to a complex eigenvalue is
149: *> stored in two consecutive columns, the first holding the real
150: *> part and the second the imaginary part.
151: *> If SIDE = 'R', VL is not referenced.
152: *> \endverbatim
153: *>
154: *> \param[in] LDVL
155: *> \verbatim
156: *> LDVL is INTEGER
157: *> The leading dimension of the array VL.
158: *> LDVL >= max(1,N) if SIDE = 'L' or 'B'; LDVL >= 1 otherwise.
159: *> \endverbatim
160: *>
161: *> \param[in,out] VR
162: *> \verbatim
163: *> VR is DOUBLE PRECISION array, dimension (LDVR,MM)
164: *> On entry, if INITV = 'U' and SIDE = 'R' or 'B', VR must
165: *> contain starting vectors for the inverse iteration for the
166: *> right eigenvectors; the starting vector for each eigenvector
167: *> must be in the same column(s) in which the eigenvector will
168: *> be stored.
169: *> On exit, if SIDE = 'R' or 'B', the right eigenvectors
170: *> specified by SELECT will be stored consecutively in the
171: *> columns of VR, in the same order as their eigenvalues. A
172: *> complex eigenvector corresponding to a complex eigenvalue is
173: *> stored in two consecutive columns, the first holding the real
174: *> part and the second the imaginary part.
175: *> If SIDE = 'L', VR is not referenced.
176: *> \endverbatim
177: *>
178: *> \param[in] LDVR
179: *> \verbatim
180: *> LDVR is INTEGER
181: *> The leading dimension of the array VR.
182: *> LDVR >= max(1,N) if SIDE = 'R' or 'B'; LDVR >= 1 otherwise.
183: *> \endverbatim
184: *>
185: *> \param[in] MM
186: *> \verbatim
187: *> MM is INTEGER
188: *> The number of columns in the arrays VL and/or VR. MM >= M.
189: *> \endverbatim
190: *>
191: *> \param[out] M
192: *> \verbatim
193: *> M is INTEGER
194: *> The number of columns in the arrays VL and/or VR required to
195: *> store the eigenvectors; each selected real eigenvector
196: *> occupies one column and each selected complex eigenvector
197: *> occupies two columns.
198: *> \endverbatim
199: *>
200: *> \param[out] WORK
201: *> \verbatim
202: *> WORK is DOUBLE PRECISION array, dimension ((N+2)*N)
203: *> \endverbatim
204: *>
205: *> \param[out] IFAILL
206: *> \verbatim
207: *> IFAILL is INTEGER array, dimension (MM)
208: *> If SIDE = 'L' or 'B', IFAILL(i) = j > 0 if the left
209: *> eigenvector in the i-th column of VL (corresponding to the
210: *> eigenvalue w(j)) failed to converge; IFAILL(i) = 0 if the
211: *> eigenvector converged satisfactorily. If the i-th and (i+1)th
212: *> columns of VL hold a complex eigenvector, then IFAILL(i) and
213: *> IFAILL(i+1) are set to the same value.
214: *> If SIDE = 'R', IFAILL is not referenced.
215: *> \endverbatim
216: *>
217: *> \param[out] IFAILR
218: *> \verbatim
219: *> IFAILR is INTEGER array, dimension (MM)
220: *> If SIDE = 'R' or 'B', IFAILR(i) = j > 0 if the right
221: *> eigenvector in the i-th column of VR (corresponding to the
222: *> eigenvalue w(j)) failed to converge; IFAILR(i) = 0 if the
223: *> eigenvector converged satisfactorily. If the i-th and (i+1)th
224: *> columns of VR hold a complex eigenvector, then IFAILR(i) and
225: *> IFAILR(i+1) are set to the same value.
226: *> If SIDE = 'L', IFAILR is not referenced.
227: *> \endverbatim
228: *>
229: *> \param[out] INFO
230: *> \verbatim
231: *> INFO is INTEGER
232: *> = 0: successful exit
233: *> < 0: if INFO = -i, the i-th argument had an illegal value
234: *> > 0: if INFO = i, i is the number of eigenvectors which
235: *> failed to converge; see IFAILL and IFAILR for further
236: *> details.
237: *> \endverbatim
238: *
239: * Authors:
240: * ========
241: *
1.15 bertrand 242: *> \author Univ. of Tennessee
243: *> \author Univ. of California Berkeley
244: *> \author Univ. of Colorado Denver
245: *> \author NAG Ltd.
1.8 bertrand 246: *
247: *> \ingroup doubleOTHERcomputational
248: *
249: *> \par Further Details:
250: * =====================
251: *>
252: *> \verbatim
253: *>
254: *> Each eigenvector is normalized so that the element of largest
255: *> magnitude has magnitude 1; here the magnitude of a complex number
256: *> (x,y) is taken to be |x|+|y|.
257: *> \endverbatim
258: *>
259: * =====================================================================
1.1 bertrand 260: SUBROUTINE DHSEIN( SIDE, EIGSRC, INITV, SELECT, N, H, LDH, WR, WI,
261: $ VL, LDVL, VR, LDVR, MM, M, WORK, IFAILL,
262: $ IFAILR, INFO )
263: *
1.18 ! bertrand 264: * -- LAPACK computational routine --
1.1 bertrand 265: * -- LAPACK is a software package provided by Univ. of Tennessee, --
266: * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
267: *
268: * .. Scalar Arguments ..
269: CHARACTER EIGSRC, INITV, SIDE
270: INTEGER INFO, LDH, LDVL, LDVR, M, MM, N
271: * ..
272: * .. Array Arguments ..
273: LOGICAL SELECT( * )
274: INTEGER IFAILL( * ), IFAILR( * )
275: DOUBLE PRECISION H( LDH, * ), VL( LDVL, * ), VR( LDVR, * ),
276: $ WI( * ), WORK( * ), WR( * )
277: * ..
278: *
279: * =====================================================================
280: *
281: * .. Parameters ..
282: DOUBLE PRECISION ZERO, ONE
283: PARAMETER ( ZERO = 0.0D+0, ONE = 1.0D+0 )
284: * ..
285: * .. Local Scalars ..
286: LOGICAL BOTHV, FROMQR, LEFTV, NOINIT, PAIR, RIGHTV
287: INTEGER I, IINFO, K, KL, KLN, KR, KSI, KSR, LDWORK
288: DOUBLE PRECISION BIGNUM, EPS3, HNORM, SMLNUM, ULP, UNFL, WKI,
289: $ WKR
290: * ..
291: * .. External Functions ..
1.12 bertrand 292: LOGICAL LSAME, DISNAN
1.1 bertrand 293: DOUBLE PRECISION DLAMCH, DLANHS
1.12 bertrand 294: EXTERNAL LSAME, DLAMCH, DLANHS, DISNAN
1.1 bertrand 295: * ..
296: * .. External Subroutines ..
297: EXTERNAL DLAEIN, XERBLA
298: * ..
299: * .. Intrinsic Functions ..
300: INTRINSIC ABS, MAX
301: * ..
302: * .. Executable Statements ..
303: *
304: * Decode and test the input parameters.
305: *
306: BOTHV = LSAME( SIDE, 'B' )
307: RIGHTV = LSAME( SIDE, 'R' ) .OR. BOTHV
308: LEFTV = LSAME( SIDE, 'L' ) .OR. BOTHV
309: *
310: FROMQR = LSAME( EIGSRC, 'Q' )
311: *
312: NOINIT = LSAME( INITV, 'N' )
313: *
314: * Set M to the number of columns required to store the selected
315: * eigenvectors, and standardize the array SELECT.
316: *
317: M = 0
318: PAIR = .FALSE.
319: DO 10 K = 1, N
320: IF( PAIR ) THEN
321: PAIR = .FALSE.
322: SELECT( K ) = .FALSE.
323: ELSE
324: IF( WI( K ).EQ.ZERO ) THEN
325: IF( SELECT( K ) )
326: $ M = M + 1
327: ELSE
328: PAIR = .TRUE.
329: IF( SELECT( K ) .OR. SELECT( K+1 ) ) THEN
330: SELECT( K ) = .TRUE.
331: M = M + 2
332: END IF
333: END IF
334: END IF
335: 10 CONTINUE
336: *
337: INFO = 0
338: IF( .NOT.RIGHTV .AND. .NOT.LEFTV ) THEN
339: INFO = -1
340: ELSE IF( .NOT.FROMQR .AND. .NOT.LSAME( EIGSRC, 'N' ) ) THEN
341: INFO = -2
342: ELSE IF( .NOT.NOINIT .AND. .NOT.LSAME( INITV, 'U' ) ) THEN
343: INFO = -3
344: ELSE IF( N.LT.0 ) THEN
345: INFO = -5
346: ELSE IF( LDH.LT.MAX( 1, N ) ) THEN
347: INFO = -7
348: ELSE IF( LDVL.LT.1 .OR. ( LEFTV .AND. LDVL.LT.N ) ) THEN
349: INFO = -11
350: ELSE IF( LDVR.LT.1 .OR. ( RIGHTV .AND. LDVR.LT.N ) ) THEN
351: INFO = -13
352: ELSE IF( MM.LT.M ) THEN
353: INFO = -14
354: END IF
355: IF( INFO.NE.0 ) THEN
356: CALL XERBLA( 'DHSEIN', -INFO )
357: RETURN
358: END IF
359: *
360: * Quick return if possible.
361: *
362: IF( N.EQ.0 )
363: $ RETURN
364: *
365: * Set machine-dependent constants.
366: *
367: UNFL = DLAMCH( 'Safe minimum' )
368: ULP = DLAMCH( 'Precision' )
369: SMLNUM = UNFL*( N / ULP )
370: BIGNUM = ( ONE-ULP ) / SMLNUM
371: *
372: LDWORK = N + 1
373: *
374: KL = 1
375: KLN = 0
376: IF( FROMQR ) THEN
377: KR = 0
378: ELSE
379: KR = N
380: END IF
381: KSR = 1
382: *
383: DO 120 K = 1, N
384: IF( SELECT( K ) ) THEN
385: *
386: * Compute eigenvector(s) corresponding to W(K).
387: *
388: IF( FROMQR ) THEN
389: *
390: * If affiliation of eigenvalues is known, check whether
391: * the matrix splits.
392: *
393: * Determine KL and KR such that 1 <= KL <= K <= KR <= N
394: * and H(KL,KL-1) and H(KR+1,KR) are zero (or KL = 1 or
395: * KR = N).
396: *
397: * Then inverse iteration can be performed with the
398: * submatrix H(KL:N,KL:N) for a left eigenvector, and with
399: * the submatrix H(1:KR,1:KR) for a right eigenvector.
400: *
401: DO 20 I = K, KL + 1, -1
402: IF( H( I, I-1 ).EQ.ZERO )
403: $ GO TO 30
404: 20 CONTINUE
405: 30 CONTINUE
406: KL = I
407: IF( K.GT.KR ) THEN
408: DO 40 I = K, N - 1
409: IF( H( I+1, I ).EQ.ZERO )
410: $ GO TO 50
411: 40 CONTINUE
412: 50 CONTINUE
413: KR = I
414: END IF
415: END IF
416: *
417: IF( KL.NE.KLN ) THEN
418: KLN = KL
419: *
420: * Compute infinity-norm of submatrix H(KL:KR,KL:KR) if it
421: * has not ben computed before.
422: *
423: HNORM = DLANHS( 'I', KR-KL+1, H( KL, KL ), LDH, WORK )
1.12 bertrand 424: IF( DISNAN( HNORM ) ) THEN
425: INFO = -6
426: RETURN
427: ELSE IF( HNORM.GT.ZERO ) THEN
1.1 bertrand 428: EPS3 = HNORM*ULP
429: ELSE
430: EPS3 = SMLNUM
431: END IF
432: END IF
433: *
434: * Perturb eigenvalue if it is close to any previous
435: * selected eigenvalues affiliated to the submatrix
436: * H(KL:KR,KL:KR). Close roots are modified by EPS3.
437: *
438: WKR = WR( K )
439: WKI = WI( K )
440: 60 CONTINUE
441: DO 70 I = K - 1, KL, -1
442: IF( SELECT( I ) .AND. ABS( WR( I )-WKR )+
443: $ ABS( WI( I )-WKI ).LT.EPS3 ) THEN
444: WKR = WKR + EPS3
445: GO TO 60
446: END IF
447: 70 CONTINUE
448: WR( K ) = WKR
449: *
450: PAIR = WKI.NE.ZERO
451: IF( PAIR ) THEN
452: KSI = KSR + 1
453: ELSE
454: KSI = KSR
455: END IF
456: IF( LEFTV ) THEN
457: *
458: * Compute left eigenvector.
459: *
460: CALL DLAEIN( .FALSE., NOINIT, N-KL+1, H( KL, KL ), LDH,
461: $ WKR, WKI, VL( KL, KSR ), VL( KL, KSI ),
462: $ WORK, LDWORK, WORK( N*N+N+1 ), EPS3, SMLNUM,
463: $ BIGNUM, IINFO )
464: IF( IINFO.GT.0 ) THEN
465: IF( PAIR ) THEN
466: INFO = INFO + 2
467: ELSE
468: INFO = INFO + 1
469: END IF
470: IFAILL( KSR ) = K
471: IFAILL( KSI ) = K
472: ELSE
473: IFAILL( KSR ) = 0
474: IFAILL( KSI ) = 0
475: END IF
476: DO 80 I = 1, KL - 1
477: VL( I, KSR ) = ZERO
478: 80 CONTINUE
479: IF( PAIR ) THEN
480: DO 90 I = 1, KL - 1
481: VL( I, KSI ) = ZERO
482: 90 CONTINUE
483: END IF
484: END IF
485: IF( RIGHTV ) THEN
486: *
487: * Compute right eigenvector.
488: *
489: CALL DLAEIN( .TRUE., NOINIT, KR, H, LDH, WKR, WKI,
490: $ VR( 1, KSR ), VR( 1, KSI ), WORK, LDWORK,
491: $ WORK( N*N+N+1 ), EPS3, SMLNUM, BIGNUM,
492: $ IINFO )
493: IF( IINFO.GT.0 ) THEN
494: IF( PAIR ) THEN
495: INFO = INFO + 2
496: ELSE
497: INFO = INFO + 1
498: END IF
499: IFAILR( KSR ) = K
500: IFAILR( KSI ) = K
501: ELSE
502: IFAILR( KSR ) = 0
503: IFAILR( KSI ) = 0
504: END IF
505: DO 100 I = KR + 1, N
506: VR( I, KSR ) = ZERO
507: 100 CONTINUE
508: IF( PAIR ) THEN
509: DO 110 I = KR + 1, N
510: VR( I, KSI ) = ZERO
511: 110 CONTINUE
512: END IF
513: END IF
514: *
515: IF( PAIR ) THEN
516: KSR = KSR + 2
517: ELSE
518: KSR = KSR + 1
519: END IF
520: END IF
521: 120 CONTINUE
522: *
523: RETURN
524: *
525: * End of DHSEIN
526: *
527: END
CVSweb interface <joel.bertrand@systella.fr>