1 SUBROUTINE DSYTRS
( UPLO
, N
, NRHS
, A
, LDA
, IPIV
, B
, LDB
, INFO
)
3 * -- LAPACK routine
(version
3.1) --
4 * Univ
. of Tennessee
, Univ
. of California Berkeley and NAG Ltd
..
7 * .. Scalar Arguments
..
9 INTEGER INFO
, LDA
, LDB
, N
, NRHS
11 * .. Array Arguments
..
13 DOUBLE PRECISION A
( LDA
, * ), B
( LDB
, * )
19 * DSYTRS solves a system of linear equations A*X
= B with a
real
20 * symmetric matrix A using the factorization A
= U*D*U**T or
21 * A
= L*D*L**T computed by DSYTRF
.
26 * UPLO
(input
) CHARACTER*1
27 * Specifies whether the details of the factorization are stored
28 * as an upper or lower triangular matrix
.
29 * = 'U': Upper triangular
, form is A
= U*D*U**T
;
30 * = 'L': Lower triangular
, form is A
= L*D*L**T
.
33 * The order of the matrix A
. N
>= 0.
35 * NRHS
(input
) INTEGER
36 * The number of right hand sides
, i
.e
., the number of columns
37 * of the matrix B
. NRHS
>= 0.
39 * A
(input
) DOUBLE PRECISION array
, dimension (LDA
,N
)
40 * The block diagonal matrix D and the multipliers used
to
41 * obtain the factor U or L as computed by DSYTRF
.
44 * The leading
dimension of the array A
. LDA
>= max
(1,N
).
46 * IPIV
(input
) INTEGER array
, dimension (N
)
47 * Details of the interchanges and the block structure of D
48 * as determined by DSYTRF
.
50 * B
(input
/output
) DOUBLE PRECISION array
, dimension (LDB
,NRHS
)
51 * On entry
, the right hand side matrix B
.
52 * On exit
, the solution matrix X
.
55 * The leading
dimension of the array B
. LDB
>= max
(1,N
).
57 * INFO
(output
) INTEGER
58 * = 0: successful exit
59 * < 0: if INFO
= -i
, the i
-th argument had an illegal value
61 * =====================================================================
65 PARAMETER ( ONE
= 1.0D
+0 )
70 DOUBLE PRECISION AK
, AKM1
, AKM1K
, BK
, BKM1
, DENOM
72 * .. External Functions
..
76 * .. External Subroutines
..
77 EXTERNAL DGEMV
, DGER
, DSCAL
, DSWAP
, XERBLA
79 * .. Intrinsic Functions
..
82 * .. Executable Statements
..
85 UPPER
= LSAME
( UPLO
, 'U' )
86 IF( .NOT
.UPPER
.AND
. .NOT
.LSAME
( UPLO
, 'L' ) ) THEN
88 ELSE IF( N
.LT
.0 ) THEN
90 ELSE IF( NRHS
.LT
.0 ) THEN
92 ELSE IF( LDA
.LT
.MAX
( 1, N
) ) THEN
94 ELSE IF( LDB
.LT
.MAX
( 1, N
) ) THEN
98 CALL XERBLA
( 'DSYTRS', -INFO
)
102 * Quick
return if possible
104 IF( N
.EQ
.0 .OR
. NRHS
.EQ
.0 )
109 * Solve A*X
= B
, where A
= U*D*U
'.
111 * First solve U*D*X = B, overwriting B with X.
113 * K is the main loop index, decreasing from N to 1 in steps of
114 * 1 or 2, depending on the size of the diagonal blocks.
119 * If K < 1, exit from loop.
124 IF( IPIV( K ).GT.0 ) THEN
126 * 1 x 1 diagonal block
128 * Interchange rows K and IPIV(K).
132 $ CALL DSWAP( NRHS, B( K, 1 ), LDB, B( KP, 1 ), LDB )
134 * Multiply by inv(U(K)), where U(K) is the transformation
135 * stored in column K of A.
137 CALL DGER( K-1, NRHS, -ONE, A( 1, K ), 1, B( K, 1 ), LDB,
140 * Multiply by the inverse of the diagonal block.
142 CALL DSCAL( NRHS, ONE / A( K, K ), B( K, 1 ), LDB )
146 * 2 x 2 diagonal block
148 * Interchange rows K-1 and -IPIV(K).
152 $ CALL DSWAP( NRHS, B( K-1, 1 ), LDB, B( KP, 1 ), LDB )
154 * Multiply by inv(U(K)), where U(K) is the transformation
155 * stored in columns K-1 and K of A.
157 CALL DGER( K-2, NRHS, -ONE, A( 1, K ), 1, B( K, 1 ), LDB,
159 CALL DGER( K-2, NRHS, -ONE, A( 1, K-1 ), 1, B( K-1, 1 ),
160 $ LDB, B( 1, 1 ), LDB )
162 * Multiply by the inverse of the diagonal block.
165 AKM1 = A( K-1, K-1 ) / AKM1K
166 AK = A( K, K ) / AKM1K
167 DENOM = AKM1*AK - ONE
169 BKM1 = B( K-1, J ) / AKM1K
170 BK = B( K, J ) / AKM1K
171 B( K-1, J ) = ( AK*BKM1-BK ) / DENOM
172 B( K, J ) = ( AKM1*BK-BKM1 ) / DENOM
180 * Next solve U'*X
= B
, overwriting B with X
.
182 * K is the main loop index
, increasing from
1 to N in steps of
183 * 1 or
2, depending on the size of the diagonal blocks
.
188 * If K
> N
, exit from loop
.
193 IF( IPIV
( K
).GT
.0 ) THEN
195 * 1 x
1 diagonal block
197 * Multiply by inv
(U
'(K)), where U(K) is the transformation
198 * stored in column K of A.
200 CALL DGEMV( 'Transpose
', K-1, NRHS, -ONE, B, LDB, A( 1, K ),
201 $ 1, ONE, B( K, 1 ), LDB )
203 * Interchange rows K and IPIV(K).
207 $ CALL DSWAP( NRHS, B( K, 1 ), LDB, B( KP, 1 ), LDB )
211 * 2 x 2 diagonal block
213 * Multiply by inv(U'(K
+1)), where U
(K
+1) is the transformation
214 * stored in columns K and K
+1 of A
.
216 CALL DGEMV
( 'Transpose', K
-1, NRHS
, -ONE
, B
, LDB
, A
( 1, K
),
217 $
1, ONE
, B
( K
, 1 ), LDB
)
218 CALL DGEMV
( 'Transpose', K
-1, NRHS
, -ONE
, B
, LDB
,
219 $ A
( 1, K
+1 ), 1, ONE
, B
( K
+1, 1 ), LDB
)
221 * Interchange rows K and
-IPIV
(K
).
225 $
CALL DSWAP
( NRHS
, B
( K
, 1 ), LDB
, B
( KP
, 1 ), LDB
)
234 * Solve A*X
= B
, where A
= L*D*L
'.
236 * First solve L*D*X = B, overwriting B with X.
238 * K is the main loop index, increasing from 1 to N in steps of
239 * 1 or 2, depending on the size of the diagonal blocks.
244 * If K > N, exit from loop.
249 IF( IPIV( K ).GT.0 ) THEN
251 * 1 x 1 diagonal block
253 * Interchange rows K and IPIV(K).
257 $ CALL DSWAP( NRHS, B( K, 1 ), LDB, B( KP, 1 ), LDB )
259 * Multiply by inv(L(K)), where L(K) is the transformation
260 * stored in column K of A.
263 $ CALL DGER( N-K, NRHS, -ONE, A( K+1, K ), 1, B( K, 1 ),
264 $ LDB, B( K+1, 1 ), LDB )
266 * Multiply by the inverse of the diagonal block.
268 CALL DSCAL( NRHS, ONE / A( K, K ), B( K, 1 ), LDB )
272 * 2 x 2 diagonal block
274 * Interchange rows K+1 and -IPIV(K).
278 $ CALL DSWAP( NRHS, B( K+1, 1 ), LDB, B( KP, 1 ), LDB )
280 * Multiply by inv(L(K)), where L(K) is the transformation
281 * stored in columns K and K+1 of A.
284 CALL DGER( N-K-1, NRHS, -ONE, A( K+2, K ), 1, B( K, 1 ),
285 $ LDB, B( K+2, 1 ), LDB )
286 CALL DGER( N-K-1, NRHS, -ONE, A( K+2, K+1 ), 1,
287 $ B( K+1, 1 ), LDB, B( K+2, 1 ), LDB )
290 * Multiply by the inverse of the diagonal block.
293 AKM1 = A( K, K ) / AKM1K
294 AK = A( K+1, K+1 ) / AKM1K
295 DENOM = AKM1*AK - ONE
297 BKM1 = B( K, J ) / AKM1K
298 BK = B( K+1, J ) / AKM1K
299 B( K, J ) = ( AK*BKM1-BK ) / DENOM
300 B( K+1, J ) = ( AKM1*BK-BKM1 ) / DENOM
308 * Next solve L'*X
= B
, overwriting B with X
.
310 * K is the main loop index
, decreasing from N
to 1 in steps of
311 * 1 or
2, depending on the size of the diagonal blocks
.
316 * If K
< 1, exit from loop
.
321 IF( IPIV
( K
).GT
.0 ) THEN
323 * 1 x
1 diagonal block
325 * Multiply by inv
(L
'(K)), where L(K) is the transformation
326 * stored in column K of A.
329 $ CALL DGEMV( 'Transpose
', N-K, NRHS, -ONE, B( K+1, 1 ),
330 $ LDB, A( K+1, K ), 1, ONE, B( K, 1 ), LDB )
332 * Interchange rows K and IPIV(K).
336 $ CALL DSWAP( NRHS, B( K, 1 ), LDB, B( KP, 1 ), LDB )
340 * 2 x 2 diagonal block
342 * Multiply by inv(L'(K
-1)), where L
(K
-1) is the transformation
343 * stored in columns K
-1 and K of A
.
346 CALL DGEMV
( 'Transpose', N
-K
, NRHS
, -ONE
, B
( K
+1, 1 ),
347 $ LDB
, A
( K
+1, K
), 1, ONE
, B
( K
, 1 ), LDB
)
348 CALL DGEMV
( 'Transpose', N
-K
, NRHS
, -ONE
, B
( K
+1, 1 ),
349 $ LDB
, A
( K
+1, K
-1 ), 1, ONE
, B
( K
-1, 1 ),
353 * Interchange rows K and
-IPIV
(K
).
357 $
CALL DSWAP
( NRHS
, B
( K
, 1 ), LDB
, B
( KP
, 1 ), LDB
)