LAPACK 3.3.0

zhegs2.f

Go to the documentation of this file.
00001       SUBROUTINE ZHEGS2( ITYPE, UPLO, N, A, LDA, B, LDB, INFO )
00002 *
00003 *  -- LAPACK routine (version 3.2) --
00004 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
00005 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
00006 *     November 2006
00007 *
00008 *     .. Scalar Arguments ..
00009       CHARACTER          UPLO
00010       INTEGER            INFO, ITYPE, LDA, LDB, N
00011 *     ..
00012 *     .. Array Arguments ..
00013       COMPLEX*16         A( LDA, * ), B( LDB, * )
00014 *     ..
00015 *
00016 *  Purpose
00017 *  =======
00018 *
00019 *  ZHEGS2 reduces a complex Hermitian-definite generalized
00020 *  eigenproblem to standard form.
00021 *
00022 *  If ITYPE = 1, the problem is A*x = lambda*B*x,
00023 *  and A is overwritten by inv(U')*A*inv(U) or inv(L)*A*inv(L')
00024 *
00025 *  If ITYPE = 2 or 3, the problem is A*B*x = lambda*x or
00026 *  B*A*x = lambda*x, and A is overwritten by U*A*U` or L'*A*L.
00027 *
00028 *  B must have been previously factorized as U'*U or L*L' by ZPOTRF.
00029 *
00030 *  Arguments
00031 *  =========
00032 *
00033 *  ITYPE   (input) INTEGER
00034 *          = 1: compute inv(U')*A*inv(U) or inv(L)*A*inv(L');
00035 *          = 2 or 3: compute U*A*U' or L'*A*L.
00036 *
00037 *  UPLO    (input) CHARACTER*1
00038 *          Specifies whether the upper or lower triangular part of the
00039 *          Hermitian matrix A is stored, and how B has been factorized.
00040 *          = 'U':  Upper triangular
00041 *          = 'L':  Lower triangular
00042 *
00043 *  N       (input) INTEGER
00044 *          The order of the matrices A and B.  N >= 0.
00045 *
00046 *  A       (input/output) COMPLEX*16 array, dimension (LDA,N)
00047 *          On entry, the Hermitian matrix A.  If UPLO = 'U', the leading
00048 *          n by n upper triangular part of A contains the upper
00049 *          triangular part of the matrix A, and the strictly lower
00050 *          triangular part of A is not referenced.  If UPLO = 'L', the
00051 *          leading n by n lower triangular part of A contains the lower
00052 *          triangular part of the matrix A, and the strictly upper
00053 *          triangular part of A is not referenced.
00054 *
00055 *          On exit, if INFO = 0, the transformed matrix, stored in the
00056 *          same format as A.
00057 *
00058 *  LDA     (input) INTEGER
00059 *          The leading dimension of the array A.  LDA >= max(1,N).
00060 *
00061 *  B       (input) COMPLEX*16 array, dimension (LDB,N)
00062 *          The triangular factor from the Cholesky factorization of B,
00063 *          as returned by ZPOTRF.
00064 *
00065 *  LDB     (input) INTEGER
00066 *          The leading dimension of the array B.  LDB >= max(1,N).
00067 *
00068 *  INFO    (output) INTEGER
00069 *          = 0:  successful exit.
00070 *          < 0:  if INFO = -i, the i-th argument had an illegal value.
00071 *
00072 *  =====================================================================
00073 *
00074 *     .. Parameters ..
00075       DOUBLE PRECISION   ONE, HALF
00076       PARAMETER          ( ONE = 1.0D+0, HALF = 0.5D+0 )
00077       COMPLEX*16         CONE
00078       PARAMETER          ( CONE = ( 1.0D+0, 0.0D+0 ) )
00079 *     ..
00080 *     .. Local Scalars ..
00081       LOGICAL            UPPER
00082       INTEGER            K
00083       DOUBLE PRECISION   AKK, BKK
00084       COMPLEX*16         CT
00085 *     ..
00086 *     .. External Subroutines ..
00087       EXTERNAL           XERBLA, ZAXPY, ZDSCAL, ZHER2, ZLACGV, ZTRMV,
00088      $                   ZTRSV
00089 *     ..
00090 *     .. Intrinsic Functions ..
00091       INTRINSIC          MAX
00092 *     ..
00093 *     .. External Functions ..
00094       LOGICAL            LSAME
00095       EXTERNAL           LSAME
00096 *     ..
00097 *     .. Executable Statements ..
00098 *
00099 *     Test the input parameters.
00100 *
00101       INFO = 0
00102       UPPER = LSAME( UPLO, 'U' )
00103       IF( ITYPE.LT.1 .OR. ITYPE.GT.3 ) THEN
00104          INFO = -1
00105       ELSE IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THEN
00106          INFO = -2
00107       ELSE IF( N.LT.0 ) THEN
00108          INFO = -3
00109       ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
00110          INFO = -5
00111       ELSE IF( LDB.LT.MAX( 1, N ) ) THEN
00112          INFO = -7
00113       END IF
00114       IF( INFO.NE.0 ) THEN
00115          CALL XERBLA( 'ZHEGS2', -INFO )
00116          RETURN
00117       END IF
00118 *
00119       IF( ITYPE.EQ.1 ) THEN
00120          IF( UPPER ) THEN
00121 *
00122 *           Compute inv(U')*A*inv(U)
00123 *
00124             DO 10 K = 1, N
00125 *
00126 *              Update the upper triangle of A(k:n,k:n)
00127 *
00128                AKK = A( K, K )
00129                BKK = B( K, K )
00130                AKK = AKK / BKK**2
00131                A( K, K ) = AKK
00132                IF( K.LT.N ) THEN
00133                   CALL ZDSCAL( N-K, ONE / BKK, A( K, K+1 ), LDA )
00134                   CT = -HALF*AKK
00135                   CALL ZLACGV( N-K, A( K, K+1 ), LDA )
00136                   CALL ZLACGV( N-K, B( K, K+1 ), LDB )
00137                   CALL ZAXPY( N-K, CT, B( K, K+1 ), LDB, A( K, K+1 ),
00138      $                        LDA )
00139                   CALL ZHER2( UPLO, N-K, -CONE, A( K, K+1 ), LDA,
00140      $                        B( K, K+1 ), LDB, A( K+1, K+1 ), LDA )
00141                   CALL ZAXPY( N-K, CT, B( K, K+1 ), LDB, A( K, K+1 ),
00142      $                        LDA )
00143                   CALL ZLACGV( N-K, B( K, K+1 ), LDB )
00144                   CALL ZTRSV( UPLO, 'Conjugate transpose', 'Non-unit',
00145      $                        N-K, B( K+1, K+1 ), LDB, A( K, K+1 ),
00146      $                        LDA )
00147                   CALL ZLACGV( N-K, A( K, K+1 ), LDA )
00148                END IF
00149    10       CONTINUE
00150          ELSE
00151 *
00152 *           Compute inv(L)*A*inv(L')
00153 *
00154             DO 20 K = 1, N
00155 *
00156 *              Update the lower triangle of A(k:n,k:n)
00157 *
00158                AKK = A( K, K )
00159                BKK = B( K, K )
00160                AKK = AKK / BKK**2
00161                A( K, K ) = AKK
00162                IF( K.LT.N ) THEN
00163                   CALL ZDSCAL( N-K, ONE / BKK, A( K+1, K ), 1 )
00164                   CT = -HALF*AKK
00165                   CALL ZAXPY( N-K, CT, B( K+1, K ), 1, A( K+1, K ), 1 )
00166                   CALL ZHER2( UPLO, N-K, -CONE, A( K+1, K ), 1,
00167      $                        B( K+1, K ), 1, A( K+1, K+1 ), LDA )
00168                   CALL ZAXPY( N-K, CT, B( K+1, K ), 1, A( K+1, K ), 1 )
00169                   CALL ZTRSV( UPLO, 'No transpose', 'Non-unit', N-K,
00170      $                        B( K+1, K+1 ), LDB, A( K+1, K ), 1 )
00171                END IF
00172    20       CONTINUE
00173          END IF
00174       ELSE
00175          IF( UPPER ) THEN
00176 *
00177 *           Compute U*A*U'
00178 *
00179             DO 30 K = 1, N
00180 *
00181 *              Update the upper triangle of A(1:k,1:k)
00182 *
00183                AKK = A( K, K )
00184                BKK = B( K, K )
00185                CALL ZTRMV( UPLO, 'No transpose', 'Non-unit', K-1, B,
00186      $                     LDB, A( 1, K ), 1 )
00187                CT = HALF*AKK
00188                CALL ZAXPY( K-1, CT, B( 1, K ), 1, A( 1, K ), 1 )
00189                CALL ZHER2( UPLO, K-1, CONE, A( 1, K ), 1, B( 1, K ), 1,
00190      $                     A, LDA )
00191                CALL ZAXPY( K-1, CT, B( 1, K ), 1, A( 1, K ), 1 )
00192                CALL ZDSCAL( K-1, BKK, A( 1, K ), 1 )
00193                A( K, K ) = AKK*BKK**2
00194    30       CONTINUE
00195          ELSE
00196 *
00197 *           Compute L'*A*L
00198 *
00199             DO 40 K = 1, N
00200 *
00201 *              Update the lower triangle of A(1:k,1:k)
00202 *
00203                AKK = A( K, K )
00204                BKK = B( K, K )
00205                CALL ZLACGV( K-1, A( K, 1 ), LDA )
00206                CALL ZTRMV( UPLO, 'Conjugate transpose', 'Non-unit', K-1,
00207      $                     B, LDB, A( K, 1 ), LDA )
00208                CT = HALF*AKK
00209                CALL ZLACGV( K-1, B( K, 1 ), LDB )
00210                CALL ZAXPY( K-1, CT, B( K, 1 ), LDB, A( K, 1 ), LDA )
00211                CALL ZHER2( UPLO, K-1, CONE, A( K, 1 ), LDA, B( K, 1 ),
00212      $                     LDB, A, LDA )
00213                CALL ZAXPY( K-1, CT, B( K, 1 ), LDB, A( K, 1 ), LDA )
00214                CALL ZLACGV( K-1, B( K, 1 ), LDB )
00215                CALL ZDSCAL( K-1, BKK, A( K, 1 ), LDA )
00216                CALL ZLACGV( K-1, A( K, 1 ), LDA )
00217                A( K, K ) = AKK*BKK**2
00218    40       CONTINUE
00219          END IF
00220       END IF
00221       RETURN
00222 *
00223 *     End of ZHEGS2
00224 *
00225       END
 All Files Functions