LAPACK 3.3.0

# zppt03.f

Go to the documentation of this file.
```00001       SUBROUTINE ZPPT03( UPLO, N, A, AINV, WORK, LDWORK, RWORK, RCOND,
00002      \$                   RESID )
00003 *
00004 *  -- LAPACK test routine (version 3.1) --
00005 *     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
00006 *     November 2006
00007 *
00008 *     .. Scalar Arguments ..
00009       CHARACTER          UPLO
00010       INTEGER            LDWORK, N
00011       DOUBLE PRECISION   RCOND, RESID
00012 *     ..
00013 *     .. Array Arguments ..
00014       DOUBLE PRECISION   RWORK( * )
00015       COMPLEX*16         A( * ), AINV( * ), WORK( LDWORK, * )
00016 *     ..
00017 *
00018 *  Purpose
00019 *  =======
00020 *
00021 *  ZPPT03 computes the residual for a Hermitian packed matrix times its
00022 *  inverse:
00023 *     norm( I - A*AINV ) / ( N * norm(A) * norm(AINV) * EPS ),
00024 *  where EPS is the machine epsilon.
00025 *
00026 *  Arguments
00027 *  ==========
00028 *
00029 *  UPLO    (input) CHARACTER*1
00030 *          Specifies whether the upper or lower triangular part of the
00031 *          Hermitian matrix A is stored:
00032 *          = 'U':  Upper triangular
00033 *          = 'L':  Lower triangular
00034 *
00035 *  N       (input) INTEGER
00036 *          The number of rows and columns of the matrix A.  N >= 0.
00037 *
00038 *  A       (input) COMPLEX*16 array, dimension (N*(N+1)/2)
00039 *          The original Hermitian matrix A, stored as a packed
00040 *          triangular matrix.
00041 *
00042 *  AINV    (input) COMPLEX*16 array, dimension (N*(N+1)/2)
00043 *          The (Hermitian) inverse of the matrix A, stored as a packed
00044 *          triangular matrix.
00045 *
00046 *  WORK    (workspace) COMPLEX*16 array, dimension (LDWORK,N)
00047 *
00048 *  LDWORK  (input) INTEGER
00049 *          The leading dimension of the array WORK.  LDWORK >= max(1,N).
00050 *
00051 *  RWORK   (workspace) DOUBLE PRECISION array, dimension (N)
00052 *
00053 *  RCOND   (output) DOUBLE PRECISION
00054 *          The reciprocal of the condition number of A, computed as
00055 *          ( 1/norm(A) ) / norm(AINV).
00056 *
00057 *  RESID   (output) DOUBLE PRECISION
00058 *          norm(I - A*AINV) / ( N * norm(A) * norm(AINV) * EPS )
00059 *
00060 *  =====================================================================
00061 *
00062 *     .. Parameters ..
00063       DOUBLE PRECISION   ZERO, ONE
00064       PARAMETER          ( ZERO = 0.0D+0, ONE = 1.0D+0 )
00065       COMPLEX*16         CZERO, CONE
00066       PARAMETER          ( CZERO = ( 0.0D+0, 0.0D+0 ),
00067      \$                   CONE = ( 1.0D+0, 0.0D+0 ) )
00068 *     ..
00069 *     .. Local Scalars ..
00070       INTEGER            I, J, JJ
00071       DOUBLE PRECISION   AINVNM, ANORM, EPS
00072 *     ..
00073 *     .. External Functions ..
00074       LOGICAL            LSAME
00075       DOUBLE PRECISION   DLAMCH, ZLANGE, ZLANHP
00076       EXTERNAL           LSAME, DLAMCH, ZLANGE, ZLANHP
00077 *     ..
00078 *     .. Intrinsic Functions ..
00079       INTRINSIC          DBLE, DCONJG
00080 *     ..
00081 *     .. External Subroutines ..
00082       EXTERNAL           ZCOPY, ZHPMV
00083 *     ..
00084 *     .. Executable Statements ..
00085 *
00086 *     Quick exit if N = 0.
00087 *
00088       IF( N.LE.0 ) THEN
00089          RCOND = ONE
00090          RESID = ZERO
00091          RETURN
00092       END IF
00093 *
00094 *     Exit with RESID = 1/EPS if ANORM = 0 or AINVNM = 0.
00095 *
00096       EPS = DLAMCH( 'Epsilon' )
00097       ANORM = ZLANHP( '1', UPLO, N, A, RWORK )
00098       AINVNM = ZLANHP( '1', UPLO, N, AINV, RWORK )
00099       IF( ANORM.LE.ZERO .OR. AINVNM.LE.ZERO ) THEN
00100          RCOND = ZERO
00101          RESID = ONE / EPS
00102          RETURN
00103       END IF
00104       RCOND = ( ONE / ANORM ) / AINVNM
00105 *
00106 *     UPLO = 'U':
00107 *     Copy the leading N-1 x N-1 submatrix of AINV to WORK(1:N,2:N) and
00108 *     expand it to a full matrix, then multiply by A one column at a
00109 *     time, moving the result one column to the left.
00110 *
00111       IF( LSAME( UPLO, 'U' ) ) THEN
00112 *
00113 *        Copy AINV
00114 *
00115          JJ = 1
00116          DO 20 J = 1, N - 1
00117             CALL ZCOPY( J, AINV( JJ ), 1, WORK( 1, J+1 ), 1 )
00118             DO 10 I = 1, J - 1
00119                WORK( J, I+1 ) = DCONJG( AINV( JJ+I-1 ) )
00120    10       CONTINUE
00121             JJ = JJ + J
00122    20    CONTINUE
00123          JJ = ( ( N-1 )*N ) / 2 + 1
00124          DO 30 I = 1, N - 1
00125             WORK( N, I+1 ) = DCONJG( AINV( JJ+I-1 ) )
00126    30    CONTINUE
00127 *
00128 *        Multiply by A
00129 *
00130          DO 40 J = 1, N - 1
00131             CALL ZHPMV( 'Upper', N, -CONE, A, WORK( 1, J+1 ), 1, CZERO,
00132      \$                  WORK( 1, J ), 1 )
00133    40    CONTINUE
00134          CALL ZHPMV( 'Upper', N, -CONE, A, AINV( JJ ), 1, CZERO,
00135      \$               WORK( 1, N ), 1 )
00136 *
00137 *     UPLO = 'L':
00138 *     Copy the trailing N-1 x N-1 submatrix of AINV to WORK(1:N,1:N-1)
00139 *     and multiply by A, moving each column to the right.
00140 *
00141       ELSE
00142 *
00143 *        Copy AINV
00144 *
00145          DO 50 I = 1, N - 1
00146             WORK( 1, I ) = DCONJG( AINV( I+1 ) )
00147    50    CONTINUE
00148          JJ = N + 1
00149          DO 70 J = 2, N
00150             CALL ZCOPY( N-J+1, AINV( JJ ), 1, WORK( J, J-1 ), 1 )
00151             DO 60 I = 1, N - J
00152                WORK( J, J+I-1 ) = DCONJG( AINV( JJ+I ) )
00153    60       CONTINUE
00154             JJ = JJ + N - J + 1
00155    70    CONTINUE
00156 *
00157 *        Multiply by A
00158 *
00159          DO 80 J = N, 2, -1
00160             CALL ZHPMV( 'Lower', N, -CONE, A, WORK( 1, J-1 ), 1, CZERO,
00161      \$                  WORK( 1, J ), 1 )
00162    80    CONTINUE
00163          CALL ZHPMV( 'Lower', N, -CONE, A, AINV( 1 ), 1, CZERO,
00164      \$               WORK( 1, 1 ), 1 )
00165 *
00166       END IF
00167 *
00168 *     Add the identity matrix to WORK .
00169 *
00170       DO 90 I = 1, N
00171          WORK( I, I ) = WORK( I, I ) + CONE
00172    90 CONTINUE
00173 *
00174 *     Compute norm(I - A*AINV) / (N * norm(A) * norm(AINV) * EPS)
00175 *
00176       RESID = ZLANGE( '1', N, N, WORK, LDWORK, RWORK )
00177 *
00178       RESID = ( ( RESID*RCOND ) / EPS ) / DBLE( N )
00179 *
00180       RETURN
00181 *
00182 *     End of ZPPT03
00183 *
00184       END
```