3 * =========== DOCUMENTATION ===========
5 * Online html documentation available at
6 * http://www.netlib.org/lapack/explore-html/
9 *> Download SSYTRS2 + dependencies
10 *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/ssytrs2.f">
12 *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/ssytrs2.f">
14 *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/ssytrs2.f">
21 * SUBROUTINE SSYTRS2( UPLO, N, NRHS, A, LDA, IPIV, B, LDB,
24 * .. Scalar Arguments ..
26 * INTEGER INFO, LDA, LDB, N, NRHS
28 * .. Array Arguments ..
30 * REAL A( LDA, * ), B( LDB, * ), WORK( * )
39 *> SSYTRS2 solves a system of linear equations A*X = B with a real
40 *> symmetric matrix A using the factorization A = U*D*U**T or
41 *> A = L*D*L**T computed by SSYTRF and converted by SSYCONV.
49 *> UPLO is CHARACTER*1
50 *> Specifies whether the details of the factorization are stored
51 *> as an upper or lower triangular matrix.
52 *> = 'U': Upper triangular, form is A = U*D*U**T;
53 *> = 'L': Lower triangular, form is A = L*D*L**T.
59 *> The order of the matrix A. N >= 0.
65 *> The number of right hand sides, i.e., the number of columns
66 *> of the matrix B. NRHS >= 0.
71 *> A is REAL array, dimension (LDA,N)
72 *> The block diagonal matrix D and the multipliers used to
73 *> obtain the factor U or L as computed by SSYTRF.
74 *> Note that A is input / output. This might be counter-intuitive,
75 *> and one may think that A is input only. A is input / output. This
76 *> is because, at the start of the subroutine, we permute A in a
77 *> "better" form and then we permute A back to its original form at
84 *> The leading dimension of the array A. LDA >= max(1,N).
89 *> IPIV is INTEGER array, dimension (N)
90 *> Details of the interchanges and the block structure of D
91 *> as determined by SSYTRF.
96 *> B is REAL array, dimension (LDB,NRHS)
97 *> On entry, the right hand side matrix B.
98 *> On exit, the solution matrix X.
104 *> The leading dimension of the array B. LDB >= max(1,N).
109 *> WORK is REAL array, dimension (N)
115 *> = 0: successful exit
116 *> < 0: if INFO = -i, the i-th argument had an illegal value
122 *> \author Univ. of Tennessee
123 *> \author Univ. of California Berkeley
124 *> \author Univ. of Colorado Denver
127 *> \date November 2015
129 *> \ingroup realSYcomputational
131 * =====================================================================
132 SUBROUTINE SSYTRS2( UPLO, N, NRHS, A, LDA, IPIV, B, LDB,
135 * -- LAPACK computational routine (version 3.6.0) --
136 * -- LAPACK is a software package provided by Univ. of Tennessee, --
137 * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
140 * .. Scalar Arguments ..
142 INTEGER INFO, LDA, LDB, N, NRHS
144 * .. Array Arguments ..
146 REAL A( LDA, * ), B( LDB, * ), WORK( * )
149 * =====================================================================
153 PARAMETER ( ONE = 1.0E+0 )
155 * .. Local Scalars ..
157 INTEGER I, IINFO, J, K, KP
158 REAL AK, AKM1, AKM1K, BK, BKM1, DENOM
160 * .. External Functions ..
164 * .. External Subroutines ..
165 EXTERNAL SSCAL, SSYCONV, SSWAP, STRSM, XERBLA
167 * .. Intrinsic Functions ..
170 * .. Executable Statements ..
173 UPPER = LSAME( UPLO, 'U' )
174 IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THEN
176 ELSE IF( N.LT.0 ) THEN
178 ELSE IF( NRHS.LT.0 ) THEN
180 ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
182 ELSE IF( LDB.LT.MAX( 1, N ) ) THEN
186 CALL XERBLA( 'SSYTRS2', -INFO )
190 * Quick return if possible
192 IF( N.EQ.0 .OR. NRHS.EQ.0 )
197 CALL SSYCONV( UPLO, 'C', N, A, LDA, IPIV, WORK, IINFO )
201 * Solve A*X = B, where A = U*D*U**T.
205 DO WHILE ( K .GE. 1 )
206 IF( IPIV( K ).GT.0 ) THEN
207 * 1 x 1 diagonal block
208 * Interchange rows K and IPIV(K).
211 $ CALL SSWAP( NRHS, B( K, 1 ), LDB, B( KP, 1 ), LDB )
214 * 2 x 2 diagonal block
215 * Interchange rows K-1 and -IPIV(K).
217 IF( KP.EQ.-IPIV( K-1 ) )
218 $ CALL SSWAP( NRHS, B( K-1, 1 ), LDB, B( KP, 1 ), LDB )
223 * Compute (U \P**T * B) -> B [ (U \P**T * B) ]
225 CALL STRSM('L','U','N','U',N,NRHS,ONE,A,LDA,B,LDB)
227 * Compute D \ B -> B [ D \ (U \P**T * B) ]
230 DO WHILE ( I .GE. 1 )
231 IF( IPIV(I) .GT. 0 ) THEN
232 CALL SSCAL( NRHS, ONE / A( I, I ), B( I, 1 ), LDB )
233 ELSEIF ( I .GT. 1) THEN
234 IF ( IPIV(I-1) .EQ. IPIV(I) ) THEN
236 AKM1 = A( I-1, I-1 ) / AKM1K
237 AK = A( I, I ) / AKM1K
238 DENOM = AKM1*AK - ONE
240 BKM1 = B( I-1, J ) / AKM1K
241 BK = B( I, J ) / AKM1K
242 B( I-1, J ) = ( AK*BKM1-BK ) / DENOM
243 B( I, J ) = ( AKM1*BK-BKM1 ) / DENOM
251 * Compute (U**T \ B) -> B [ U**T \ (D \ (U \P**T * B) ) ]
253 CALL STRSM('L','U','T','U',N,NRHS,ONE,A,LDA,B,LDB)
255 * P * B [ P * (U**T \ (D \ (U \P**T * B) )) ]
258 DO WHILE ( K .LE. N )
259 IF( IPIV( K ).GT.0 ) THEN
260 * 1 x 1 diagonal block
261 * Interchange rows K and IPIV(K).
264 $ CALL SSWAP( NRHS, B( K, 1 ), LDB, B( KP, 1 ), LDB )
267 * 2 x 2 diagonal block
268 * Interchange rows K-1 and -IPIV(K).
270 IF( K .LT. N .AND. KP.EQ.-IPIV( K+1 ) )
271 $ CALL SSWAP( NRHS, B( K, 1 ), LDB, B( KP, 1 ), LDB )
278 * Solve A*X = B, where A = L*D*L**T.
282 DO WHILE ( K .LE. N )
283 IF( IPIV( K ).GT.0 ) THEN
284 * 1 x 1 diagonal block
285 * Interchange rows K and IPIV(K).
288 $ CALL SSWAP( NRHS, B( K, 1 ), LDB, B( KP, 1 ), LDB )
291 * 2 x 2 diagonal block
292 * Interchange rows K and -IPIV(K+1).
294 IF( KP.EQ.-IPIV( K ) )
295 $ CALL SSWAP( NRHS, B( K+1, 1 ), LDB, B( KP, 1 ), LDB )
300 * Compute (L \P**T * B) -> B [ (L \P**T * B) ]
302 CALL STRSM('L','L','N','U',N,NRHS,ONE,A,LDA,B,LDB)
304 * Compute D \ B -> B [ D \ (L \P**T * B) ]
307 DO WHILE ( I .LE. N )
308 IF( IPIV(I) .GT. 0 ) THEN
309 CALL SSCAL( NRHS, ONE / A( I, I ), B( I, 1 ), LDB )
312 AKM1 = A( I, I ) / AKM1K
313 AK = A( I+1, I+1 ) / AKM1K
314 DENOM = AKM1*AK - ONE
316 BKM1 = B( I, J ) / AKM1K
317 BK = B( I+1, J ) / AKM1K
318 B( I, J ) = ( AK*BKM1-BK ) / DENOM
319 B( I+1, J ) = ( AKM1*BK-BKM1 ) / DENOM
326 * Compute (L**T \ B) -> B [ L**T \ (D \ (L \P**T * B) ) ]
328 CALL STRSM('L','L','T','U',N,NRHS,ONE,A,LDA,B,LDB)
330 * P * B [ P * (L**T \ (D \ (L \P**T * B) )) ]
333 DO WHILE ( K .GE. 1 )
334 IF( IPIV( K ).GT.0 ) THEN
335 * 1 x 1 diagonal block
336 * Interchange rows K and IPIV(K).
339 $ CALL SSWAP( NRHS, B( K, 1 ), LDB, B( KP, 1 ), LDB )
342 * 2 x 2 diagonal block
343 * Interchange rows K-1 and -IPIV(K).
345 IF( K.GT.1 .AND. KP.EQ.-IPIV( K-1 ) )
346 $ CALL SSWAP( NRHS, B( K, 1 ), LDB, B( KP, 1 ), LDB )
355 CALL SSYCONV( UPLO, 'R', N, A, LDA, IPIV, WORK, IINFO )