Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- from scipy import *
- from pylab import *
- #class containing vector operations. Inherited by ODEsolver
- class vecMethods:
- def __init__(self):
- pass
- def vecAddition(self, a, b, *args):
- if len(a) == len(b):
- c=[i+j for i,j in zip(a,b)]
- return c
- elif len(args) > 0:
- partialVec=a[args[1]]
- c=[i+j for i,j in zip(partialVec, b)]
- return c
- else:
- raise Exception("Vector length does not match!")
- def vecUpdate(self, a, b, *args):
- if len(args) > 0:
- a[args[1]]=self.vecAddition(a[args[1]], b)
- return a
- else:
- return self.vecAddition(a, b)
- def scalarMulti(self, s, v):
- return [s*i for i in v]
- def absoluteVal(self, a, b):
- if len(a) == len(b):
- sumR=0
- for i in range(len(a)):
- sumR+=(a[i]-b[i])**2
- return sqrt(sumR)
- else:
- raise Exception("Vector length does not match!")
- #class for solving ODE:s. Inherits vecMethods.
- class ODEsolver(vecMethods):
- def __init__(self, tMax, y0, numberTimeSteps, a, b, m): #y0 is a vector (list) containing the initial values
- self.y0=y0
- self.numTimeSteps=numberTimeSteps
- self.h=2*tMax/self.numTimeSteps
- self.a=a
- self.b=b
- self.m=m
- self.t=[i*self.h for i in range(self.numTimeSteps)] #discretize time
- def solve(self, fcn, eulerOrRK): #eulerOrRK is a string determining whether to use Euler's or the Runge-Kutta method.
- y=[self.y0] #this list will contain the solution to the ODE in the form of y_n:s.
- if eulerOrRK == 'e':
- for i in range(self.numTimeSteps): #generate the y_n:s using Euler's method
- y.append(self.recursionEuler(self.t[i], y[i], fcn))
- return y
- else:
- for i in range(self.numTimeSteps): #generate the y_n:s using the R-K method
- y.append(self.recursionRK(self.t[i], y[i], fcn))
- return y
- def solveCoupled(self, fcn, eulerOrRK, extra): #send [j, n, extra] to fcn via recursion
- N=len(self.y0)
- y=[self.y0]
- if eulerOrRK == 'e':
- for i in range(self.numTimeSteps):
- tmp=[]
- for j in range(N):
- tmp.append(self.recursionEuler(self.t[i], y[i], fcn, N, j, extra))
- y.append(tmp)
- return y
- else:
- for i in range(self.numTimeSteps):
- tmp=[]
- for j in range(N):
- tmp.append(self.recursionRK(self.t[i], y[i], fcn, N, j, extra))
- y.append(tmp)
- return y
- def recursionEuler(self, tN, yN, fcn, *args):
- f=fcn(tN, yN, *args)
- hf=self.scalarMulti(self.h, f)
- return self.vecAddition(yN, hf, *args)
- def recursionRK(self, tN, yN, fcn, *args):
- f1=fcn(tN, yN, *args)
- k1=self.scalarMulti(self.h, f1)
- k2=self.scalarMulti(self.h, fcn(tN+self.m*self.h, self.vecUpdate(yN, self.scalarMulti(self.m, k1), *args), *args))
- return self.vecAddition(yN, self.vecAddition(self.scalarMulti(self.a, k1), self.scalarMulti(self.b, k2), *args), *args)
- def SIS(t, y): #f(t, x) for the sis model
- alpha=0.5
- beta=1.2
- return [-beta*y[0]*y[1]/y[2]+alpha*y[1], beta*y[0]*y[1]/y[2]-alpha*y[1], 0]
- def SIR(t, y): #f(t, x) for the sir model
- alpha=0.05
- beta=1.2
- gamma=0.02
- return [-beta*y[0]*y[1]/y[3]-gamma*y[0], beta*y[0]*y[1]/y[3]-alpha*y[1], gamma*y[0]+alpha*y[1], 0]
- def SIRwithPopulations(t, y, *args): #args should be [number of populations, current population, omegaList]
- alpha=0.06
- beta=0.88
- gamma=0
- n=args[1]
- iterationList=[i for i in range(args[0])]
- del iterationList[args[1]]
- travelTermsS=0
- travelTermsI=0
- travelTermsR=0
- for m in iterationList:
- travelTermsS+=args[2][m][n]*y[m][0]-args[2][n][m]*y[n][0]
- travelTermsI+=args[2][m][n]*y[m][1]-args[2][n][m]*y[n][1]
- travelTermsR+=args[2][m][n]*y[m][2]-args[2][n][m]*y[n][2]
- sN=-beta*y[n][0]*y[n][1]/y[n][3]-gamma*y[n][0]+travelTermsS
- iN=beta*y[n][0]*y[n][1]/y[n][3]-alpha*y[n][1]+travelTermsI
- rN=gamma*y[n][0]+alpha*y[n][1]+travelTermsR
- nN=0
- return [sN, iN, rN, nN]
- p_population=2059484
- b_population=2462637
- m_population=4963349
- bp_totalpassengers=976100
- pm_totalpassengers=2057800
- bm_totalpassengers=355700
- wbtop=(bp_totalpassengers*.5)/b_population
- wptob=(bp_totalpassengers*.5)/p_population
- wmtop=(pm_totalpassengers*.5)/m_population
- wptom=(pm_totalpassengers*.5)/p_population
- wbtom=(bm_totalpassengers*.5)/b_population
- wmtob=(bm_totalpassengers*.5)/m_population
- vecOperators=vecMethods()
- popSizes=[m_population, p_population, b_population] #the population sizes (Melbourne, Perth, Brisbane)
- omega=[[0, wmtop, wmtob], [wptom, 0,wptob],[wbtom, wbtop, 0]]
- """
- for i in range(len(popSizes)): #calculate the omega_nm
- tmp=[]
- for j in range(len(popSizes)):
- if i == j:
- tmp.append(0)
- else:
- denom=vecOperators.absoluteVal(positionVectors[i], positionVectors[j])
- tmp.append(omega0*popSizes[i]**xi*popSizes[j]**(xi-1)/(denom**(2+mu)))
- omega.append(tmp)
- """
- inst1=ODEsolver(50, [[4784607, 1, 0, 4784608],[2020138, 0, 0, 2020138], [2379724, 0, 0, 2379724]], 10000, .5, .5, 1) #initialize instance
- #Infection starts with 1 person in Melbourne
- solution2Pop=inst1.solveCoupled(SIRwithPopulations, 'r', omega)
- pop1Sus=[]
- pop1Inf=[]
- pop1Res=[]
- pop2Sus=[]
- pop2Inf=[]
- pop2Res=[]
- pop3Sus=[]
- pop3Inf=[]
- pop3Res=[]
- for i in range(len(solution2Pop)-1):
- pop1Sus.append(solution2Pop[i][0][0])
- pop1Inf.append(solution2Pop[i][0][1])
- pop1Res.append(solution2Pop[i][0][2])
- pop2Sus.append(solution2Pop[i][1][0])
- pop2Inf.append(solution2Pop[i][1][1])
- pop2Res.append(solution2Pop[i][1][2])
- pop3Sus.append(solution2Pop[i][2][0])
- pop3Inf.append(solution2Pop[i][2][1])
- pop3Res.append(solution2Pop[i][2][2])
- plt.scatter(inst1.t, pop1Sus, s=3, c="b", marker="^", label='Susceptible')
- plt.scatter(inst1.t, pop1Inf, s=3, c="r", marker="s", label='Infected')
- plt.scatter(inst1.t, pop1Res, s=3, c="g", marker="D", label='Resistant')
- plt.legend()
- plt.xlabel('Time, years')
- plt.ylabel('Number of individuals')
- plt.title('Melbourne')
- plt.show()
- plt.scatter(inst1.t, pop2Sus, s=3, c="b", marker="^", label='Susceptible')
- plt.scatter(inst1.t, pop2Inf, s=3, c="r", marker="s", label='Infected')
- plt.scatter(inst1.t, pop2Res, s=3, c="g", marker="D", label='Resistant')
- plt.legend()
- plt.xlabel('Time, years')
- plt.ylabel('Number of individuals')
- plt.title('Perth')
- plt.show()
- plt.scatter(inst1.t, pop3Sus, s=3, c="b", marker="^", label='Susceptible')
- plt.scatter(inst1.t, pop3Inf, s=3, c="r", marker="s", label='Infected')
- plt.scatter(inst1.t, pop3Res, s=3, c="g", marker="D", label='Resistant')
- plt.legend()
- plt.xlabel('Time, years')
- plt.ylabel('Number of individuals')
- plt.title('Brisbane')
- plt.show()
- print("Max people infected in Melbourne at one time" , str(max(pop1Inf)) , "at time" , str((pop1Inf.index(max(pop1Inf))/200)) , "years" )
- print("Max people infected in Perth at one time" , str(max(pop2Inf)) , "at time" , str((pop2Inf.index(max(pop2Inf))/200)) , "years" )
- print("Max people infected in Brisbane at one time" , str(max(pop3Inf)) , "at time" , str((pop3Inf.index(max(pop3Inf))/200)) , "years" )
- for i in pop2Inf:
- if i>1:
- Perth1st=((i/200)*365)
- break
- for i in pop3Inf:
- if i>1:
- Brisbane1st=((i/200)*365)
- break
- print("Time of first infection in Perth, ", str(Perth1st), "days")
- print("Time of first infection in Brisbane, ", str(Perth1st), "days")
- Enm=(3600978.8582057036-3602620.7706316267)/3 # errors at time max I
- Enb=(1786964.2076815274-1493251.606199126)/3
- Enb=(1786148.5211670923-1786964.2076815274)/3
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement