1       SUBROUTINE CHPT01( UPLO, N, A, AFAC, IPIV, C, LDC, RWORK, RESID )
  2 *
  3 *  -- LAPACK test routine (version 3.1) --
  4 *     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
  5 *     November 2006
  6 *
  7 *     .. Scalar Arguments ..
  8       CHARACTER          UPLO
  9       INTEGER            LDC, N
 10       REAL               RESID
 11 *     ..
 12 *     .. Array Arguments ..
 13       INTEGER            IPIV( * )
 14       REAL               RWORK( * )
 15       COMPLEX            A( * ), AFAC( * ), C( LDC, * )
 16 *     ..
 17 *
 18 *  Purpose
 19 *  =======
 20 *
 21 *  CHPT01 reconstructs a Hermitian indefinite packed matrix A from its
 22 *  block L*D*L' or U*D*U' factorization and computes the residual
 23 *     norm( C - A ) / ( N * norm(A) * EPS ),
 24 *  where C is the reconstructed matrix, EPS is the machine epsilon,
 25 *  L' is the conjugate transpose of L, and U' is the conjugate transpose
 26 *  of U.
 27 *
 28 *  Arguments
 29 *  ==========
 30 *
 31 *  UPLO    (input) CHARACTER*1
 32 *          Specifies whether the upper or lower triangular part of the
 33 *          Hermitian matrix A is stored:
 34 *          = 'U':  Upper triangular
 35 *          = 'L':  Lower triangular
 36 *
 37 *  N       (input) INTEGER
 38 *          The number of rows and columns of the matrix A.  N >= 0.
 39 *
 40 *  A       (input) COMPLEX array, dimension (N*(N+1)/2)
 41 *          The original Hermitian matrix A, stored as a packed
 42 *          triangular matrix.
 43 *
 44 *  AFAC    (input) COMPLEX array, dimension (N*(N+1)/2)
 45 *          The factored form of the matrix A, stored as a packed
 46 *          triangular matrix.  AFAC contains the block diagonal matrix D
 47 *          and the multipliers used to obtain the factor L or U from the
 48 *          block L*D*L' or U*D*U' factorization as computed by CHPTRF.
 49 *
 50 *  IPIV    (input) INTEGER array, dimension (N)
 51 *          The pivot indices from CHPTRF.
 52 *
 53 *  C       (workspace) COMPLEX array, dimension (LDC,N)
 54 *
 55 *  LDC     (integer) INTEGER
 56 *          The leading dimension of the array C.  LDC >= max(1,N).
 57 *
 58 *  RWORK   (workspace) REAL array, dimension (N)
 59 *
 60 *  RESID   (output) REAL
 61 *          If UPLO = 'L', norm(L*D*L' - A) / ( N * norm(A) * EPS )
 62 *          If UPLO = 'U', norm(U*D*U' - A) / ( N * norm(A) * EPS )
 63 *
 64 *  =====================================================================
 65 *
 66 *     .. Parameters ..
 67       REAL               ZERO, ONE
 68       PARAMETER          ( ZERO = 0.0E+0, ONE = 1.0E+0 )
 69       COMPLEX            CZERO, CONE
 70       PARAMETER          ( CZERO = ( 0.0E+00.0E+0 ),
 71      $                   CONE = ( 1.0E+00.0E+0 ) )
 72 *     ..
 73 *     .. Local Scalars ..
 74       INTEGER            I, INFO, J, JC
 75       REAL               ANORM, EPS
 76 *     ..
 77 *     .. External Functions ..
 78       LOGICAL            LSAME
 79       REAL               CLANHE, CLANHP, SLAMCH
 80       EXTERNAL           LSAME, CLANHE, CLANHP, SLAMCH
 81 *     ..
 82 *     .. External Subroutines ..
 83       EXTERNAL           CLAVHP, CLASET
 84 *     ..
 85 *     .. Intrinsic Functions ..
 86       INTRINSIC          AIMAG, REAL
 87 *     ..
 88 *     .. Executable Statements ..
 89 *
 90 *     Quick exit if N = 0.
 91 *
 92       IF( N.LE.0 ) THEN
 93          RESID = ZERO
 94          RETURN
 95       END IF
 96 *
 97 *     Determine EPS and the norm of A.
 98 *
 99       EPS = SLAMCH( 'Epsilon' )
100       ANORM = CLANHP( '1', UPLO, N, A, RWORK )
101 *
102 *     Check the imaginary parts of the diagonal elements and return with
103 *     an error code if any are nonzero.
104 *
105       JC = 1
106       IF( LSAME( UPLO, 'U' ) ) THEN
107          DO 10 J = 1, N
108             IFAIMAG( AFAC( JC ) ).NE.ZERO ) THEN
109                RESID = ONE / EPS
110                RETURN
111             END IF
112             JC = JC + J + 1
113    10    CONTINUE
114       ELSE
115          DO 20 J = 1, N
116             IFAIMAG( AFAC( JC ) ).NE.ZERO ) THEN
117                RESID = ONE / EPS
118                RETURN
119             END IF
120             JC = JC + N - J + 1
121    20    CONTINUE
122       END IF
123 *
124 *     Initialize C to the identity matrix.
125 *
126       CALL CLASET( 'Full', N, N, CZERO, CONE, C, LDC )
127 *
128 *     Call CLAVHP to form the product D * U' (or D * L' ).
129 *
130       CALL CLAVHP( UPLO, 'Conjugate''Non-unit', N, N, AFAC, IPIV, C,
131      $             LDC, INFO )
132 *
133 *     Call CLAVHP again to multiply by U ( or L ).
134 *
135       CALL CLAVHP( UPLO, 'No transpose''Unit', N, N, AFAC, IPIV, C,
136      $             LDC, INFO )
137 *
138 *     Compute the difference  C - A .
139 *
140       IF( LSAME( UPLO, 'U' ) ) THEN
141          JC = 0
142          DO 40 J = 1, N
143             DO 30 I = 1, J - 1
144                C( I, J ) = C( I, J ) - A( JC+I )
145    30       CONTINUE
146             C( J, J ) = C( J, J ) - REAL( A( JC+J ) )
147             JC = JC + J
148    40    CONTINUE
149       ELSE
150          JC = 1
151          DO 60 J = 1, N
152             C( J, J ) = C( J, J ) - REAL( A( JC ) )
153             DO 50 I = J + 1, N
154                C( I, J ) = C( I, J ) - A( JC+I-J )
155    50       CONTINUE
156             JC = JC + N - J + 1
157    60    CONTINUE
158       END IF
159 *
160 *     Compute norm( C - A ) / ( N * norm(A) * EPS )
161 *
162       RESID = CLANHE( '1', UPLO, N, C, LDC, RWORK )
163 *
164       IF( ANORM.LE.ZERO ) THEN
165          IF( RESID.NE.ZERO )
166      $      RESID = ONE / EPS
167       ELSE
168          RESID = ( ( RESID / REAL( N ) ) / ANORM ) / EPS
169       END IF
170 *
171       RETURN
172 *
173 *     End of CHPT01
174 *
175       END