LAPACK 3.3.0

dspgst.f

Go to the documentation of this file.
00001       SUBROUTINE DSPGST( ITYPE, UPLO, N, AP, BP, 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, N
00011 *     ..
00012 *     .. Array Arguments ..
00013       DOUBLE PRECISION   AP( * ), BP( * )
00014 *     ..
00015 *
00016 *  Purpose
00017 *  =======
00018 *
00019 *  DSPGST reduces a real symmetric-definite generalized eigenproblem
00020 *  to standard form, using packed storage.
00021 *
00022 *  If ITYPE = 1, the problem is A*x = lambda*B*x,
00023 *  and A is overwritten by inv(U**T)*A*inv(U) or inv(L)*A*inv(L**T)
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**T or L**T*A*L.
00027 *
00028 *  B must have been previously factorized as U**T*U or L*L**T by DPPTRF.
00029 *
00030 *  Arguments
00031 *  =========
00032 *
00033 *  ITYPE   (input) INTEGER
00034 *          = 1: compute inv(U**T)*A*inv(U) or inv(L)*A*inv(L**T);
00035 *          = 2 or 3: compute U*A*U**T or L**T*A*L.
00036 *
00037 *  UPLO    (input) CHARACTER*1
00038 *          = 'U':  Upper triangle of A is stored and B is factored as
00039 *                  U**T*U;
00040 *          = 'L':  Lower triangle of A is stored and B is factored as
00041 *                  L*L**T.
00042 *
00043 *  N       (input) INTEGER
00044 *          The order of the matrices A and B.  N >= 0.
00045 *
00046 *  AP      (input/output) DOUBLE PRECISION array, dimension (N*(N+1)/2)
00047 *          On entry, the upper or lower triangle of the symmetric matrix
00048 *          A, packed columnwise in a linear array.  The j-th column of A
00049 *          is stored in the array AP as follows:
00050 *          if UPLO = 'U', AP(i + (j-1)*j/2) = A(i,j) for 1<=i<=j;
00051 *          if UPLO = 'L', AP(i + (j-1)*(2n-j)/2) = A(i,j) for j<=i<=n.
00052 *
00053 *          On exit, if INFO = 0, the transformed matrix, stored in the
00054 *          same format as A.
00055 *
00056 *  BP      (input) DOUBLE PRECISION array, dimension (N*(N+1)/2)
00057 *          The triangular factor from the Cholesky factorization of B,
00058 *          stored in the same format as A, as returned by DPPTRF.
00059 *
00060 *  INFO    (output) INTEGER
00061 *          = 0:  successful exit
00062 *          < 0:  if INFO = -i, the i-th argument had an illegal value
00063 *
00064 *  =====================================================================
00065 *
00066 *     .. Parameters ..
00067       DOUBLE PRECISION   ONE, HALF
00068       PARAMETER          ( ONE = 1.0D0, HALF = 0.5D0 )
00069 *     ..
00070 *     .. Local Scalars ..
00071       LOGICAL            UPPER
00072       INTEGER            J, J1, J1J1, JJ, K, K1, K1K1, KK
00073       DOUBLE PRECISION   AJJ, AKK, BJJ, BKK, CT
00074 *     ..
00075 *     .. External Subroutines ..
00076       EXTERNAL           DAXPY, DSCAL, DSPMV, DSPR2, DTPMV, DTPSV,
00077      $                   XERBLA
00078 *     ..
00079 *     .. External Functions ..
00080       LOGICAL            LSAME
00081       DOUBLE PRECISION   DDOT
00082       EXTERNAL           LSAME, DDOT
00083 *     ..
00084 *     .. Executable Statements ..
00085 *
00086 *     Test the input parameters.
00087 *
00088       INFO = 0
00089       UPPER = LSAME( UPLO, 'U' )
00090       IF( ITYPE.LT.1 .OR. ITYPE.GT.3 ) THEN
00091          INFO = -1
00092       ELSE IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THEN
00093          INFO = -2
00094       ELSE IF( N.LT.0 ) THEN
00095          INFO = -3
00096       END IF
00097       IF( INFO.NE.0 ) THEN
00098          CALL XERBLA( 'DSPGST', -INFO )
00099          RETURN
00100       END IF
00101 *
00102       IF( ITYPE.EQ.1 ) THEN
00103          IF( UPPER ) THEN
00104 *
00105 *           Compute inv(U')*A*inv(U)
00106 *
00107 *           J1 and JJ are the indices of A(1,j) and A(j,j)
00108 *
00109             JJ = 0
00110             DO 10 J = 1, N
00111                J1 = JJ + 1
00112                JJ = JJ + J
00113 *
00114 *              Compute the j-th column of the upper triangle of A
00115 *
00116                BJJ = BP( JJ )
00117                CALL DTPSV( UPLO, 'Transpose', 'Nonunit', J, BP,
00118      $                     AP( J1 ), 1 )
00119                CALL DSPMV( UPLO, J-1, -ONE, AP, BP( J1 ), 1, ONE,
00120      $                     AP( J1 ), 1 )
00121                CALL DSCAL( J-1, ONE / BJJ, AP( J1 ), 1 )
00122                AP( JJ ) = ( AP( JJ )-DDOT( J-1, AP( J1 ), 1, BP( J1 ),
00123      $                    1 ) ) / BJJ
00124    10       CONTINUE
00125          ELSE
00126 *
00127 *           Compute inv(L)*A*inv(L')
00128 *
00129 *           KK and K1K1 are the indices of A(k,k) and A(k+1,k+1)
00130 *
00131             KK = 1
00132             DO 20 K = 1, N
00133                K1K1 = KK + N - K + 1
00134 *
00135 *              Update the lower triangle of A(k:n,k:n)
00136 *
00137                AKK = AP( KK )
00138                BKK = BP( KK )
00139                AKK = AKK / BKK**2
00140                AP( KK ) = AKK
00141                IF( K.LT.N ) THEN
00142                   CALL DSCAL( N-K, ONE / BKK, AP( KK+1 ), 1 )
00143                   CT = -HALF*AKK
00144                   CALL DAXPY( N-K, CT, BP( KK+1 ), 1, AP( KK+1 ), 1 )
00145                   CALL DSPR2( UPLO, N-K, -ONE, AP( KK+1 ), 1,
00146      $                        BP( KK+1 ), 1, AP( K1K1 ) )
00147                   CALL DAXPY( N-K, CT, BP( KK+1 ), 1, AP( KK+1 ), 1 )
00148                   CALL DTPSV( UPLO, 'No transpose', 'Non-unit', N-K,
00149      $                        BP( K1K1 ), AP( KK+1 ), 1 )
00150                END IF
00151                KK = K1K1
00152    20       CONTINUE
00153          END IF
00154       ELSE
00155          IF( UPPER ) THEN
00156 *
00157 *           Compute U*A*U'
00158 *
00159 *           K1 and KK are the indices of A(1,k) and A(k,k)
00160 *
00161             KK = 0
00162             DO 30 K = 1, N
00163                K1 = KK + 1
00164                KK = KK + K
00165 *
00166 *              Update the upper triangle of A(1:k,1:k)
00167 *
00168                AKK = AP( KK )
00169                BKK = BP( KK )
00170                CALL DTPMV( UPLO, 'No transpose', 'Non-unit', K-1, BP,
00171      $                     AP( K1 ), 1 )
00172                CT = HALF*AKK
00173                CALL DAXPY( K-1, CT, BP( K1 ), 1, AP( K1 ), 1 )
00174                CALL DSPR2( UPLO, K-1, ONE, AP( K1 ), 1, BP( K1 ), 1,
00175      $                     AP )
00176                CALL DAXPY( K-1, CT, BP( K1 ), 1, AP( K1 ), 1 )
00177                CALL DSCAL( K-1, BKK, AP( K1 ), 1 )
00178                AP( KK ) = AKK*BKK**2
00179    30       CONTINUE
00180          ELSE
00181 *
00182 *           Compute L'*A*L
00183 *
00184 *           JJ and J1J1 are the indices of A(j,j) and A(j+1,j+1)
00185 *
00186             JJ = 1
00187             DO 40 J = 1, N
00188                J1J1 = JJ + N - J + 1
00189 *
00190 *              Compute the j-th column of the lower triangle of A
00191 *
00192                AJJ = AP( JJ )
00193                BJJ = BP( JJ )
00194                AP( JJ ) = AJJ*BJJ + DDOT( N-J, AP( JJ+1 ), 1,
00195      $                    BP( JJ+1 ), 1 )
00196                CALL DSCAL( N-J, BJJ, AP( JJ+1 ), 1 )
00197                CALL DSPMV( UPLO, N-J, ONE, AP( J1J1 ), BP( JJ+1 ), 1,
00198      $                     ONE, AP( JJ+1 ), 1 )
00199                CALL DTPMV( UPLO, 'Transpose', 'Non-unit', N-J+1,
00200      $                     BP( JJ ), AP( JJ ), 1 )
00201                JJ = J1J1
00202    40       CONTINUE
00203          END IF
00204       END IF
00205       RETURN
00206 *
00207 *     End of DSPGST
00208 *
00209       END
 All Files Functions