import numpy as np
import matplotlib.pyplot as plt
import Pythonic_files as pf
%config InlineBackend.figure_format='retina'
Using Newtons Second Law $F=ma$, we get
where $b>0$, where $b$ is damping constant
Usually this, but we are getting funky $$ \frac{g}{l}\sin\theta = \frac{d^2\theta}{dt^2}$$
Change the variable to make things easy, lets just say that $v$ is the speed of the pendulum in angular
$v= \frac{d\theta}{dt}$, If we differentiate this function $ \frac{dv}{dt} = \frac{d^2\theta}{dt^2} $
We now have two differential equations, $$ \frac{d\theta}{dt}=v$$
$$ \frac{dv}{dt} = \frac{d^2\theta}{dt^2} = -\frac{b}{m}v-\frac{g}{l}sin\theta$$b=2
g=9.81
l=1
m=3
def xfunc(x,y):
return y
def yfunc(x,y):
return -b/m*y-g/l*np.sin(x)
t,x,y = pf.Ode_2D_solve(xfunc,yfunc,2,1,0.01,10)
plt.plot(x,y,c='b')
plt.plot(x[0],y[0],'x',c='g')
plt.plot(x[-1],y[-1],'o',c='r')
plt.figure(figsize=(13,8))
b=3
g=9.81
l=2
m=4
def xfunc(x,y):
return y
def yfunc(x,y):
return -b/m*y-g/l*np.sin(x)
X=np.linspace(-13,13,30)
Y=np.linspace(-2,2,9)
X,Y = np.meshgrid(X,Y)
X=np.ravel(X)
Y=np.ravel(Y)
timelength = 20
stepsize = 0.01
for count in range(len(X)):
t,x,y = pf.Ode_2D_solve(xfunc,yfunc,X[count],Y[count],stepsize,timelength)
plt.plot(x,y,c='b',alpha=0.1)
plt.show()
def xfunc(x,y,z):
return x*(1-x)-x*y
def yfunc(x,y,z):
return y*(1-y) +x*y -y*z
def zfunc(x,y,z):
return z*(1-z) +y*z
def Ode_3D_solve(xfunc,yfunc,zfunc,x0,y0,z0,dt,T):
Num = int(T//dt)
x=np.ones(Num+1)*x0
y=np.ones(Num+1)*y0
z=np.ones(Num+1)*z0
t = np.linspace(0,Num*dt,len(x))
for count in range(Num):
x[count +1] = x[count]+xfunc(x[count],y[count],z[count])*dt
y[count +1] = y[count]+yfunc(x[count],y[count],z[count])*dt
z[count +1] = z[count]+zfunc(x[count],y[count],z[count])*dt
return t,x,y,z
fig = plt.figure()
ax= plt.axes(projection = "3d")
t,x,y,z = Ode_3D_solve(xfunc,yfunc,zfunc,10,2,1,0.01,1)
ax.plot3D(x,y,z)
ax.scatter3D(x[0],y[0],z[0],c='g')
ax.scatter3D(x[-1],y[-1],z[-1],c='r')
ax.set_xlabel('Trees')
ax.set_ylabel('Moose')
ax.set_zlabel('Wolves')
ax.view_init(30,55)
print(x[-1],y[-1],z[-1])
plt.figure(figsize=(13,6))
plt.plot(t,x,c='b',label='Trees')
plt.plot(t,y,c='r',label='Moose')
plt.plot(t,z,c='g',label='Wolves')
plt.legend()
plt.ylim(0,5)
plt.show()
def xfunc(x,y,z):
return 2*x*(1-x)-x*y
def yfunc(x,y,z):
return y*(1-y) +x*y -y*z
def zfunc(x,y,z):
return z*(1-z) +y*z
fig = plt.figure()
ax= plt.axes(projection = "3d")
t,x,y,z = Ode_3D_solve(xfunc,yfunc,zfunc,10,2,1,0.01,5)
ax.plot3D(x,y,z)
ax.scatter3D(x[0],y[0],z[0],c='g')
ax.scatter3D(x[-1],y[-1],z[-1],c='r')
ax.set_xlabel('Trees')
ax.set_ylabel('Moose')
ax.set_zlabel('Wolves')
ax.view_init(30,55)
print(x[-1],y[-1],z[-1])
plt.figure(figsize=(13,6))
plt.plot(t,x,c='b',label='Trees')
plt.plot(t,y,c='r',label='Moose')
plt.plot(t,z,c='g',label='Wolves')
plt.legend()
plt.ylim(0,5)
plt.show()
s=10
r=28
b=8/3
def xfunc(x,y,z):
return s*(y-x)
def yfunc(x,y,z):
return r*x-y-x*z
def zfunc(x,y,z):
return -b*z+x*y
fig = plt.figure(figsize=(13,13))
ax= plt.axes(projection = "3d")
t,x,y,z = Ode_3D_solve(xfunc,yfunc,zfunc,1,1,1,0.01,100)
ax.plot3D(x,y,z,linewidth=0.5)
ax.view_init(30,25)
for g in range(0,90,5):
fig = plt.figure(figsize=(13,13))
ax= plt.axes(projection = "3d")
ax.plot3D(x,y,z,linewidth=0.5)
ax.view_init(30,g)
plt.show()
plt.figure(figsize=(13,5))
plt.plot(t,x)
t,x,y,z = Ode_3D_solve(xfunc,yfunc,zfunc,1,1,1,0.01,100)
t1,x1,y1,z1 = Ode_3D_solve(xfunc,yfunc,zfunc,1.1,1,1,0.01,100)
plt.figure(figsize=(13,5))
plt.plot(t,x,c='b')
plt.plot(t1,x1,c='r')
We can split a population in to different "compartments"
Lets look at the differential equations
The total population $=N$, when we normalize we had $N=S+I+R$ and then we get after normalization $1=s+i+r$
Hence our model,
$$\frac{ds}{dt} = -\beta s i $$$$\frac{di}{dt} = \beta s i -\gamma i$$import numpy as np
import matplotlib.pyplot as plt
import Pythonic_files as pf
import seaborn as sns
%config InlineBackend.figure_format='retina'
For our first example lets use $\beta = 2$ and $ \gamma = \frac{1}{4}$
beta , gamma = 2,1/4
def sfunc(s,i):
return -beta*s*i
def ifunc(s,i):
return beta*s*i-gamma*i
I0=0.001
S0=1-I0
t,s,i = pf.Ode_2D_solve(sfunc,ifunc,S0,I0,0.01,30)
plt.plot(t,s,label='Susceptible')
plt.plot(t,i,label='Infectious')
plt.plot(t,1-s-i,label='Recovered')
plt.legend()
plt.show()
plt.figure(figsize=(13,6))
beta , gamma = 0.7,1/14
def sfunc(s,i):
return -beta*s*i
def ifunc(s,i):
return beta*s*i-gamma*i
I0=0.001
S0=1-I0
dt=0.01
t,s,i = pf.Ode_2D_solve(sfunc,ifunc,S0,I0,dt,60)
plt.plot(t,s,label='Susceptible')
plt.plot(t,i,label='Infectious')
plt.plot(t,1-s-i,label='Recovered')
plt.xlabel('time in days/months/mucci')
plt.ylabel('Proportion of Population')
plt.legend()
plt.show()
plt.figure(figsize=(13,6))
plt.subplot(2,2,1)
plt.plot(s,i)
plt.xlabel('susceptible')
plt.ylabel('infectious')
plt.plot(s[0],i[0],'o',c='g')
plt.plot(s[-1],i[-1],'x',c='r')
plt.subplot(2,2,2)
plt.plot(t,i)
plt.xlabel('time')
plt.ylabel('infectious')
plt.plot(t[0],i[0],'o',c='g')
plt.plot(t[-1],i[-1],'x',c='r')
plt.subplot(2,2,3)
plt.plot(s,t)
plt.xlabel('time')
plt.ylabel('susceptible')
plt.plot(s[0],t[0],'o',c='g')
plt.plot(s[-1],t[-1],'x',c='r')
plt.show()
How do you figure out the $\beta$ from data
We know $\frac{ds}{dt} = -\beta s i $, thats the infinitesimal derivative, so an approximation is $\frac{\Delta s}{\Delta t} = -\beta si$
Or
$$ \beta= - \frac{\frac{\Delta s}{\Delta t}}{si}$$We can use for each data point a $\beta$ representation, so a collection of them will be a distribution of the $\beta$'s
Days=[]
for x in range(len(t)):
if t[x]//1-t[x-1]//1>=1:
Days.append(x)
Betas = []
for x in Days[1:]:
b = -(s[x]-s[x-1])/dt/(s[x]*i[x])
Betas.append(b)
Betas
plt.hist(Betas)
plt.show()
plt.figure(figsize=(13,6))
beta , gamma = 0.3365,1/20
def sfunc(s,i):
return -beta*s*i
def ifunc(s,i):
return beta*s*i-gamma*i
I0=0.001
S0=1-I0
dt=0.01
t,s,i = pf.Ode_2D_solve(sfunc,ifunc,S0,I0,dt,100)
plt.plot(t,s,label='Susceptible')
plt.plot(t,i,label='Infectious')
plt.plot(t,1-s-i,label='Recovered')
plt.xlabel('time in days/months/mucci')
plt.ylabel('Proportion of Population')
plt.legend()
plt.show()
Days=[]
for x in range(len(t)):
if t[x]//1-t[x-1]//1>=1:
Days.append(x)
Betas = []
for x in Days[1:]:
b = -(s[x]-s[x-1])/dt/(s[x]*i[x])
Betas.append(b)
sns.distplot(Betas)
plt.show()