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