LAPACK 3.3.1 Linear Algebra PACKage

# dsytrs2.f

Go to the documentation of this file.
```00001       SUBROUTINE DSYTRS2( UPLO, N, NRHS, A, LDA, IPIV, B, LDB,
00002      \$                    WORK, INFO )
00003 *
00004 *  -- LAPACK PROTOTYPE routine (version 3.3.1) --
00005 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
00006 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
00007 *  -- April 2011                                                      --
00008 *
00009 *  -- Written by Julie Langou of the Univ. of TN    --
00010 *
00011 *     .. Scalar Arguments ..
00012       CHARACTER          UPLO
00013       INTEGER            INFO, LDA, LDB, N, NRHS
00014 *     ..
00015 *     .. Array Arguments ..
00016       INTEGER            IPIV( * )
00017       DOUBLE PRECISION   A( LDA, * ), B( LDB, * ), WORK( * )
00018 *     ..
00019 *
00020 *  Purpose
00021 *  =======
00022 *
00023 *  DSYTRS2 solves a system of linear equations A*X = B with a real
00024 *  symmetric matrix A using the factorization A = U*D*U**T or
00025 *  A = L*D*L**T computed by DSYTRF and converted by DSYCONV.
00026 *
00027 *  Arguments
00028 *  =========
00029 *
00030 *  UPLO    (input) CHARACTER*1
00031 *          Specifies whether the details of the factorization are stored
00032 *          as an upper or lower triangular matrix.
00033 *          = 'U':  Upper triangular, form is A = U*D*U**T;
00034 *          = 'L':  Lower triangular, form is A = L*D*L**T.
00035 *
00036 *  N       (input) INTEGER
00037 *          The order of the matrix A.  N >= 0.
00038 *
00039 *  NRHS    (input) INTEGER
00040 *          The number of right hand sides, i.e., the number of columns
00041 *          of the matrix B.  NRHS >= 0.
00042 *
00043 *  A       (input) DOUBLE PRECISION array, dimension (LDA,N)
00044 *          The block diagonal matrix D and the multipliers used to
00045 *          obtain the factor U or L as computed by DSYTRF.
00046 *
00047 *  LDA     (input) INTEGER
00048 *          The leading dimension of the array A.  LDA >= max(1,N).
00049 *
00050 *  IPIV    (input) INTEGER array, dimension (N)
00051 *          Details of the interchanges and the block structure of D
00052 *          as determined by DSYTRF.
00053 *
00054 *  B       (input/output) DOUBLE PRECISION array, dimension (LDB,NRHS)
00055 *          On entry, the right hand side matrix B.
00056 *          On exit, the solution matrix X.
00057 *
00058 *  LDB     (input) INTEGER
00059 *          The leading dimension of the array B.  LDB >= max(1,N).
00060 *
00061 *  WORK    (workspace) REAL array, dimension (N)
00062 *
00063 *  INFO    (output) INTEGER
00064 *          = 0:  successful exit
00065 *          < 0:  if INFO = -i, the i-th argument had an illegal value
00066 *
00067 *  =====================================================================
00068 *
00069 *     .. Parameters ..
00070       DOUBLE PRECISION   ONE
00071       PARAMETER          ( ONE = 1.0D+0 )
00072 *     ..
00073 *     .. Local Scalars ..
00074       LOGICAL            UPPER
00075       INTEGER            I, IINFO, J, K, KP
00076       DOUBLE PRECISION   AK, AKM1, AKM1K, BK, BKM1, DENOM
00077 *     ..
00078 *     .. External Functions ..
00079       LOGICAL            LSAME
00080       EXTERNAL           LSAME
00081 *     ..
00082 *     .. External Subroutines ..
00083       EXTERNAL           DSCAL, DSYCONV, DSWAP, DTRSM, XERBLA
00084 *     ..
00085 *     .. Intrinsic Functions ..
00086       INTRINSIC          MAX
00087 *     ..
00088 *     .. Executable Statements ..
00089 *
00090       INFO = 0
00091       UPPER = LSAME( UPLO, 'U' )
00092       IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THEN
00093          INFO = -1
00094       ELSE IF( N.LT.0 ) THEN
00095          INFO = -2
00096       ELSE IF( NRHS.LT.0 ) THEN
00097          INFO = -3
00098       ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
00099          INFO = -5
00100       ELSE IF( LDB.LT.MAX( 1, N ) ) THEN
00101          INFO = -8
00102       END IF
00103       IF( INFO.NE.0 ) THEN
00104          CALL XERBLA( 'DSYTRS2', -INFO )
00105          RETURN
00106       END IF
00107 *
00108 *     Quick return if possible
00109 *
00110       IF( N.EQ.0 .OR. NRHS.EQ.0 )
00111      \$   RETURN
00112 *
00113 *     Convert A
00114 *
00115       CALL DSYCONV( UPLO, 'C', N, A, LDA, IPIV, WORK, IINFO )
00116 *
00117       IF( UPPER ) THEN
00118 *
00119 *        Solve A*X = B, where A = U*D*U**T.
00120 *
00121 *       P**T * B
00122         K=N
00123         DO WHILE ( K .GE. 1 )
00124          IF( IPIV( K ).GT.0 ) THEN
00125 *           1 x 1 diagonal block
00126 *           Interchange rows K and IPIV(K).
00127             KP = IPIV( K )
00128             IF( KP.NE.K )
00129      \$         CALL DSWAP( NRHS, B( K, 1 ), LDB, B( KP, 1 ), LDB )
00130             K=K-1
00131          ELSE
00132 *           2 x 2 diagonal block
00133 *           Interchange rows K-1 and -IPIV(K).
00134             KP = -IPIV( K )
00135             IF( KP.EQ.-IPIV( K-1 ) )
00136      \$         CALL DSWAP( NRHS, B( K-1, 1 ), LDB, B( KP, 1 ), LDB )
00137             K=K-2
00138          END IF
00139         END DO
00140 *
00141 *  Compute (U \P**T * B) -> B    [ (U \P**T * B) ]
00142 *
00143         CALL DTRSM('L','U','N','U',N,NRHS,ONE,A,LDA,B,LDB)
00144 *
00145 *  Compute D \ B -> B   [ D \ (U \P**T * B) ]
00146 *
00147          I=N
00148          DO WHILE ( I .GE. 1 )
00149             IF( IPIV(I) .GT. 0 ) THEN
00150               CALL DSCAL( NRHS, ONE / A( I, I ), B( I, 1 ), LDB )
00151             ELSEIF ( I .GT. 1) THEN
00152                IF ( IPIV(I-1) .EQ. IPIV(I) ) THEN
00153                   AKM1K = WORK(I)
00154                   AKM1 = A( I-1, I-1 ) / AKM1K
00155                   AK = A( I, I ) / AKM1K
00156                   DENOM = AKM1*AK - ONE
00157                   DO 15 J = 1, NRHS
00158                      BKM1 = B( I-1, J ) / AKM1K
00159                      BK = B( I, J ) / AKM1K
00160                      B( I-1, J ) = ( AK*BKM1-BK ) / DENOM
00161                      B( I, J ) = ( AKM1*BK-BKM1 ) / DENOM
00162  15              CONTINUE
00163                I = I - 1
00164                ENDIF
00165             ENDIF
00166             I = I - 1
00167          END DO
00168 *
00169 *      Compute (U**T \ B) -> B   [ U**T \ (D \ (U \P**T * B) ) ]
00170 *
00171          CALL DTRSM('L','U','T','U',N,NRHS,ONE,A,LDA,B,LDB)
00172 *
00173 *       P * B  [ P * (U**T \ (D \ (U \P**T * B) )) ]
00174 *
00175         K=1
00176         DO WHILE ( K .LE. N )
00177          IF( IPIV( K ).GT.0 ) THEN
00178 *           1 x 1 diagonal block
00179 *           Interchange rows K and IPIV(K).
00180             KP = IPIV( K )
00181             IF( KP.NE.K )
00182      \$         CALL DSWAP( NRHS, B( K, 1 ), LDB, B( KP, 1 ), LDB )
00183             K=K+1
00184          ELSE
00185 *           2 x 2 diagonal block
00186 *           Interchange rows K-1 and -IPIV(K).
00187             KP = -IPIV( K )
00188             IF( K .LT. N .AND. KP.EQ.-IPIV( K+1 ) )
00189      \$         CALL DSWAP( NRHS, B( K, 1 ), LDB, B( KP, 1 ), LDB )
00190             K=K+2
00191          ENDIF
00192         END DO
00193 *
00194       ELSE
00195 *
00196 *        Solve A*X = B, where A = L*D*L**T.
00197 *
00198 *       P**T * B
00199         K=1
00200         DO WHILE ( K .LE. N )
00201          IF( IPIV( K ).GT.0 ) THEN
00202 *           1 x 1 diagonal block
00203 *           Interchange rows K and IPIV(K).
00204             KP = IPIV( K )
00205             IF( KP.NE.K )
00206      \$         CALL DSWAP( NRHS, B( K, 1 ), LDB, B( KP, 1 ), LDB )
00207             K=K+1
00208          ELSE
00209 *           2 x 2 diagonal block
00210 *           Interchange rows K and -IPIV(K+1).
00211             KP = -IPIV( K+1 )
00212             IF( KP.EQ.-IPIV( K ) )
00213      \$         CALL DSWAP( NRHS, B( K+1, 1 ), LDB, B( KP, 1 ), LDB )
00214             K=K+2
00215          ENDIF
00216         END DO
00217 *
00218 *  Compute (L \P**T * B) -> B    [ (L \P**T * B) ]
00219 *
00220         CALL DTRSM('L','L','N','U',N,NRHS,ONE,A,LDA,B,LDB)
00221 *
00222 *  Compute D \ B -> B   [ D \ (L \P**T * B) ]
00223 *
00224          I=1
00225          DO WHILE ( I .LE. N )
00226             IF( IPIV(I) .GT. 0 ) THEN
00227               CALL DSCAL( NRHS, ONE / A( I, I ), B( I, 1 ), LDB )
00228             ELSE
00229                   AKM1K = WORK(I)
00230                   AKM1 = A( I, I ) / AKM1K
00231                   AK = A( I+1, I+1 ) / AKM1K
00232                   DENOM = AKM1*AK - ONE
00233                   DO 25 J = 1, NRHS
00234                      BKM1 = B( I, J ) / AKM1K
00235                      BK = B( I+1, J ) / AKM1K
00236                      B( I, J ) = ( AK*BKM1-BK ) / DENOM
00237                      B( I+1, J ) = ( AKM1*BK-BKM1 ) / DENOM
00238  25              CONTINUE
00239                   I = I + 1
00240             ENDIF
00241             I = I + 1
00242          END DO
00243 *
00244 *  Compute (L**T \ B) -> B   [ L**T \ (D \ (L \P**T * B) ) ]
00245 *
00246         CALL DTRSM('L','L','T','U',N,NRHS,ONE,A,LDA,B,LDB)
00247 *
00248 *       P * B  [ P * (L**T \ (D \ (L \P**T * B) )) ]
00249 *
00250         K=N
00251         DO WHILE ( K .GE. 1 )
00252          IF( IPIV( K ).GT.0 ) THEN
00253 *           1 x 1 diagonal block
00254 *           Interchange rows K and IPIV(K).
00255             KP = IPIV( K )
00256             IF( KP.NE.K )
00257      \$         CALL DSWAP( NRHS, B( K, 1 ), LDB, B( KP, 1 ), LDB )
00258             K=K-1
00259          ELSE
00260 *           2 x 2 diagonal block
00261 *           Interchange rows K-1 and -IPIV(K).
00262             KP = -IPIV( K )
00263             IF( K.GT.1 .AND. KP.EQ.-IPIV( K-1 ) )
00264      \$         CALL DSWAP( NRHS, B( K, 1 ), LDB, B( KP, 1 ), LDB )
00265             K=K-2
00266          ENDIF
00267         END DO
00268 *
00269       END IF
00270 *
00271 *     Revert A
00272 *
00273       CALL DSYCONV( UPLO, 'R', N, A, LDA, IPIV, WORK, IINFO )
00274 *
00275       RETURN
00276 *
00277 *     End of DSYTRS2
00278 *
00279       END
```