简体   繁体   中英

Error in computing differential equations using the forward euler method in python

I doing a project to which I predict the behaviour of COVID using a SEIRDV model. I have created the differential equations and have set initial parameters. I am solving these ODE's using the forward Euler method. When I create a program to find the S, E, I, R, D, V at each day for 180 days and display it using matplotlib. I get an error which can be seen below. I believe this is due to the following operation.

I[i]/N[i] 

I am sort of new to NumPy and therefore not familiar with the errors that come up. Can anyone please inform me on how to fix this issue? In addition, I have tried plotting the data using matplotlib but the data points are all-over the place and not in the way a SEIRDV model representation should look like. Any insights on how to solve this would be greatly appreciated.

import matplotlib.pyplot as plt
import numpy as np

ndays = 180 # time length for prediction
dt = 1 # time step in days

S = np.zeros(ndays) # susceptibles
E = np.zeros(ndays) # exposed
I = np.zeros(ndays) # infective
R = np.zeros(ndays) # recovered / removed
D = np.zeros(ndays) # fatalities
V = np.zeros(ndays) # vaccinated but have had the vaccine for less than 21 days
N = np.zeros(ndays) # total population
t = np.arange(ndays)*dt

S[0] = 45167146 # initial S
E[0] = 20000 # initial E
I[0] = 3085 # initial I
R[0] = 19744004 # initial R
V[0] = 65000 # initial V
D[0] = 0 # initial D
N[0] = 60500000 # initial N

beta = (0.75) # infection rate
gam = (0.1) # recovery rate
Clamb = (0.00005) # birth rate
mu = (0.00003) # natural death rate
epsi = (0.07) # rate at which someone goes from E to I
alpha = (0.1) # rate at which Infectives die from the virus
Ldelta = (0.0006) # rate at which people get vaccinated
zeta = (0.07) # rate at which someone goes from V to R

for i in range(ndays-1):
    S[i+1] = S[i] + (Clamb - mu*S[i] - beta*S[i]*(I[i]/N[i]) - Ldelta*S[i])*dt
    E[i+1] = E[i] + (beta*S[i]*(I[i]/N[i]) + beta*V[i]*(I[i]/N[i]) - mu*E[i] - epsi*E[i])*dt
    I[i+1] = I[i] + (epsi*E[i] - gam*I[i] - mu*I[i] - alpha*I[i])*dt
    R[i+1] = R[i] + (gam*I[i] + zeta*V[i] - mu*R[i])*dt
    D[i+1] = D[i] + (alpha*I[i])*dt
    V[i+1] = V[i] + (Ldelta*S[i] - beta*V[i]*(I[i]/N[i]) - zeta*V[i])*dt

display (S)
fig = plt.figure(1) 
plt.plot(t, S, "r", lw=2, label="Susceptible")
plt.plot(t, E, "y", lw=2, label="Exposed")
plt.plot(t, I, "g", lw=2, label="Infective")
plt.plot(t, R, "p", lw=2, label="Removed")
plt.plot(t, D, "b", lw=2, label="Fatalities")
plt.plot(t, V, "o", lw=2, label="Vaccinated before immunity")
fig.legend(); plt.xlabel("Days"); plt.ylabel("Amount of people")

This is the error I get

C:\Users\jared\AppData\Local\Temp/ipykernel_18008/1585353571.py:34: RuntimeWarning: divide by zero encountered in double_scalars
  S[i+1] = S[i] + (Clamb - mu*S[i] - beta*S[i]*(I[i]/N[i]) - Ldelta*S[i])*dt
C:\Users\jared\AppData\Local\Temp/ipykernel_18008/1585353571.py:35: RuntimeWarning: divide by zero encountered in double_scalars
  E[i+1] = E[i] + (beta*S[i]*(I[i]/N[i]) + beta*V[i]*(I[i]/N[i]) - mu*E[i] - epsi*E[i])*dt
C:\Users\jared\AppData\Local\Temp/ipykernel_18008/1585353571.py:39: RuntimeWarning: divide by zero encountered in double_scalars
  V[i+1] = V[i] + (Ldelta*S[i] - beta*V[i]*(I[i]/N[i]) - zeta*V[i])*dt
C:\Users\jared\AppData\Local\Temp/ipykernel_18008/1585353571.py:34: RuntimeWarning: invalid value encountered in double_scalars
  S[i+1] = S[i] + (Clamb - mu*S[i] - beta*S[i]*(I[i]/N[i]) - Ldelta*S[i])*dt
C:\Users\jared\AppData\Local\Temp/ipykernel_18008/1585353571.py:35: RuntimeWarning: invalid value encountered in double_scalars
  E[i+1] = E[i] + (beta*S[i]*(I[i]/N[i]) + beta*V[i]*(I[i]/N[i]) - mu*E[i] - epsi*E[i])*dt
C:\Users\jared\AppData\Local\Temp/ipykernel_18008/1585353571.py:39: RuntimeWarning: invalid value encountered in double_scalars
  V[i+1] = V[i] + (Ldelta*S[i] - beta*V[i]*(I[i]/N[i]) - zeta*V[i])*dt

You never update N[i] , so it's 0 after the first step.. it should probably be set at each iteration and perhaps filled to begin with

N[i+1] = N[i] - D[i]
i=0 S[i]=45167146.0 I[i]=3085.0 N[i]=60500000.0 dt=1
i=1 S[i]=45136963.33469715 I[i]=3867.90745 N[i]=0.0 dt=1

You can embed a print() or use PDB to debug small programs very easily

% python3 -m pdb test_70976944.py
> test_70976944.py(1)<module>()
-> import matplotlib.pyplot as plt
(Pdb) b 34
Breakpoint 1 at test_70976944.py:34
(Pdb) c
> test_70976944.py(34)<module>()
-> S[i+1] = S[i] + (Clamb - mu*S[i] - beta*S[i]*(I[i]/N[i]) - Ldelta*S[i])*dt
(Pdb) print(f"i={i} S[i]={S[i]} I[i]={I[i]} N[i]={N[i]} dt={dt}")
i=0 S[i]=45167146.0 I[i]=3085.0 N[i]=60500000.0 dt=1
(Pdb) c
> test_70976944.py(34)<module>()
-> S[i+1] = S[i] + (Clamb - mu*S[i] - beta*S[i]*(I[i]/N[i]) - Ldelta*S[i])*dt
(Pdb) print(f"i={i} S[i]={S[i]} I[i]={I[i]} N[i]={N[i]} dt={dt}")
i=1 S[i]=45136963.33469715 I[i]=3867.90745 N[i]=0.0 dt=1

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM