Application of 2nd order Runge Kutta to Populations Equations#
This notebook implements the 2nd Order Runge Kutta method for three different population intial value problems.
2nd Order Runge Kutta#
The general 2nd Order Runge Kutta method for to the first order differential equation
numerical approximates
for
and
and
To illustrate the method we will apply it to three intial value problems:
1. Linear#
Consider the linear population Differential Equation
with the initial condition,
2. Non-Linear Population Equation#
Consider the non-linear population Differential Equation
with the initial condition,
3. Non-Linear Population Equation with an oscillation#
Consider the non-linear population Differential Equation with an oscillation
with the initial condition,
Setting up Libraries#
## Library
import numpy as np
import math
import pandas as pd
%matplotlib inline
import matplotlib.pyplot as plt # side-stepping mpl backend
import matplotlib.gridspec as gridspec # subplots
import warnings
warnings.filterwarnings("ignore")
Discrete Interval#
The continuous time
Here, the interval is
This gives the 201 discrete points:
This is generalised to
The plot below shows the discrete time steps:
N=200
t_end=2020.0
t_start=2000.0
h=((t_end-t_start)/N)
t=np.arange(t_start,t_end+h/2,h)
fig = plt.figure(figsize=(10,4))
plt.plot(t,0*t,'o:',color='red')
plt.title('Illustration of discrete time points for h=%s'%(h))
plt.show()

1. Linear Population Equation#
Exact Solution#
The linear population equation
with the initial condition,
has a known exact (analytic) solution
Specific 2nd Order Runge Kutta#
To write the specific 2nd Order Runge Kutta method for the linear population equation we need
def linfun(t,w):
ftw=0.1*w
return ftw
this gives
and the difference equation
for
w=np.zeros(N+1)
w[0]=6.0
## 2nd Order Runge Kutta
for k in range (0,N):
k1=linfun(t[k],w[k])
k2=linfun(t[k]+h,w[k]+h*k1)
w[k+1]=w[k]+h/2*(k1+k2)
Plotting Results#
y=6*np.exp(0.1*(t-2000))
fig = plt.figure(figsize=(8,4))
plt.plot(t,w,'o:',color='purple',label='Runge Kutta')
plt.plot(t,y,'s:',color='black',label='Exact')
plt.legend(loc='best')
plt.show()

Table#
The table below shows the time, the Runge Kutta numerical approximation,
d = {'time t_i': t[0:10], 'Runge Kutta':w[0:10],'Exact (y)':y[0:10],'Exact Error':np.abs(np.round(y[0:10]-w[0:10],10))}
df = pd.DataFrame(data=d)
df
time t_i | Runge Kutta | Exact (y) | Exact Error | |
---|---|---|---|---|
0 | 2000.0 | 6.000000 | 6.000000 | 0.000000 |
1 | 2000.1 | 6.060300 | 6.060301 | 0.000001 |
2 | 2000.2 | 6.121206 | 6.121208 | 0.000002 |
3 | 2000.3 | 6.182724 | 6.182727 | 0.000003 |
4 | 2000.4 | 6.244861 | 6.244865 | 0.000004 |
5 | 2000.5 | 6.307621 | 6.307627 | 0.000005 |
6 | 2000.6 | 6.371013 | 6.371019 | 0.000006 |
7 | 2000.7 | 6.435042 | 6.435049 | 0.000007 |
8 | 2000.8 | 6.499714 | 6.499722 | 0.000009 |
9 | 2000.9 | 6.565036 | 6.565046 | 0.000010 |
2. Non-Linear Population Equation#
with the initial condition,
Specific 2nd Order Runge Kutta for the Non-Linear Population Equation#
To write the specific 2nd Order Runge Kutta method we need
this gives
and the difference equation
for
def nonlinfun(t,w):
ftw=0.2*w-0.01*w*w
return ftw
w=np.zeros(N+1)
w[0]=6.0
## 2nd Order Runge Kutta
for k in range (0,N):
k1=nonlinfun(t[k],w[k])
k2=nonlinfun(t[k]+h,w[k]+h*k1)
w[k+1]=w[k]+h/2*(k1+k2)
Results#
The plot below shows the Runge Kutta numerical approximation,
fig = plt.figure(figsize=(8,4))
plt.plot(t,w,'o:',color='purple',label='Runge Kutta')
plt.legend(loc='best')
plt.show()

Table#
The table below shows the time and the Runge Kutta numerical approximation,
d = {'time t_i': t[0:10],
'Runge Kutta':w[0:10]}
df = pd.DataFrame(data=d)
df
time t_i | Runge Kutta | |
---|---|---|
0 | 2000.0 | 6.000000 |
1 | 2000.1 | 6.084332 |
2 | 2000.2 | 6.169328 |
3 | 2000.3 | 6.254977 |
4 | 2000.4 | 6.341270 |
5 | 2000.5 | 6.428197 |
6 | 2000.6 | 6.515747 |
7 | 2000.7 | 6.603909 |
8 | 2000.8 | 6.692672 |
9 | 2000.9 | 6.782025 |
3. Non-Linear Population Equation with an oscilation#
with the initial condition,
Specific 2nd Order Runge Kutta for the Non-Linear Population Equation with an oscilation#
To write the specific 2nd Order Runge Kutta difference equation for the intial value problem we need
which gives
and the difference equation
for
def nonlin_oscfun(t,w):
ftw=0.2*w-0.01*w*w+np.sin(2*np.math.pi*t)
return ftw
w=np.zeros(N+1)
w[0]=6.0
## 2nd Order Runge Kutta
for k in range (0,N):
k1=nonlin_oscfun(t[k],w[k])
k2=nonlin_oscfun(t[k]+h,w[k]+h*k1)
w[k+1]=w[k]+h/2*(k1+k2)
Results#
The plot below shows the 2nd order Runge Kutta numerical approximation,
fig = plt.figure(figsize=(8,4))
plt.plot(t,w,'o:',color='purple',label='Taylor')
plt.legend(loc='best')
plt.show()

Table#
The table below shows the time and the 2nd order Runge Kutta numerical approximation,
d = {'time t_i': t[0:10],
'Runge Kutta':w[0:10]}
df = pd.DataFrame(data=d)
df
time t_i | Runge Kutta | |
---|---|---|
0 | 2000.0 | 6.000000 |
1 | 2000.1 | 6.113722 |
2 | 2000.2 | 6.276109 |
3 | 2000.3 | 6.458005 |
4 | 2000.4 | 6.623032 |
5 | 2000.5 | 6.741504 |
6 | 2000.6 | 6.801784 |
7 | 2000.7 | 6.814712 |
8 | 2000.8 | 6.809444 |
9 | 2000.9 | 6.822305 |