LAPACK 3.3.0

zlavhe.f

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