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