C C This is the FORTRAN version of program 2.5 from page 39 of C "Modeling Infectious Disease in humans and animals" C by Keeling & Rohani. C C It is the simple SIR epidemic without births or deaths. C C This code is written to be simple, transparent and readily compiled. C Far more elegant and efficient code can be written. C C This code can be compiled using the intel fortran compiler: C ifort -Vaxlib -o Program_2_5 Program_2_5.f C C Main program starts here. program main REAL beta REAL gamma REAL S,I REAL I0 REAL MaxTime REAL EVERY, step, t INTEGER GivesName CHARACTER*2000 str, FileName COMMON /parameters/ beta, gamma COMMON /variables/ S, I GivesName=iargc() if (GivesName.eq.0) then beta=1.4247 gamma=0.14286 S0=1 - 1.0d-6 I0=1.0d-6 MaxTime=70 else c c READ IN ALL THE VARIABLES c call getarg(1,FileName) open(1,file=FileName,STATUS='OLD',ACCESS='SEQUENTIAL') read(1,*) str read(1,*) beta read(1,*) str read(1,*) gamma read(1,*) str read(1,*) I0 read(1,*) str read(1,*) MaxTime close(1) endif C C Check all variables are OK & set up intitial conditions */ C if ( I0.le.0) then write(*,*) "ERROR: Initial level of infecteds (",I0,") is . less than or equal to zero." STOP endif if ( I0.gt.1) then write(*,*) "ERROR: Initial level of infecteds (",I0,") is . greater than one." STOP endif if ( beta.le.0) then write(*,*) "ERROR: Transmission rate beta (",beta,") is . less than or equal to zero." STOP endif if ( gamma.le.0) then write(*,*) "ERROR: Recovery rate gamma (",gamma,") is . less than or equal to zero." STOP endif if ( MaxTime.le.0) then write(*,*) "ERROR: Maximum run time (",MaxTime,") is . less than or equal to zero." STOP endif if (beta.lt.gamma) then write(*,*) "WARNING: Basic reproductive ratio (R_0=", . beta/gamma,") is less than one." endif S=1-I0 I=I0 C C Find a suitable time-scale for outputs C step=0.01/((beta+gamma)) Every=1.0/((beta+gamma)) if (Every.gt.1) then Every=10.0**INT(log10(Every)) else Every=10.0**INT(log10(Every)-1) endif DO WHILE (MaxTime/Every.gt.10000) Every=Every*10.0 ENDDO open(1,recl=3000,file='Output',ACCESS='SEQUENTIAL') C for F77 use C open(1,file='Output_Risk',ACCESS='SEQUENTIAL') C C C The main iteration routine C t=0 DO WHILE (t.lt.MaxTime) CALL Runge_Kutta(step) t=t+step C If time has moved on sufficiently, output the current data if( INT(t/Every).gt.INT((t-step)/Every) ) then write(1,*) t,S,I endif ENDDO END SUBROUTINE Runge_Kutta(step) REAL InitialPop(2), tmpPop(2) REAL dPop1(2), dPop2(2), dPop3(2), dPop4(2) REAL S,I, step COMMON /variables/ S, I C C Integrates the equations one step, using Runge-Kutta 4 C Note: we work with arrays rather than variables to make the C coding easier C InitialPop(1)=S InitialPop(2)=I CALL Diff(InitialPop,dPop1) do k=1,2 tmpPop(k)=InitialPop(k)+step*dPop1(k)/2.0 ENDDO CALL Diff(tmpPop,dPop2) do k=1,2 tmpPop(k)=InitialPop(k)+step*dPop2(k)/2.0 ENDDO CALL Diff(tmpPop,dPop3) do k=1,2 tmpPop(k)=InitialPop(k)+step*dPop3(k) ENDDO CALL Diff(tmpPop,dPop4) do k=1,2 tmpPop(k)=InitialPop(k)+step*(dPop1(k)/6 + dPop2(k)/3 + . dPop3(k)/3 + dPop4(k)/6) ENDDO S=tmpPop(1) I=tmpPop(2) RETURN END C The Main Differential Equations. SUBROUTINE Diff(Pop, dPop) REAL Pop(2), dPop(2) REAL beta REAL gamma COMMON /parameters/ beta, gamma C Set up temporary variables to make the equations look neater REAL tmpS, tmpI tmpS=Pop(1) tmpI=Pop(2) C C The differential equations C C dS/dt = dPop(1) = gamma*tmpI - beta*tmpS*tmpI C dI/dt = dPop(2) = beta*tmpS*tmpI - gamma*tmpI RETURN END