CFTN77,Q,T,S C$CDS ON C$FILES(0,5) C$EMA// C$MSEG 6 C directives above used for HP100 C INCLUDE 'CALPGM.INC' PROGRAM CALCAT C********************************************************************** C C Copyright (C) 1989, California Institute of Technology C All rights reserved. U. S. Government Sponsorship under C NASA Contract NAS7-918 is acknowledged. C C Herbert M. Pickett, 20 Mar 1989 C C HMP, code added for binary read of variance C HMP, constained derivatives calculated within HAMX C HMP, IDPAR is now REAL*8 C HMP, identical dipoles are summed on input C HMP, str output now will put out component dipoles C HMP, large uncertainties do not inhibit output to .CAT file C C THIS IS A GENERALIZED INTENSITY AND FREQUENCY CALCULATOR C C THE HAMILTONIAN IS ASSUMED TO BE ORGANIZED INTO BLOCKS C SUCH THAT ADJACENT SETS OF BLOCKS ARE CONNECTED BY TRANSITIONS C C*********************************************************************** INTEGER NDPAR,NTEMP,NDEGY,NBSAVX,NXDIP,LUINT,LUVAR,LUOUT,LUBIN, : LUEGY,LUSTR,LUCAT,IFLG,NDIP,IQNFMT,NPAR,NPAR1,JNXT, : INBLK,LBLK,I,ITD,IBLK,J,JBLK,NXT,NSIZD,IDGN,NBSAVM, : NQN,NBKPJ,NSAV,NDM,ISIZ,IDMY,PCARD,SETOPT,SETBLK,KBGN, : NPARTOT,K,JJ,JX,JSIZ,INTENS,IDF,JDGN,IJ,IGUP,NBSAV, : IDAMAX,NPDIP REAL*8 ZERO,QROT,THRSH,THRSH1,THRSHF,FQMAX,FQMIN,FAC,CMC,DGNF, : TMQ,STCOMP,STR,STRR,STRQ,TMC,TMQL,STARG,SCOMP,STRMN,ERR, : CALERR,EGX,TE,DGN,FRQ,ELOW,STRLG,QLOG,EGYMIN,ONE INTEGER*4 HEAPLN,ISIZB,IOFF,IXDP,JXDP,ITAG,NLINE,VAR,S,NKNT,KNT, : LDEDP,LEIG,IBUFOF,SIJ,SWK,NS C standard dimensions: PARAMETER (NDPAR=999,NTEMP=7,NDEGY=450,NBSAVX=256,HEAPLN=560000) C DOS-PC(16 bit compiler) dimensions: C PARAMETER (NDPAR=180,NTEMP=7,NDEGY=181,NBSAVX=99,HEAPLN=55000) PARAMETER (NXDIP=511) INTEGER NFILE,LINT,LVAR,LOUT,LCAT,LSTR,LEGY,LBIN PARAMETER (NFILE=7,LINT=1,LVAR=2,LOUT=3,LCAT=4,LSTR=5,LEGY=6, : LBIN=7) INTEGER*4 IDIP(0:NXDIP),IDIP1(0:1),NSBLK(NBSAVX) INTEGER IQNI(12),NBLK(NBSAVX),IXBLK(NBSAVX) CHARACTER*2 IQN(12) CHARACTER*80 TITL CHARACTER*64 FNAME(NFILE) CHARACTER*4 EXT(NFILE) INTEGER IFDIAG,RQEXIT,GETPAR,I1,I0,ITMP,IFDUMP EXTERNAL BRKQR INTEGER*2 CLEN5 PARAMETER (I0=0,I1=1,CLEN5=5) LOGICAL FIRST,PRDER,PREGY,PRFRQ,PREIG,PRSTR,PRIR,DIAG,DIAGD REAL*8 IDPAR(0:NDPAR),PAR(NDPAR),DERV(NDPAR),EGY(NDEGY), : DIP(NXDIP),TEMP(NTEMP),QSUM(NTEMP),BIGERR C EMA PAR,DERV,EGY,DIP,IDPAR,IDIP,NBLK,IXBLK REAL*8 HEAP(0:HEAPLN) COMMON HEAP SAVE DATA TEMP /300.D0,225.D0,150.D0,75.D0,37.5D0,18.75D0,9.375D0/ DATA QSUM /7*0.D0/ DATA IQN/12*' '/ C C >>>>>> BEGIN PROGRAM C C following statement is for PRIME computer to enable ^P hot key C CALL MKON$P('QUIT$',CLEN5,BRKQR) ONE=1 ZERO=1.5E-38 BIGERR=999.9999D0 LUINT=LINT LUVAR=LVAR LUOUT=LOUT LUCAT=LCAT LUSTR=LSTR LUEGY=LEGY LUBIN=LBIN EXT(LINT)='int' EXT(LVAR)='var' EXT(LOUT)='out' EXT(LCAT)='cat' EXT(LSTR)='str' EXT(LEGY)='egy' EXT(LBIN)='unf' CALL FILGET(FNAME,EXT,NFILE) CALL OPENLU(LUOUT,FNAME(LOUT),'WP') CALL OPENLU(LUINT,FNAME(LINT),'R') NLINE=0 EGYMIN=0. C C input read and echo C READ (LUINT,430,END=425) TITL CALL CHTIME(TITL(51:80)) WRITE (LUOUT,431) TITL WRITE (*,431) TITL PAR(1)=0 PAR(2)=0 PAR(3)=1000. PAR(4)=0 PAR(5)=0 PAR(6)=-100.0 PAR(7)=-100.0 PAR(8)=9999.99 PAR(9)=300. I=9 READ (LUINT,430,END=425) TITL IF(PCARD(TITL,PAR,I).EQ.0) GO TO 425 IFLG= PAR(1) ITAG= PAR(2) QROT= PAR(3) INBLK= PAR(4) LBLK= PAR(5) THRSH= PAR(6) THRSH1=PAR(7) FQMAX= PAR(8) TMQ= PAR(9) WRITE (LUOUT,450) ITAG,QROT,INBLK,LBLK,THRSH : ,THRSH1,FQMAX,TMQ FAC=4.16231E-05/QROT CMC=29979.2458D0 PRIR=IFLG.GE.1000 C initialize intensities for infrared or microwave cases IF(PRIR) THEN FAC=FAC*CMC CMC=1 IFLG=MOD(IFLG,1000) FQMIN=0.0000005 ELSE FQMAX=FQMAX*1000. FQMIN=0.00005 ENDIF C set up flags for different output options PRFRQ=IFLG.GE.100 IFLG=MOD(IFLG,100) PRSTR=IFLG.GE.10 STCOMP=1./ZERO NPDIP=1 IF(PRSTR) THEN STCOMP=0.0000001 IF(IFLG.GE.20) NPDIP=-1 IFLG=MOD(IFLG,10) ENDIF IFDUMP=IFLG/5 PRDER=IFLG.EQ.2.OR.IFLG.EQ.4 PREIG=IFLG.GE.3 PREGY=IFLG.NE.0 C read dipole moments J=1 10 IF(J.LT.NXDIP) THEN READ(LUINT,*,END=15,ERR=15) IDIP(J),DIP(J) DO 11 I=1,NDIP IF(IDIP(I).EQ.IDIP(J)) THEN DIP(I)=DIP(I)+DIP(J) WRITE(LUOUT,440) I,IDIP(I),DIP(I) GO TO 10 ENDIF 11 CONTINUE WRITE(LUOUT,440) J,IDIP(J),DIP(J) NDIP=J J=J+1 GO TO 10 ENDIF 15 IDIP(0)=NDIP IF(NPDIP.LE.0) NPDIP=NDIP C close .INT file CALL OPENLU(LUINT,FNAME(LINT),'C') CALL OPENLU(LUVAR,FNAME(LVAR),'R') CALL OPENLU(LUBIN,FNAME(LBIN),'RB') IF(LUBIN.EQ.0) LUBIN=-1 C read var file READ(LUVAR,430) TITL WRITE(LUOUT,431) '.VAR FILE TITLE :'//TITL NPARTOT=NDPAR READ(LUVAR,*) NPARTOT C read option card I=SETOPT(LUVAR,IQNFMT,ITD,TITL) ITMP=10 NQN=MOD(IQNFMT,ITMP) C read parameters and variance IF(NPARTOT.GT.NDPAR) THEN WRITE(*,*) ' Warning: number of parameters less' : , ' than requested',NPARTOT,NDPAR NPARTOT=NDPAR ENDIF VAR=HEAPLN NPAR=NPARTOT ITMP=GETPAR(LUVAR,VAR,HEAP,DERV,NPAR,IDPAR,PAR,LUBIN,LUOUT) NPARTOT=IDPAR(0) C close .VAR file CALL OPENLU(LUVAR,FNAME(LVAR),'C') CALL OPENLU(LUBIN,FNAME(LBIN),'C') C CALL PRVAR(LUOUT,NPAR,HEAP(VAR)) C set block structure NBKPJ=LBLK NDM=NDEGY KNT=SETBLK(LUOUT,IDPAR,PAR,NBKPJ,NDM) INBLK=NBKPJ*INBLK+1 LBLK =NBKPJ*(LBLK+1) C set up IFDIAG,NSAV CALL SETINT(IFDIAG,NSAV,IDIP) NBSAV=(NSAV+1)*NBKPJ DIAG=IFDIAG.NE.0.AND.NDM.GT.1 IF(IFDUMP.EQ.0) PREIG=PREIG.AND.DIAG DIAGD=DIAG.AND.(IFDUMP.EQ.0) IF (NBSAV.GE.NBSAVX) THEN WRITE(*,*) ' FATAL: NBSAV > NBSAVX',NBSAV,NBSAVX CALL OPENLU(LUOUT,FNAME(LOUT),'C') STOP ENDIF WRITE (LUOUT,460) KNT=0 C check that heap is within addressing constraints NPAR1=NPAR+1 KNT=NDM NKNT=KNT*NDM LDEDP=0 IF(DIAG) LDEDP=NKNT ISIZB=LDEDP+NPAR1*KNT IOFF=VAR SWK=IOFF-KNT S=SWK-NKNT*NPDIP NBSAVM=S/ISIZB IF(NBSAVM.LT.2) NBSAVM=2 IF(NBSAVM.GT.NBSAV) NBSAVM=NBSAV IF(NBSAVM.LT.NBSAV) NBSAV=NBSAV+1 KNT=NBSAVM*ISIZB-S IF(KNT.GT.0) THEN WRITE(*,*) ' Warning: HEALPLN should be larger by ',KNT STR=0.5*NPAR1*NBSAVM+0.5 I=NPDIP IF(DIAG) I=I+NBSAVM NDM=(SQRT(STR*STR+IOFF*I) - STR)/I KNT=NDM NKNT=KNT*NDM LDEDP=0 IF(DIAG) LDEDP=NKNT ISIZB=LDEDP+NPAR1*KNT SWK=IOFF-KNT S=SWK-NKNT*NPDIP WRITE(*,*) ' energy dimension truncated to ',NDM ENDIF K=-1 I=RQEXIT(K) C if no diagonalization use S for working space LEIG=0 IF(.NOT.DIAG) LEIG=S C set up intensity constants TMC=-1.43878 TMQ=TMC/(TMQ*CMC) C TMQL= LOG10(EXP(1))*TMQ TMQL= 0.43429448D00*TMQ THRSH1=THRSH1-10.9542425 STARG=THRSH-LOG10(FQMAX*FAC) SCOMP=-38.0 STRMN= MAX (STARG,SCOMP) STRMN=10.**STRMN IF(PREGY) CALL OPENLU(LUEGY,FNAME(LEGY),'WP') IF(PRSTR) CALL OPENLU(LUSTR,FNAME(LSTR),'WP') CALL OPENLU(LUCAT,FNAME(LCAT),'WP') DO 110 I=1,NBSAV 110 IXBLK(I)=0 C******************************************************************** C C START MAJOR LOOP OVER BLOCKS C DO 400 IBLK=INBLK,LBLK FIRST=PRFRQ J=(IBLK-1)/NBKPJ IF(IBLK-J*NBKPJ.EQ.1) THEN IF(RQEXIT(0).NE.0) GO TO 499 C ..brand old blocks IF(J.GT.NSAV) THEN JBLK=(J-NSAV)*NBKPJ DO 105 I=1,NBSAV IF(IXBLK(I).LE.JBLK) IXBLK(I)=0 105 CONTINUE ENDIF WRITE(*,495) J ENDIF IF(IXBLK(1).GT.0) THEN C move first block to unused position NXT=0 IOFF=IBUFOF(NXT,NBSAVM,IXBLK,NBLK,NSBLK,ISIZB,HEAP) IXBLK(NXT)=IXBLK(1) NBLK(NXT)=NBLK(1) NSBLK(NXT)=NSBLK(1) IXBLK(1)=0 NKNT=NSBLK(1)-1 DO 130 KNT=0,NKNT 130 HEAP(KNT+IOFF)=HEAP(KNT) ENDIF C get energy and derivatives for new block CALL GETQN(IBLK,I0,IQNI,ISIZ,IDMY) IF (ISIZ.LE.0) GO TO 400 IF (ISIZ.GT.NDM) GO TO 499 NSIZD=ISIZ IOFF=ISIZ LDEDP=0 IF(DIAG) LDEDP=IOFF*IOFF NSBLK(1)=LDEDP+NPAR1*IOFF NBLK(1)=ISIZ IXBLK(1)=IBLK CALL HAMX (IBLK,NSIZD,IDPAR,PAR,EGY,HEAP(LEIG),HEAP(LDEDP), : IFDUMP) CALL DCOPY(ISIZ,EGY,I1,HEAP(NSBLK(1)-ISIZ),I1) C print out energies and compute partition function IF(PRFRQ) WRITE (LUOUT,500) IBLK IOFF=-1 LDEDP=LDEDP-1 KBGN=1 DO 190 I=1,ISIZ IF(IFDUMP.NE.0) KBGN=I CALL GETQN (IBLK,I,IQNI,IDGN,IDMY) IF(DIAGD.AND.IDGN.GT.0) THEN C check if eigenvector is zero IF(ABS(HEAP(IOFF+I)).LT.0.01) THEN K=IDAMAX(ISIZ,HEAP(IOFF+1),I1) IF(ABS(HEAP(IOFF+K)).LT.0.01) IDGN=0 ENDIF ENDIF IF (IDGN.LE.0) GO TO 185 C .. calculate uncertainty IXDP=LDEDP+I CALL DCOPY(NPAR,HEAP(IXDP),ISIZ,DERV,I1) ERR=MIN(BIGERR,CALERR(NPAR,HEAP(VAR),DERV)/CMC) EGX=EGY(I)/CMC IF (EGYMIN.GT.EGX) THEN C adjust energy zero TE=TMC*(EGYMIN-EGX) EGYMIN=EGX DO 160 K=1,NTEMP 160 QSUM(K)=QSUM(K)*EXP(TE/TEMP(K)) ENDIF C .. accumulate partition function values TE=TMC*(EGX-EGYMIN) DGN=IDGN DO 180 K=1,NTEMP 180 QSUM(K)=QSUM(K)+DGN*EXP(TE/TEMP(K)) IF(PRFRQ)WRITE (LUOUT,510) I,IDGN,EGX,ERR,(IQNI(K),K=1,NQN) IF(PREGY)WRITE (LUEGY,510) IBLK,I,EGX,ERR,(IQNI(K),K=1,NQN) IF(PRDER)WRITE (LUEGY,596) (K,DERV(K),K=1,NPAR) IF(PREIG)WRITE (LUEGY,596) (K,HEAP(K+IOFF),K=KBGN,ISIZ) C subtract 1 from diagonal of eigenvector 185 IF(DIAGD) HEAP(IOFF+I)=HEAP(IOFF+I)-ONE 190 IOFF=IOFF+ISIZ JBLK=0 C...loop over previous blocks for intensity 195 JJ=1 JNXT=IBLK C find oldest block .GT. jblk DO 196 J=2,NBSAV JX=IXBLK(J) IF (JX.GT.JBLK.AND.JX.LT.JNXT) THEN JNXT=JX JJ=J ENDIF 196 CONTINUE JBLK=JNXT JSIZ=NBLK(JJ) IOFF=IBUFOF(JJ,NBSAVM,IXBLK,NBLK,NSBLK,ISIZB,HEAP) C C get intensity C IDGN=0 IDIP1(0)=1 SIJ=S NS=ISIZ*JSIZ DO 200 I=1,NPDIP IF(NPDIP.EQ.1) THEN IDF=INTENS(IBLK,ISIZ,JBLK,JSIZ,IDIP,DIP,HEAP(S),NSIZD) ELSE IDIP1(1)=IDIP(I) IDF=INTENS(IBLK,ISIZ,JBLK,JSIZ,IDIP1,DIP(I),HEAP(SIJ), & NSIZD) ENDIF IF(IDF.NE.0) THEN IDGN=IDF IF (DIAGD) THEN CALL SIMT(ISIZ,JSIZ,HEAP(S),HEAP,HEAP(IOFF),HEAP(SWK)) ENDIF ENDIF SIJ=SIJ+NS 200 CONTINUE IF(IDGN.LE.0) GO TO 390 DGNF=IDGN C IF(DIAGD) IOFF=IOFF+JSIZ*JSIZ IOFF=IOFF-1 IDF=-NDM IF (JBLK.EQ.IBLK) IDF=0 DO 380 I=1,ISIZ CALL GETQN (IBLK,I,IQNI,IDGN,IDMY) IF (IDGN.LE.0) GO TO 380 DGN=IDGN/DGNF DO 370 J=1,JSIZ IF ((I-J).LT.IDF) GO TO 380 CALL GETQN (JBLK,J,IQNI(7),JDGN,IDMY) IF (JDGN.LE.0) GO TO 370 IXDP=LDEDP+I JXDP=IOFF+J DO 340 K=1,NPAR DERV(K)=HEAP(IXDP)-HEAP(JXDP) IXDP=IXDP+ISIZ 340 JXDP=JXDP+JSIZ FRQ=HEAP(IXDP)-HEAP(JXDP) IF (FRQ.LT.0.) THEN FRQ=-FRQ CALL QNFMT(IQNI(7),IQNI,NQN,IQN) IGUP=JDGN ELOW=EGY(I) ELSE CALL QNFMT(IQNI,IQNI(7),NQN,IQN) IGUP=IDGN ELOW=EGY(I)-FRQ ENDIF SIJ=S+I+ISIZ*(J-1)-1 STRR=0. DO 350 IJ=1,NPDIP STR= HEAP( SIJ ) STRR = STRR + STR STRQ = STR*STR IF (STRQ.GT.STCOMP) THEN WRITE(LUSTR,530) FRQ,STR,IQNFMT,IQN,IJ ENDIF SIJ=SIJ+NS 350 CONTINUE STRR = STRR * STRR IF (FRQ.GT.FQMAX) GO TO 370 IF (FRQ.LT.FQMIN) GO TO 370 IF (STRR.LT.STRMN) GO TO 370 STR=DGN*STRR*FAC*FRQ*(1.D00-EXP(TMQ*FRQ)) STRLG= LOG10(STR+ZERO)+TMQL*ELOW IF (STRLG.LT.THRSH) GO TO 370 THRSHF=THRSH1+2.*LOG10(FRQ+ZERO) IF(ABS(THRSH-THRSHF).LT.4.) : THRSHF=LOG10 (1. +10.**(THRSH-THRSHF))+THRSHF IF (STRLG.LT.THRSHF) GO TO 370 C...calculate errors ERR=MIN(BIGERR,CALERR(NPAR,HEAP(VAR),DERV)) ELOW=ELOW/CMC IF (FIRST) WRITE (LUOUT,520) FIRST=.FALSE. IF (PRFRQ) WRITE (LUOUT,550) FRQ,ERR,STRR,STRLG,ITD,ELOW, : IGUP,ITAG,IQNFMT,IQN NLINE=NLINE+1 IF(PRIR) THEN WRITE (LUCAT,545) FRQ,ERR,STRLG,ITD,ELOW,IGUP,ITAG, : IQNFMT,IQN ELSE WRITE (LUCAT,540) FRQ,ERR,STRLG,ITD,ELOW,IGUP,ITAG, : IQNFMT,IQN ENDIF 370 CONTINUE 380 CONTINUE 390 IF(JBLK.NE.IBLK) GO TO 195 400 CONTINUE C************************************************************** C C print partition function C 499 IF(IFDUMP.NE.0) THEN WRITE(LUOUT,555) WRITE(*,555) ENDIF WRITE (LUOUT,560) NLINE,EGYMIN WRITE (*,560) NLINE,EGYMIN DO 405 I=1,NTEMP QLOG=-100. IF(QSUM(I).GT.ZERO) QLOG=LOG10(QSUM(I)) WRITE (*,570) I,TEMP(I),QSUM(I),QLOG 405 WRITE (LUOUT,570) I,TEMP(I),QSUM(I),QLOG C IF(PREGY) CALL OPENLU(LUEGY,FNAME(LEGY),'C') IF(PRSTR) CALL OPENLU(LUSTR,FNAME(LSTR),'C') CALL OPENLU(LUCAT,FNAME(LCAT),'C') 600 CALL OPENLU(LUOUT,FNAME(LOUT),'C') STOP C 425 WRITE(*,*) ' ERROR IN READING FIRST CARDS OF .INT' CALL OPENLU(LUINT,FNAME(LINT),'C') GO TO 600 C C 430 FORMAT (A) 431 FORMAT (1X,A) 440 FORMAT (I4,I10,E15.6) 450 FORMAT(' ID=',I6,' QSPINROT=',F15.4/' MIN,' :,'MAX QN=',2I4/' MIN.LOG.STR=' :,F10.3,' MIN.LOG.STR/(FRQ/300GHZ)**2=',F10.3,' MAX FREQ',F10.1, : ' GHZ, TEMP=',F10.2) 460 FORMAT (' PARAMETER ID -- VALUE -- EST.ERROR') 495 FORMAT (' STARTING QUANTUM ',I3) 500 FORMAT (' ENERGIES FOR BLOCK NUMBER',I4/' INDEX-DEGEN-ENERGY' : ,' -EST.ERROR - QUANTUM NUMBERS') 510 FORMAT (2I5,2F18.6,6I3) 520 FORMAT (' FREQUENCY-EST.ERROR.-LINE.STR. DIP**2-LGSTR.-ITD', : '-ELOW-GUP-I.D.-QNFORM-QUANTUM NUMBERS') 530 FORMAT (F15.4,E15.6,I5,1X,12A2,I5) 540 FORMAT (F13.4,2F8.4,I2,F10.4,I3,I7,I4,12A2) 545 FORMAT (F13.6,F8.6,F8.4,I2,F10.4,I3,I7,I4,12A2) 550 FORMAT (F13.4,F9.4,E13.6,F9.4,I2,F11.4,I4,I7,I4,12(1X,A2)) 555 FORMAT (' WARNING: THERE WAS NO DIAGONALIZATION') 560 FORMAT (' NUMBER OF LINES = ',I6,/, : ' TEMPERATURE - Q(SPIN-ROT.) RELATIVE TO MIN.EGY.=',F15.4) 570 FORMAT (I3,F10.3,F15.4,F10.4) 596 FORMAT(10X,I7,E13.6,I7,E13.6,I7,E13.6,I7,E13.6, : I7,E13.6,I7,E13.6) C END SUBROUTINE QNFMT(IQU,IQL,NQN,IQN) C subroutine to do quick conversion of quantum integers to characters INTEGER IQU(*),IQL(*),NQN CHARACTER*2 IQN(12),NNFMT(0:100),TQN INTEGER K,I,IX,IPCHR,INCHR PARAMETER (IPCHR=ICHAR('A')-10, INCHR=ICHAR('a')-1) SAVE NNFMT DATA NNFMT/' 0' 1 ,' 1',' 2',' 3',' 4',' 5',' 6',' 7',' 8',' 9','10','11','12' 2 ,'13','14','15','16','17','18','19','20','21','22','23','24' 3 ,'25','26','27','28','29','30','31','32','33','34','35','36' 4 ,'37','38','39','40','41','42','43','44','45','46','47','48' 5 ,'49','50','51','52','53','54','55','56','57','58','59','60' 6 ,'61','62','63','64','65','66','67','68','69','70','71','72' 7 ,'73','74','75','76','77','78','79','80','81','82','83','84' 8 ,'85','86','87','88','89','90','91','92','93','94','95','96' 9 ,'97','98','99','**'/ DO 310 K=1,NQN I=IQU(K) IF(I.LT.0) THEN I=-I IF(I.LE.9) THEN TQN=NNFMT(I) TQN(1:1)='-' ELSE IF(I.LT.270) THEN IX=I/10 I=I-10*IX TQN=NNFMT(I) TQN(1:1)=CHAR(IX+INCHR) ELSE TQN=NNFMT(100) ENDIF ELSE IF(I.LT.100) THEN TQN=NNFMT(I) ELSE IF(I.LT.360) THEN IX=I/10 I=I-IX*10 TQN=NNFMT(I) TQN(1:1)=CHAR(IX+IPCHR) ELSE TQN=NNFMT(100) ENDIF IQN(K)=TQN I=IQL(K) IF(I.LT.0) THEN I=-I IF(I.LE.9) THEN TQN=NNFMT(I) TQN(1:1)='-' ELSE IF(I.LT.270) THEN IX=I/10 I=I-10*IX TQN=NNFMT(I) TQN(1:1)=CHAR(IX+INCHR) ELSE TQN=NNFMT(100) ENDIF ELSE IF(I.LT.100) THEN TQN=NNFMT(I) ELSE IF(I.LT.360) THEN IX=I/10 I=I-IX*10 TQN=NNFMT(I) TQN(1:1)=CHAR(IX+IPCHR) ELSE TQN=NNFMT(100) ENDIF 310 IQN(K+6)=TQN RETURN END SUBROUTINE SIMT(ISIZ,JSIZ,S,T,U,WK) C subroutine to do similarity transform C S' = transpose(T+1) * S * (U+1) INTEGER ISIZ,JSIZ,I1,I,IJ,J,JT PARAMETER (I1=1) REAL*8 S(*),T(*),U(*),WK(*),DDOT C EMA S,T,U C...do transform on the left IF(ISIZ.GT.I1) THEN IJ=1 DO 270 J=1,JSIZ CALL DCOPY(ISIZ,S(IJ),I1,WK,I1) JT=1 DO 260 I=1,ISIZ S(IJ)=S(IJ)+DDOT(ISIZ,WK,I1,T(JT),I1) JT=JT+ISIZ 260 IJ=IJ+1 270 CONTINUE ENDIF C do transform on the right IF(JSIZ.GT.I1) THEN DO 230 I=1,ISIZ CALL DCOPY(JSIZ,S(I),ISIZ,WK,I1) JT=1 IJ=I DO 220 J=1,JSIZ S(IJ)=S(IJ)+DDOT(JSIZ,WK,I1,U(JT),I1) JT=JT+JSIZ 220 IJ=IJ+ISIZ 230 CONTINUE ENDIF RETURN END FUNCTION IBUFOF(IBLK,NBSAVM,IXBLK,NBLK,NSBLK,ISIZB,HEAP) INTEGER NBSAVM,IBLK,IXBLK(*),NBLK(*),LREC,LU,JBLK,N,I,IOS PARAMETER (LREC=256) INTEGER*4 IBUFOF,NSBLK(*),ISIZB,LSIZB,MAXREC,NX,LSRC,LDEST REAL*8 HEAP(0:*) SAVE LU,LSIZB,MAXREC DATA LU /-1/ IF(IBLK.LE.NBSAVM.AND.IBLK.NE.0) THEN IBUFOF=(IBLK-1)*ISIZB RETURN ENDIF JBLK=1 1 JBLK=JBLK+1 IF(IXBLK(JBLK).GT.0) GO TO 1 IF(JBLK.GT.NBSAVM) THEN C ..... need to save block 2 in JBLK IF(LU.LT.0) THEN LU=LREC CALL OPENLU(LU,'Heap Scratch','S') LSIZB=(ISIZB-1)/LREC+1 MAXREC=0 ENDIF LDEST=(JBLK-NBSAVM-1)*LSIZB LSRC=ISIZB-1 5 IF(LDEST.GT.MAXREC) THEN C .. fill in gaps with junk FIRST time MAXREC=MAXREC+1 WRITE(LU,REC=MAXREC,ERR=90,IOSTAT=IOS) : (HEAP(LSRC+I),I=1,LREC) GO TO 5 ENDIF NX=NSBLK(2) NSBLK(JBLK)=NX 2 IF(NX.GT.0) THEN LDEST=LDEST+1 WRITE(LU,REC=LDEST,ERR=90,IOSTAT=IOS) : (HEAP(LSRC+I),I=1,LREC) LSRC=LSRC+LREC NX=NX-LREC GO TO 2 ENDIF IF(MAXREC.LT.LDEST) MAXREC=LDEST IXBLK(JBLK)=IXBLK(2) NBLK(JBLK)=NBLK(2) IXBLK(2)=0 JBLK=2 ENDIF IBUFOF=(JBLK-1)*ISIZB IF(IBLK.EQ.0) THEN IBLK=JBLK ELSE C read IBLK into JBLK LDEST=IBUFOF-1 LSRC=(IBLK-NBSAVM-1)*LSIZB NX=NSBLK(IBLK) NSBLK(JBLK)=NX 10 IF(NX.GT.0) THEN IF(NX.GT.LREC) THEN N=LREC ELSE N=NX ENDIF LSRC=LSRC+1 READ(LU,REC=LSRC,ERR=91,IOSTAT=IOS) : (HEAP(LDEST+I),I=1,N) LDEST=LDEST+LREC NX=NX-LREC GO TO 10 ENDIF NBLK(JBLK)=NBLK(IBLK) IF(JBLK.NE.2) THEN IXBLK(JBLK)=IXBLK(IBLK) IXBLK(IBLK)=0 IBLK=JBLK ENDIF ENDIF RETURN 90 WRITE(*,*) ' Heap write ERROR, IOSTAT=',IOS STOP 'Aborted' 91 WRITE(*,*) ' Heap read ERROR, IOSTAT=',IOS STOP 'Aborted' END