LAPACK  3.4.0
LAPACK: Linear Algebra PACKage
slavsy.f
Go to the documentation of this file.
00001 *> \brief \b SLAVSY
00002 *
00003 *  =========== DOCUMENTATION ===========
00004 *
00005 * Online html documentation available at 
00006 *            http://www.netlib.org/lapack/explore-html/ 
00007 *
00008 *  Definition:
00009 *  ===========
00010 *
00011 *       SUBROUTINE SLAVSY( UPLO, TRANS, DIAG, N, NRHS, A, LDA, IPIV, B,
00012 *                          LDB, INFO )
00013 * 
00014 *       .. Scalar Arguments ..
00015 *       CHARACTER          DIAG, TRANS, UPLO
00016 *       INTEGER            INFO, LDA, LDB, N, NRHS
00017 *       ..
00018 *       .. Array Arguments ..
00019 *       INTEGER            IPIV( * )
00020 *       REAL               A( LDA, * ), B( LDB, * )
00021 *       ..
00022 *  
00023 *
00024 *> \par Purpose:
00025 *  =============
00026 *>
00027 *> \verbatim
00028 *>
00029 *> SLAVSY  performs one of the matrix-vector operations
00030 *>    x := A*x  or  x := A'*x,
00031 *> where x is an N element vector and A is one of the factors
00032 *> from the block U*D*U' or L*D*L' factorization computed by SSYTRF.
00033 *>
00034 *> If TRANS = 'N', multiplies by U  or U * D  (or L  or L * D)
00035 *> If TRANS = 'T', multiplies by U' or D * U' (or L' or D * L')
00036 *> If TRANS = 'C', multiplies by U' or D * U' (or L' or D * L')
00037 *> \endverbatim
00038 *
00039 *  Arguments:
00040 *  ==========
00041 *
00042 *> \param[in] UPLO
00043 *> \verbatim
00044 *>          UPLO is CHARACTER*1
00045 *>          Specifies whether the factor stored in A is upper or lower
00046 *>          triangular.
00047 *>          = 'U':  Upper triangular
00048 *>          = 'L':  Lower triangular
00049 *> \endverbatim
00050 *>
00051 *> \param[in] TRANS
00052 *> \verbatim
00053 *>          TRANS is CHARACTER*1
00054 *>          Specifies the operation to be performed:
00055 *>          = 'N':  x := A*x
00056 *>          = 'T':  x := A'*x
00057 *>          = 'C':  x := A'*x
00058 *> \endverbatim
00059 *>
00060 *> \param[in] DIAG
00061 *> \verbatim
00062 *>          DIAG is CHARACTER*1
00063 *>          Specifies whether or not the diagonal blocks are unit
00064 *>          matrices.  If the diagonal blocks are assumed to be unit,
00065 *>          then A = U or A = L, otherwise A = U*D or A = L*D.
00066 *>          = 'U':  Diagonal blocks are assumed to be unit matrices.
00067 *>          = 'N':  Diagonal blocks are assumed to be non-unit matrices.
00068 *> \endverbatim
00069 *>
00070 *> \param[in] N
00071 *> \verbatim
00072 *>          N is INTEGER
00073 *>          The number of rows and columns of the matrix A.  N >= 0.
00074 *> \endverbatim
00075 *>
00076 *> \param[in] NRHS
00077 *> \verbatim
00078 *>          NRHS is INTEGER
00079 *>          The number of right hand sides, i.e., the number of vectors
00080 *>          x to be multiplied by A.  NRHS >= 0.
00081 *> \endverbatim
00082 *>
00083 *> \param[in] A
00084 *> \verbatim
00085 *>          A is REAL array, dimension (LDA,N)
00086 *>          The block diagonal matrix D and the multipliers used to
00087 *>          obtain the factor U or L as computed by SSYTRF.
00088 *> \endverbatim
00089 *>
00090 *> \param[in] LDA
00091 *> \verbatim
00092 *>          LDA is INTEGER
00093 *>          The leading dimension of the array A.  LDA >= max(1,N).
00094 *> \endverbatim
00095 *>
00096 *> \param[in] IPIV
00097 *> \verbatim
00098 *>          IPIV is INTEGER array, dimension (N)
00099 *>          The pivot indices from SSYTRF.
00100 *> \endverbatim
00101 *>
00102 *> \param[in,out] B
00103 *> \verbatim
00104 *>          B is REAL array, dimension (LDB,NRHS)
00105 *>          On entry, B contains NRHS vectors of length N.
00106 *>          On exit, B is overwritten with the product A * B.
00107 *> \endverbatim
00108 *>
00109 *> \param[in] LDB
00110 *> \verbatim
00111 *>          LDB is INTEGER
00112 *>          The leading dimension of the array B.  LDB >= max(1,N).
00113 *> \endverbatim
00114 *>
00115 *> \param[out] INFO
00116 *> \verbatim
00117 *>          INFO is INTEGER
00118 *>          = 0: successful exit
00119 *>          < 0: if INFO = -k, the k-th argument had an illegal value
00120 *> \endverbatim
00121 *
00122 *  Authors:
00123 *  ========
00124 *
00125 *> \author Univ. of Tennessee 
00126 *> \author Univ. of California Berkeley 
00127 *> \author Univ. of Colorado Denver 
00128 *> \author NAG Ltd. 
00129 *
00130 *> \date November 2011
00131 *
00132 *> \ingroup single_lin
00133 *
00134 *  =====================================================================
00135       SUBROUTINE SLAVSY( UPLO, TRANS, DIAG, N, NRHS, A, LDA, IPIV, B,
00136      $                   LDB, INFO )
00137 *
00138 *  -- LAPACK test routine (version 3.4.0) --
00139 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
00140 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
00141 *     November 2011
00142 *
00143 *     .. Scalar Arguments ..
00144       CHARACTER          DIAG, TRANS, UPLO
00145       INTEGER            INFO, LDA, LDB, N, NRHS
00146 *     ..
00147 *     .. Array Arguments ..
00148       INTEGER            IPIV( * )
00149       REAL               A( LDA, * ), B( LDB, * )
00150 *     ..
00151 *
00152 *  =====================================================================
00153 *
00154 *     .. Parameters ..
00155       REAL               ONE
00156       PARAMETER          ( ONE = 1.0E+0 )
00157 *     ..
00158 *     .. Local Scalars ..
00159       LOGICAL            NOUNIT
00160       INTEGER            J, K, KP
00161       REAL               D11, D12, D21, D22, T1, T2
00162 *     ..
00163 *     .. External Functions ..
00164       LOGICAL            LSAME
00165       EXTERNAL           LSAME
00166 *     ..
00167 *     .. External Subroutines ..
00168       EXTERNAL           SGEMV, SGER, SSCAL, SSWAP, XERBLA
00169 *     ..
00170 *     .. Intrinsic Functions ..
00171       INTRINSIC          ABS, MAX
00172 *     ..
00173 *     .. Executable Statements ..
00174 *
00175 *     Test the input parameters.
00176 *
00177       INFO = 0
00178       IF( .NOT.LSAME( UPLO, 'U' ) .AND. .NOT.LSAME( UPLO, 'L' ) ) THEN
00179          INFO = -1
00180       ELSE IF( .NOT.LSAME( TRANS, 'N' ) .AND. .NOT.
00181      $         LSAME( TRANS, 'T' ) .AND. .NOT.LSAME( TRANS, 'C' ) ) THEN
00182          INFO = -2
00183       ELSE IF( .NOT.LSAME( DIAG, 'U' ) .AND. .NOT.LSAME( DIAG, 'N' ) )
00184      $          THEN
00185          INFO = -3
00186       ELSE IF( N.LT.0 ) THEN
00187          INFO = -4
00188       ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
00189          INFO = -6
00190       ELSE IF( LDB.LT.MAX( 1, N ) ) THEN
00191          INFO = -9
00192       END IF
00193       IF( INFO.NE.0 ) THEN
00194          CALL XERBLA( 'SLAVSY ', -INFO )
00195          RETURN
00196       END IF
00197 *
00198 *     Quick return if possible.
00199 *
00200       IF( N.EQ.0 )
00201      $   RETURN
00202 *
00203       NOUNIT = LSAME( DIAG, 'N' )
00204 *------------------------------------------
00205 *
00206 *     Compute  B := A * B  (No transpose)
00207 *
00208 *------------------------------------------
00209       IF( LSAME( TRANS, 'N' ) ) THEN
00210 *
00211 *        Compute  B := U*B
00212 *        where U = P(m)*inv(U(m))* ... *P(1)*inv(U(1))
00213 *
00214          IF( LSAME( UPLO, 'U' ) ) THEN
00215 *
00216 *        Loop forward applying the transformations.
00217 *
00218             K = 1
00219    10       CONTINUE
00220             IF( K.GT.N )
00221      $         GO TO 30
00222             IF( IPIV( K ).GT.0 ) THEN
00223 *
00224 *              1 x 1 pivot block
00225 *
00226 *              Multiply by the diagonal element if forming U * D.
00227 *
00228                IF( NOUNIT )
00229      $            CALL SSCAL( NRHS, A( K, K ), B( K, 1 ), LDB )
00230 *
00231 *              Multiply by  P(K) * inv(U(K))  if K > 1.
00232 *
00233                IF( K.GT.1 ) THEN
00234 *
00235 *                 Apply the transformation.
00236 *
00237                   CALL SGER( K-1, NRHS, ONE, A( 1, K ), 1, B( K, 1 ),
00238      $                       LDB, B( 1, 1 ), LDB )
00239 *
00240 *                 Interchange if P(K) .ne. I.
00241 *
00242                   KP = IPIV( K )
00243                   IF( KP.NE.K )
00244      $               CALL SSWAP( NRHS, B( K, 1 ), LDB, B( KP, 1 ), LDB )
00245                END IF
00246                K = K + 1
00247             ELSE
00248 *
00249 *              2 x 2 pivot block
00250 *
00251 *              Multiply by the diagonal block if forming U * D.
00252 *
00253                IF( NOUNIT ) THEN
00254                   D11 = A( K, K )
00255                   D22 = A( K+1, K+1 )
00256                   D12 = A( K, K+1 )
00257                   D21 = D12
00258                   DO 20 J = 1, NRHS
00259                      T1 = B( K, J )
00260                      T2 = B( K+1, J )
00261                      B( K, J ) = D11*T1 + D12*T2
00262                      B( K+1, J ) = D21*T1 + D22*T2
00263    20             CONTINUE
00264                END IF
00265 *
00266 *              Multiply by  P(K) * inv(U(K))  if K > 1.
00267 *
00268                IF( K.GT.1 ) THEN
00269 *
00270 *                 Apply the transformations.
00271 *
00272                   CALL SGER( K-1, NRHS, ONE, A( 1, K ), 1, B( K, 1 ),
00273      $                       LDB, B( 1, 1 ), LDB )
00274                   CALL SGER( K-1, NRHS, ONE, A( 1, K+1 ), 1,
00275      $                       B( K+1, 1 ), LDB, B( 1, 1 ), LDB )
00276 *
00277 *                 Interchange if P(K) .ne. I.
00278 *
00279                   KP = ABS( IPIV( K ) )
00280                   IF( KP.NE.K )
00281      $               CALL SSWAP( NRHS, B( K, 1 ), LDB, B( KP, 1 ), LDB )
00282                END IF
00283                K = K + 2
00284             END IF
00285             GO TO 10
00286    30       CONTINUE
00287 *
00288 *        Compute  B := L*B
00289 *        where L = P(1)*inv(L(1))* ... *P(m)*inv(L(m)) .
00290 *
00291          ELSE
00292 *
00293 *           Loop backward applying the transformations to B.
00294 *
00295             K = N
00296    40       CONTINUE
00297             IF( K.LT.1 )
00298      $         GO TO 60
00299 *
00300 *           Test the pivot index.  If greater than zero, a 1 x 1
00301 *           pivot was used, otherwise a 2 x 2 pivot was used.
00302 *
00303             IF( IPIV( K ).GT.0 ) THEN
00304 *
00305 *              1 x 1 pivot block:
00306 *
00307 *              Multiply by the diagonal element if forming L * D.
00308 *
00309                IF( NOUNIT )
00310      $            CALL SSCAL( NRHS, A( K, K ), B( K, 1 ), LDB )
00311 *
00312 *              Multiply by  P(K) * inv(L(K))  if K < N.
00313 *
00314                IF( K.NE.N ) THEN
00315                   KP = IPIV( K )
00316 *
00317 *                 Apply the transformation.
00318 *
00319                   CALL SGER( N-K, NRHS, ONE, A( K+1, K ), 1, B( K, 1 ),
00320      $                       LDB, B( K+1, 1 ), LDB )
00321 *
00322 *                 Interchange if a permutation was applied at the
00323 *                 K-th step of the factorization.
00324 *
00325                   IF( KP.NE.K )
00326      $               CALL SSWAP( NRHS, B( K, 1 ), LDB, B( KP, 1 ), LDB )
00327                END IF
00328                K = K - 1
00329 *
00330             ELSE
00331 *
00332 *              2 x 2 pivot block:
00333 *
00334 *              Multiply by the diagonal block if forming L * D.
00335 *
00336                IF( NOUNIT ) THEN
00337                   D11 = A( K-1, K-1 )
00338                   D22 = A( K, K )
00339                   D21 = A( K, K-1 )
00340                   D12 = D21
00341                   DO 50 J = 1, NRHS
00342                      T1 = B( K-1, J )
00343                      T2 = B( K, J )
00344                      B( K-1, J ) = D11*T1 + D12*T2
00345                      B( K, J ) = D21*T1 + D22*T2
00346    50             CONTINUE
00347                END IF
00348 *
00349 *              Multiply by  P(K) * inv(L(K))  if K < N.
00350 *
00351                IF( K.NE.N ) THEN
00352 *
00353 *                 Apply the transformation.
00354 *
00355                   CALL SGER( N-K, NRHS, ONE, A( K+1, K ), 1, B( K, 1 ),
00356      $                       LDB, B( K+1, 1 ), LDB )
00357                   CALL SGER( N-K, NRHS, ONE, A( K+1, K-1 ), 1,
00358      $                       B( K-1, 1 ), LDB, B( K+1, 1 ), LDB )
00359 *
00360 *                 Interchange if a permutation was applied at the
00361 *                 K-th step of the factorization.
00362 *
00363                   KP = ABS( IPIV( K ) )
00364                   IF( KP.NE.K )
00365      $               CALL SSWAP( NRHS, B( K, 1 ), LDB, B( KP, 1 ), LDB )
00366                END IF
00367                K = K - 2
00368             END IF
00369             GO TO 40
00370    60       CONTINUE
00371          END IF
00372 *----------------------------------------
00373 *
00374 *     Compute  B := A' * B  (transpose)
00375 *
00376 *----------------------------------------
00377       ELSE
00378 *
00379 *        Form  B := U'*B
00380 *        where U  = P(m)*inv(U(m))* ... *P(1)*inv(U(1))
00381 *        and   U' = inv(U'(1))*P(1)* ... *inv(U'(m))*P(m)
00382 *
00383          IF( LSAME( UPLO, 'U' ) ) THEN
00384 *
00385 *           Loop backward applying the transformations.
00386 *
00387             K = N
00388    70       CONTINUE
00389             IF( K.LT.1 )
00390      $         GO TO 90
00391 *
00392 *           1 x 1 pivot block.
00393 *
00394             IF( IPIV( K ).GT.0 ) THEN
00395                IF( K.GT.1 ) THEN
00396 *
00397 *                 Interchange if P(K) .ne. I.
00398 *
00399                   KP = IPIV( K )
00400                   IF( KP.NE.K )
00401      $               CALL SSWAP( NRHS, B( K, 1 ), LDB, B( KP, 1 ), LDB )
00402 *
00403 *                 Apply the transformation
00404 *
00405                   CALL SGEMV( 'Transpose', K-1, NRHS, ONE, B, LDB,
00406      $                        A( 1, K ), 1, ONE, B( K, 1 ), LDB )
00407                END IF
00408                IF( NOUNIT )
00409      $            CALL SSCAL( NRHS, A( K, K ), B( K, 1 ), LDB )
00410                K = K - 1
00411 *
00412 *           2 x 2 pivot block.
00413 *
00414             ELSE
00415                IF( K.GT.2 ) THEN
00416 *
00417 *                 Interchange if P(K) .ne. I.
00418 *
00419                   KP = ABS( IPIV( K ) )
00420                   IF( KP.NE.K-1 )
00421      $               CALL SSWAP( NRHS, B( K-1, 1 ), LDB, B( KP, 1 ),
00422      $                           LDB )
00423 *
00424 *                 Apply the transformations
00425 *
00426                   CALL SGEMV( 'Transpose', K-2, NRHS, ONE, B, LDB,
00427      $                        A( 1, K ), 1, ONE, B( K, 1 ), LDB )
00428                   CALL SGEMV( 'Transpose', K-2, NRHS, ONE, B, LDB,
00429      $                        A( 1, K-1 ), 1, ONE, B( K-1, 1 ), LDB )
00430                END IF
00431 *
00432 *              Multiply by the diagonal block if non-unit.
00433 *
00434                IF( NOUNIT ) THEN
00435                   D11 = A( K-1, K-1 )
00436                   D22 = A( K, K )
00437                   D12 = A( K-1, K )
00438                   D21 = D12
00439                   DO 80 J = 1, NRHS
00440                      T1 = B( K-1, J )
00441                      T2 = B( K, J )
00442                      B( K-1, J ) = D11*T1 + D12*T2
00443                      B( K, J ) = D21*T1 + D22*T2
00444    80             CONTINUE
00445                END IF
00446                K = K - 2
00447             END IF
00448             GO TO 70
00449    90       CONTINUE
00450 *
00451 *        Form  B := L'*B
00452 *        where L  = P(1)*inv(L(1))* ... *P(m)*inv(L(m))
00453 *        and   L' = inv(L'(m))*P(m)* ... *inv(L'(1))*P(1)
00454 *
00455          ELSE
00456 *
00457 *           Loop forward applying the L-transformations.
00458 *
00459             K = 1
00460   100       CONTINUE
00461             IF( K.GT.N )
00462      $         GO TO 120
00463 *
00464 *           1 x 1 pivot block
00465 *
00466             IF( IPIV( K ).GT.0 ) THEN
00467                IF( K.LT.N ) THEN
00468 *
00469 *                 Interchange if P(K) .ne. I.
00470 *
00471                   KP = IPIV( K )
00472                   IF( KP.NE.K )
00473      $               CALL SSWAP( NRHS, B( K, 1 ), LDB, B( KP, 1 ), LDB )
00474 *
00475 *                 Apply the transformation
00476 *
00477                   CALL SGEMV( 'Transpose', N-K, NRHS, ONE, B( K+1, 1 ),
00478      $                        LDB, A( K+1, K ), 1, ONE, B( K, 1 ), LDB )
00479                END IF
00480                IF( NOUNIT )
00481      $            CALL SSCAL( NRHS, A( K, K ), B( K, 1 ), LDB )
00482                K = K + 1
00483 *
00484 *           2 x 2 pivot block.
00485 *
00486             ELSE
00487                IF( K.LT.N-1 ) THEN
00488 *
00489 *              Interchange if P(K) .ne. I.
00490 *
00491                   KP = ABS( IPIV( K ) )
00492                   IF( KP.NE.K+1 )
00493      $               CALL SSWAP( NRHS, B( K+1, 1 ), LDB, B( KP, 1 ),
00494      $                           LDB )
00495 *
00496 *                 Apply the transformation
00497 *
00498                   CALL SGEMV( 'Transpose', N-K-1, NRHS, ONE,
00499      $                        B( K+2, 1 ), LDB, A( K+2, K+1 ), 1, ONE,
00500      $                        B( K+1, 1 ), LDB )
00501                   CALL SGEMV( 'Transpose', N-K-1, NRHS, ONE,
00502      $                        B( K+2, 1 ), LDB, A( K+2, K ), 1, ONE,
00503      $                        B( K, 1 ), LDB )
00504                END IF
00505 *
00506 *              Multiply by the diagonal block if non-unit.
00507 *
00508                IF( NOUNIT ) THEN
00509                   D11 = A( K, K )
00510                   D22 = A( K+1, K+1 )
00511                   D21 = A( K+1, K )
00512                   D12 = D21
00513                   DO 110 J = 1, NRHS
00514                      T1 = B( K, J )
00515                      T2 = B( K+1, J )
00516                      B( K, J ) = D11*T1 + D12*T2
00517                      B( K+1, J ) = D21*T1 + D22*T2
00518   110             CONTINUE
00519                END IF
00520                K = K + 2
00521             END IF
00522             GO TO 100
00523   120       CONTINUE
00524          END IF
00525 *
00526       END IF
00527       RETURN
00528 *
00529 *     End of SLAVSY
00530 *
00531       END
 All Files Functions