      SUBROUTINE ZREADM( NMAX, NZMAX, JOB, IOUNIT, TITLE, KEY, TYPE,
     $                   NROW, NCOL, NNZ, A, COLPTR, ROWIND, RHS, 
     $                   INFO )
*     .. 
*     .. Scalar Arguments .. 
      CHARACTER          TITLE*72, KEY*8, TYPE*3
      INTEGER            JOB, IOUNIT, INFO, NROW, NCOL, NNZ, NMAX, 
     $                   NZMAX 
*     .. 
*     .. Array Arguments .. 
      INTEGER            COLPTR( * ), ROWIND( * ) 
      COMPLEX*16         A( * ), RHS( * )
*
*
*  Purpose
*  =======
*
*  reads a matrix which is in the standard Harwell-Beoing format (but
*  it is a complex matrix). The matrix A is stored in compressed column
*  format.
*
*  This routine is a modified version of the routine READMT in SPARSKIT
*  by Y. Saad (Univ. of Minnesota).
*
*  Arguments
*  =========
*
*  NMAX    (input) INTEGER
*          max dimension allowed for matrix A. 
*
*  NZMAX   (input) INTEGER
*          max number of nonzeros elements allowed in matrix A. 
*
*  JOB     (input/output) INTEGER 
*          On input, JOB indicates what is to be read. 
*           JOB = 0, read the values of NCOL, NROW, NNZ, TITLE, KEY,
*                    TYPE and return. matrix is not read and arrays
*                    A, COLPTR and ROWIND are not touched.
*           JOB = 1, read structure, i.e., the arrays COLPTR and
*                    ROWIND. 
*           JOB = 2, read matrix including values, i.e., A, COLPTR,  
*                    ROWIND 
*           JOB = 3, read matrix and right hand side: A, COLPTR, 
*                    ROWIND, RHS.
*          On output, JOB decreases to the highest job possible: if 
*          JOB = 2 on entry but no matrix values are available it is 
*          reset to JOB = 1 on return. Similarly of JOB = 3 but no RHS 
*          is provided then it is rest to JOB = 2 or JOB = 1 depending 
*          on whether or not matrix values are provided.
*
* IOUNIT   (input) INTEGER 
*          logical unit number from which to read the matrix.
*
* TITLE    (output) CHARACTER*72
*          title of matrix 
*
* KEY      (output) CHARACTER*8
*          key of matrix
*
* TYPE     (output) CHARATCER*3
*          type of matrix.
*
* NROW     (output) INTEGER
*          number of rows in matrix A
*
* NCOL     (output) INTEGER
*          number of columns in matrix  A
*
* NNZ      (output) INTEGER
*          number of nonzero elements in A. It is returned even if there
*          is not enough space in A, ROWIND, COLPTR to allow the user
*          to determine the storage needed.
*
* A	   (output) COMPLEX*16 array, dimension (NNZ) 
*          the non-zero numerical values of the matrix ordered by column.
*
* COLPTR   (output) INTEGER array, dimension( NCOL+1 ). 
*          column pointer, COLPTR(I) points to the beginning of column I, 
*          and COLPTR(NCOL+1) = NNZ+1.
*
* ROWIND   (output) INTEGER array, dimension( NNZ )
*          row (or varilable) indices number of element a(i,j) in 
*          array A.
*
* RHS      (output) COMPLEX*16 array, dimension (NROW+1)  
*          The right hand side of the linear system if exists. 
*
* INFO     (output) integer 
*          info = 0, the matrix has been read normally. 
*          info = 1, the array matrix could not be read because 
*                    NCOL+1 .GT. NMAX
*          info = 2, the array matrix could not be read 
*                    because NNZ.GT.NZMAX
*          info = 3, the array matrix could not be read because both 
*                    (NCOL+1 .GT. NMAX) and  (NNZ .GT. NZMAX )
*
* ======================================================================       
*
*     .. Local variables ..
      CHARACTER          PTRFMT*16, INDFMT*16, VALFMT*20, RHSFMT*20
      INTEGER            I, TOTCRD, PTRCRD, INDCRD, VALCRD, RHSCRD,
     $                   N, NRHS
*     .. 
*     .. Executable statements ..
*
      READ(IOUNIT,10)TITLE, KEY, TOTCRD, PTRCRD, INDCRD, VALCRD, 
     $               RHSCRD, TYPE, NROW, NCOL, NNZ, NRHS, PTRFMT, 
     $               INDFMT, VALFMT, RHSFMT
 10   FORMAT(A72,A8/5I14/A3,11X,4I14/2A16,2A20)
*
*     If nothing to read, exit 
*
      IF ( JOB .LE. 0 ) 
     $   RETURN
*
*     check whether matrix is readable 
*
      INFO = 0
      N = NCOL
      IF ( NCOL+1 .GT. NMAX) 
     $   INFO = 1
      IF (NNZ .GT. NZMAX) 
     $   INFO = INFO + 2
      IF (INFO .NE. 0) 
     $   RETURN
*
*     read pointer and row numbers 
*
      READ(IOUNIT,PTRFMT)(COLPTR(I), I = 1, N+1)
      READ(IOUNIT,INDFMT)(ROWIND(I), I = 1, NNZ)
*
*     reading values of matrix if required
*
      IF (JOB .LE. 1)  
     $   RETURN
*
      IF (VALCRD .LE. 0) THEN
	 JOB = 1
	 RETURN
      END If
*
      READ(IOUNIT,VALFMT)(A(I), I = 1, NNZ)
*
*     reading RHS if required
*
      IF (JOB .LE. 2)  
     $   RETURN
*
      IF ( RHSCRD .LE. 0) THEN
	 JOB = 2
	 RETURN
      ENDIF
      READ(IOUNIT,RHSFMT)(RHS(I), I = 1, NROW)
*
      RETURN
*
*     END of ZREADM 
*
      END
