1
SUBROUTINE SB04RX( RC, UL, M, A, LDA, LAMBD1, LAMBD2, LAMBD3,
2
$ LAMBD4, D, TOL, IWORK, DWORK, LDDWOR, INFO )
4
C RELEASE 4.0, WGS COPYRIGHT 2000.
8
C To solve a system of equations in quasi-Hessenberg form
9
C (Hessenberg form plus two consecutive offdiagonals) with two
17
C Indicates processing by columns or rows, as follows:
18
C = 'R': Row transformations are applied;
19
C = 'C': Column transformations are applied.
22
C Indicates whether A is upper or lower Hessenberg matrix,
24
C = 'U': A is upper Hessenberg;
25
C = 'L': A is lower Hessenberg.
27
C Input/Output Parameters
30
C The order of the matrix A. M >= 0.
32
C A (input) DOUBLE PRECISION array, dimension (LDA,M)
33
C The leading M-by-M part of this array must contain a
34
C matrix A in Hessenberg form.
37
C The leading dimension of array A. LDA >= MAX(1,M).
39
C LAMBD1, (input) DOUBLE PRECISION
40
C LAMBD2, These variables must contain the 2-by-2 block to be
41
C LAMBD3, multiplied to the elements of A.
44
C D (input/output) DOUBLE PRECISION array, dimension (2*M)
45
C On entry, this array must contain the two right-hand
46
C side vectors of the quasi-Hessenberg system, stored
48
C On exit, if INFO = 0, this array contains the two solution
49
C vectors of the quasi-Hessenberg system, stored row-wise.
53
C TOL DOUBLE PRECISION
54
C The tolerance to be used to test for near singularity of
55
C the triangular factor R of the quasi-Hessenberg matrix.
56
C A matrix whose estimated condition number is less
57
C than 1/TOL is considered to be nonsingular.
61
C IWORK INTEGER array, dimension (2*M)
63
C DWORK DOUBLE PRECISION array, dimension (LDDWOR,2*M+3)
64
C The leading 2*M-by-2*M part of this array is used for
65
C computing the triangular factor of the QR decomposition
66
C of the quasi-Hessenberg matrix. The remaining 6*M elements
67
C are used as workspace for the computation of the
68
C reciprocal condition estimate.
71
C The leading dimension of array DWORK.
72
C LDDWOR >= MAX(1,2*M).
77
C = 0: successful exit;
78
C = 1: if the quasi-Hessenberg matrix is (numerically)
79
C singular. That is, its estimated reciprocal
80
C condition number is less than or equal to TOL.
88
C D. Sima, University of Bucharest, May 2000.
94
C Note that RC, UL, M, LDA, and LDDWOR must be such that the value
95
C of the LOGICAL variable OK in the following statement is true.
97
C OK = ( ( UL.EQ.'U' ) .OR. ( UL.EQ.'u' ) .OR.
98
C ( UL.EQ.'L' ) .OR. ( UL.EQ.'l' ) )
100
C ( ( RC.EQ.'R' ) .OR. ( RC.EQ.'r' ) .OR.
101
C ( RC.EQ.'C' ) .OR. ( RC.EQ.'c' ) )
105
C ( LDA.GE.MAX( 1, M ) )
107
C ( LDDWOR.GE.MAX( 1, 2*M ) )
109
C These conditions are not checked by the routine.
113
C Hessenberg form, orthogonal transformation, real Schur form,
114
C Sylvester equation.
116
C ******************************************************************
118
DOUBLE PRECISION ONE, ZERO
119
PARAMETER ( ONE = 1.0D0, ZERO = 0.0D0 )
120
C .. Scalar Arguments ..
122
INTEGER INFO, LDA, LDDWOR, M
123
DOUBLE PRECISION LAMBD1, LAMBD2, LAMBD3, LAMBD4, TOL
124
C .. Array Arguments ..
126
DOUBLE PRECISION A(LDA,*), D(*), DWORK(LDDWOR,*)
127
C .. Local Scalars ..
129
INTEGER J, J1, J2, M2, MJ, ML
130
DOUBLE PRECISION C, R, RCOND, S
131
C .. External Functions ..
134
C .. External Subroutines ..
135
EXTERNAL DCOPY, DLARTG, DLASET, DROT, DSCAL, DTRCON,
137
C .. Intrinsic Functions ..
138
INTRINSIC MAX, MIN, MOD
139
C .. Executable Statements ..
143
C For speed, no tests on the input scalar arguments are made.
144
C Quick return if possible.
150
IF ( LSAME( UL, 'U' ) ) THEN
155
CALL DLASET( 'Full', M2, 2, ZERO, ZERO, DWORK(1,J2-1),
157
CALL DCOPY( ML, A(1,J), 1, DWORK(1,J2-1), 2 )
158
CALL DSCAL( ML, LAMBD1, DWORK(1,J2-1), 2 )
159
CALL DCOPY( ML, A(1,J), 1, DWORK(2,J2-1), 2 )
160
CALL DSCAL( ML, LAMBD3, DWORK(2,J2-1), 2 )
161
CALL DCOPY( ML, A(1,J), 1, DWORK(1,J2), 2 )
162
CALL DSCAL( ML, LAMBD2, DWORK(1,J2), 2 )
163
CALL DCOPY( ML, A(1,J), 1, DWORK(2,J2), 2 )
164
CALL DSCAL( ML, LAMBD4, DWORK(2,J2), 2 )
166
DWORK(J2-1,J2-1) = DWORK(J2-1,J2-1) + ONE
167
DWORK(J2,J2) = DWORK(J2,J2) + ONE
170
IF ( LSAME( RC, 'R' ) ) THEN
173
C A is an upper Hessenberg matrix, row transformations.
177
IF ( MOD(J,2).EQ.1 .AND. J.LT.M2-2 ) THEN
178
IF ( DWORK(J+3,J).NE.ZERO ) THEN
179
CALL DLARTG( DWORK(J+2,J), DWORK(J+3,J), C, S, R )
182
CALL DROT( MJ, DWORK(J+2,J+1), LDDWOR,
183
$ DWORK(J+3,J+1), LDDWOR, C, S )
184
CALL DROT( 1, D(J+2), 1, D(J+3), 1, C, S )
187
IF ( J.LT.M2-1 ) THEN
188
IF ( DWORK(J+2,J).NE.ZERO ) THEN
189
CALL DLARTG( DWORK(J+1,J), DWORK(J+2,J), C, S, R )
192
CALL DROT( MJ, DWORK(J+1,J+1), LDDWOR,
193
$ DWORK(J+2,J+1), LDDWOR, C, S )
194
CALL DROT( 1, D(J+1), 1, D(J+2), 1, C, S )
197
IF ( DWORK(J+1,J).NE.ZERO ) THEN
198
CALL DLARTG( DWORK(J,J), DWORK(J+1,J), C, S, R )
201
CALL DROT( MJ, DWORK(J,J+1), LDDWOR, DWORK(J+1,J+1),
203
CALL DROT( 1, D(J), 1, D(J+1), 1, C, S )
210
C A is an upper Hessenberg matrix, column transformations.
214
IF ( MOD(J,2).EQ.1 .AND. J.LT.M2-2 ) THEN
215
IF ( DWORK(MJ+1,MJ-2).NE.ZERO ) THEN
216
CALL DLARTG( DWORK(MJ+1,MJ-1), DWORK(MJ+1,MJ-2), C,
219
DWORK(MJ+1,MJ-2) = ZERO
220
CALL DROT( MJ, DWORK(1,MJ-1), 1, DWORK(1,MJ-2), 1,
222
CALL DROT( 1, D(MJ-1), 1, D(MJ-2), 1, C, S )
225
IF ( J.LT.M2-1 ) THEN
226
IF ( DWORK(MJ+1,MJ-1).NE.ZERO ) THEN
227
CALL DLARTG( DWORK(MJ+1,MJ), DWORK(MJ+1,MJ-1), C,
230
DWORK(MJ+1,MJ-1) = ZERO
231
CALL DROT( MJ, DWORK(1,MJ), 1, DWORK(1,MJ-1), 1, C,
233
CALL DROT( 1, D(MJ), 1, D(MJ-1), 1, C, S )
236
IF ( DWORK(MJ+1,MJ).NE.ZERO ) THEN
237
CALL DLARTG( DWORK(MJ+1,MJ+1), DWORK(MJ+1,MJ), C, S,
240
DWORK(MJ+1,MJ) = ZERO
241
CALL DROT( MJ, DWORK(1,MJ+1), 1, DWORK(1,MJ), 1, C,
243
CALL DROT( 1, D(MJ+1), 1, D(MJ), 1, C, S )
253
ML = MIN( M - J + 2, M )
254
CALL DLASET( 'Full', M2, 2, ZERO, ZERO, DWORK(1,J2-1),
256
CALL DCOPY( ML, A(J1,J), 1, DWORK(J1*2-1,J2-1), 2 )
257
CALL DSCAL( ML, LAMBD1, DWORK(J1*2-1,J2-1), 2 )
258
CALL DCOPY( ML, A(J1,J), 1, DWORK(J1*2,J2-1), 2 )
259
CALL DSCAL( ML, LAMBD3, DWORK(J1*2,J2-1), 2 )
260
CALL DCOPY( ML, A(J1,J), 1, DWORK(J1*2-1,J2), 2 )
261
CALL DSCAL( ML, LAMBD2, DWORK(J1*2-1,J2), 2 )
262
CALL DCOPY( ML, A(J1,J), 1, DWORK(J1*2,J2), 2 )
263
CALL DSCAL( ML, LAMBD4, DWORK(J1*2,J2), 2 )
265
DWORK(J2-1,J2-1) = DWORK(J2-1,J2-1) + ONE
266
DWORK(J2,J2) = DWORK(J2,J2) + ONE
269
IF ( LSAME( RC, 'R' ) ) THEN
272
C A is a lower Hessenberg matrix, row transformations.
276
IF ( MOD(J,2).EQ.1 .AND. J.LT.M2-2 ) THEN
277
IF ( DWORK(MJ-2,MJ+1).NE.ZERO ) THEN
278
CALL DLARTG( DWORK(MJ-1,MJ+1), DWORK(MJ-2,MJ+1), C,
281
DWORK(MJ-2,MJ+1) = ZERO
282
CALL DROT( MJ, DWORK(MJ-1,1), LDDWOR,
283
$ DWORK(MJ-2,1), LDDWOR, C, S )
284
CALL DROT( 1, D(MJ-1), 1, D(MJ-2), 1, C, S )
287
IF ( J.LT.M2-1 ) THEN
288
IF ( DWORK(MJ-1,MJ+1).NE.ZERO ) THEN
289
CALL DLARTG( DWORK(MJ,MJ+1), DWORK(MJ-1,MJ+1), C,
292
DWORK(MJ-1,MJ+1) = ZERO
293
CALL DROT( MJ, DWORK(MJ,1), LDDWOR, DWORK(MJ-1,1),
295
CALL DROT( 1, D(MJ), 1, D(MJ-1), 1, C, S )
298
IF ( DWORK(MJ,MJ+1).NE.ZERO ) THEN
299
CALL DLARTG( DWORK(MJ+1,MJ+1), DWORK(MJ,MJ+1), C, S,
302
DWORK(MJ,MJ+1) = ZERO
303
CALL DROT( MJ, DWORK(MJ+1,1), LDDWOR, DWORK(MJ,1),
305
CALL DROT( 1, D(MJ+1), 1, D(MJ), 1, C, S )
312
C A is a lower Hessenberg matrix, column transformations.
316
IF ( MOD(J,2).EQ.1 .AND. J.LT.M2-2 ) THEN
317
IF ( DWORK(J,J+3).NE.ZERO ) THEN
318
CALL DLARTG( DWORK(J,J+2), DWORK(J,J+3), C, S, R )
321
CALL DROT( MJ, DWORK(J+1,J+2), 1, DWORK(J+1,J+3),
323
CALL DROT( 1, D(J+2), 1, D(J+3), 1, C, S )
326
IF ( J.LT.M2-1 ) THEN
327
IF ( DWORK(J,J+2).NE.ZERO ) THEN
328
CALL DLARTG( DWORK(J,J+1), DWORK(J,J+2), C, S, R )
331
CALL DROT( MJ, DWORK(J+1,J+1), 1, DWORK(J+1,J+2),
333
CALL DROT( 1, D(J+1), 1, D(J+2), 1, C, S )
336
IF ( DWORK(J,J+1).NE.ZERO ) THEN
337
CALL DLARTG( DWORK(J,J), DWORK(J,J+1), C, S, R )
340
CALL DROT( MJ, DWORK(J+1,J), 1, DWORK(J+1,J+1), 1, C,
342
CALL DROT( 1, D(J), 1, D(J+1), 1, C, S )
349
CALL DTRCON( '1-norm', UL, 'Non-unit', M2, DWORK, LDDWOR, RCOND,
350
$ DWORK(1,M2+1), IWORK, INFO )
351
IF ( RCOND.LE.TOL ) THEN
354
CALL DTRSV( UL, TRANS, 'Non-unit', M2, DWORK, LDDWOR, D, 1 )
358
C *** Last line of SB04RX ***