SUBROUTINE RANKV(MATFIL,OUTFIL,NSTATS,M,ERRCD,ERRMSG) C C FUNCTION: CF CF C USAGE: CU CU C INPUTS: CI CI C OUTPUTS: CO CO C ALGORITHM: CA CA C MACHINE DEPENDENCIES: CM CM C HISTORY: CH CH written by: CH date: CH current version: CH modifications: CH added dpcom: 7/16/88 jdb CH C ROUTINES CALLED: CC CC C COMMON MEMORY USED: CM CM DPCOM -- see dpcommon.f and dpcom.f CM C---------------------------------------------------------------------- C written for: The CASCADE Project C Oak Ridge National Laboratory C U.S. Department of Energy C contract number DE-AC05-840R21400 C subcontract number 37B-07685C S13 C organization: The University of Tennessee C---------------------------------------------------------------------- C THIS SOFTWARE IS IN THE PUBLIC DOMAIN C NO RESTRICTIONS ON ITS USE ARE IMPLIED C---------------------------------------------------------------------- C C INCLUDE 'Parameter.f' C DOUBLE PRECISION A(SIZE,SIZE) DOUBLE PRECISION B(SIZE,SIZE) DOUBLE PRECISION SIGMA(SIZE) DOUBLE PRECISION U DOUBLE PRECISION V DOUBLE PRECISION E(SIZE) DOUBLE PRECISION WORK(SIZE) DOUBLE PRECISION EPS DOUBLE PRECISION EPS1 DOUBLE PRECISION EPSLON C INTEGER NSTATS INTEGER M INTEGER ERRCD C CHARACTER*(*) MATFIL CHARACTER*(*) OUTFIL CHARACTER*(*) ERRMSG C INCLUDE 'dpcom.f' C IF (NSTATS .GT. SIZE .OR. M .GT. SIZE) THEN ERRCD = 100 ERRMSG = 'RANKV: Fatal Error; The matrix is too big.' RETURN END IF C C--read the matrices C OPEN (UNIT=UNIT1,FILE=MATFIL,STATUS='OLD',ERR=9999) C DO 20, I = 1, NSTATS READ (UNIT1,*,END=9999,ERR=9999) (A(J,I),J=1,NSTATS) 20 CONTINUE C DO 30, I = 1, M READ (UNIT1,*,END=9999,ERR=9999) (B(J,I),J=1,M) 30 CONTINUE C CLOSE (UNIT=UNIT1) C C--use SVD to calculate the rank of b C JOB = 0 CALL DSVDC (B,SIZE,M,M,SIGMA,E,U,1,V,1,WORK,JOB,INFO) IF (INFO .NE. 0) THEN ERRCD = INFO ERRMSG = 'RANKV: Computation of singular values failed. '// & 'ERRCD = INFO where INFO is returned from DSVDC.' RETURN END IF C C--count singular values less than 2**8 * eps, the machine precision C C C--compute machine precision C EPS = 1.D0 10 CONTINUE EPS = EPS / 2.D0 EPS1 = EPS + 1.D0 IF (EPS1 .GT. 1.D0) GO TO 10 EPS = 2.D0 * EPS C C--set cutoff for zero singular values C EPSLON = 256.D0 * EPS C C--count them C IZERO = 0 DO 40, I = 1, M IF (SIGMA(I) .LT. EPSLON) IZERO = IZERO + 1 40 CONTINUE C C--Set the output file C OPEN(UNIT=UNIT1,FILE=OUTFIL,ERR=9998) IF (IZERO .EQ. 0) THEN WRITE(UNIT1,111,ERR=9998) 111 FORMAT(1X,'YES') ELSE WRITE(UNIT1,112,ERR=9998) 112 FORMAT(1X,'NO') END IF C CLOSE (UNIT=UNIT1) C C--finished C RETURN C C--ERROR READING DATA C 9998 ERRCD = 100 ERRMSG = ' RANKV: Fatal Error writing to '//OUTFIL RETURN 9999 ERRCD = 200 ERRMSG = ' RANKV: Fatal Error reading from '//MATFIL RETURN END