1       SUBROUTINE ZGET03( N, A, LDA, AINV, LDAINV, WORK, LDWORK, RWORK,
  2      $                   RCOND, RESID )
  3 *
  4 *  -- LAPACK test routine (version 3.1) --
  5 *     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
  6 *     November 2006
  7 *
  8 *     .. Scalar Arguments ..
  9       INTEGER            LDA, LDAINV, LDWORK, N
 10       DOUBLE PRECISION   RCOND, RESID
 11 *     ..
 12 *     .. Array Arguments ..
 13       DOUBLE PRECISION   RWORK( * )
 14       COMPLEX*16         A( LDA, * ), AINV( LDAINV, * ),
 15      $                   WORK( LDWORK, * )
 16 *     ..
 17 *
 18 *  Purpose
 19 *  =======
 20 *
 21 *  ZGET03 computes the residual for a general matrix times its inverse:
 22 *     norm( I - AINV*A ) / ( N * norm(A) * norm(AINV) * EPS ),
 23 *  where EPS is the machine epsilon.
 24 *
 25 *  Arguments
 26 *  ==========
 27 *
 28 *  N       (input) INTEGER
 29 *          The number of rows and columns of the matrix A.  N >= 0.
 30 *
 31 *  A       (input) COMPLEX*16 array, dimension (LDA,N)
 32 *          The original N x N matrix A.
 33 *
 34 *  LDA     (input) INTEGER
 35 *          The leading dimension of the array A.  LDA >= max(1,N).
 36 *
 37 *  AINV    (input) COMPLEX*16 array, dimension (LDAINV,N)
 38 *          The inverse of the matrix A.
 39 *
 40 *  LDAINV  (input) INTEGER
 41 *          The leading dimension of the array AINV.  LDAINV >= max(1,N).
 42 *
 43 *  WORK    (workspace) COMPLEX*16 array, dimension (LDWORK,N)
 44 *
 45 *  LDWORK  (input) INTEGER
 46 *          The leading dimension of the array WORK.  LDWORK >= max(1,N).
 47 *
 48 *  RWORK   (workspace) DOUBLE PRECISION array, dimension (N)
 49 *
 50 *  RCOND   (output) DOUBLE PRECISION
 51 *          The reciprocal of the condition number of A, computed as
 52 *          ( 1/norm(A) ) / norm(AINV).
 53 *
 54 *  RESID   (output) DOUBLE PRECISION
 55 *          norm(I - AINV*A) / ( N * norm(A) * norm(AINV) * EPS )
 56 *
 57 *  =====================================================================
 58 *
 59 *     .. Parameters ..
 60       DOUBLE PRECISION   ZERO, ONE
 61       PARAMETER          ( ZERO = 0.0D+0, ONE = 1.0D+0 )
 62       COMPLEX*16         CZERO, CONE
 63       PARAMETER          ( CZERO = ( 0.0D+00.0D+0 ),
 64      $                   CONE = ( 1.0D+00.0D+0 ) )
 65 *     ..
 66 *     .. Local Scalars ..
 67       INTEGER            I
 68       DOUBLE PRECISION   AINVNM, ANORM, EPS
 69 *     ..
 70 *     .. External Functions ..
 71       DOUBLE PRECISION   DLAMCH, ZLANGE
 72       EXTERNAL           DLAMCH, ZLANGE
 73 *     ..
 74 *     .. External Subroutines ..
 75       EXTERNAL           ZGEMM
 76 *     ..
 77 *     .. Intrinsic Functions ..
 78       INTRINSIC          DBLE
 79 *     ..
 80 *     .. Executable Statements ..
 81 *
 82 *     Quick exit if N = 0.
 83 *
 84       IF( N.LE.0 ) THEN
 85          RCOND = ONE
 86          RESID = ZERO
 87          RETURN
 88       END IF
 89 *
 90 *     Exit with RESID = 1/EPS if ANORM = 0 or AINVNM = 0.
 91 *
 92       EPS = DLAMCH( 'Epsilon' )
 93       ANORM = ZLANGE( '1', N, N, A, LDA, RWORK )
 94       AINVNM = ZLANGE( '1', N, N, AINV, LDAINV, RWORK )
 95       IF( ANORM.LE.ZERO .OR. AINVNM.LE.ZERO ) THEN
 96          RCOND = ZERO
 97          RESID = ONE / EPS
 98          RETURN
 99       END IF
100       RCOND = ( ONE / ANORM ) / AINVNM
101 *
102 *     Compute I - A * AINV
103 *
104       CALL ZGEMM( 'No transpose''No transpose', N, N, N, -CONE, AINV,
105      $            LDAINV, A, LDA, CZERO, WORK, LDWORK )
106       DO 10 I = 1, N
107          WORK( I, I ) = CONE + WORK( I, I )
108    10 CONTINUE
109 *
110 *     Compute norm(I - AINV*A) / (N * norm(A) * norm(AINV) * EPS)
111 *
112       RESID = ZLANGE( '1', N, N, WORK, LDWORK, RWORK )
113 *
114       RESID = ( ( RESID*RCOND ) / EPS ) / DBLE( N )
115 *
116       RETURN
117 *
118 *     End of ZGET03
119 *
120       END