<a href="https://colab.research.google.com/github/john-s-butler-dit/Numerical-Analysis-Python/blob/master/Chapter%2004%20-%20Multistep%20Methods/402_Adams%20Bashforth%20Population%20Equations.ipynb" target="_parent"></a>

# 2 Step Adam Bashforth 
#### John S Butler 
john.s.butler@tudublin.ie  
[Course Notes](https://johnsbutler.netlify.com/files/Teaching/Numerical_Analysis_for_Differential_Equations.pdf)    [Github](https://github.com/john-s-butler-dit/Numerical-Analysis-Python)



This notebook implements the 2 step Adams Bashforth method for three different population intial value problems.

# Formula
The general 2 step Adams-Bashforth method for the first order differential equation
\begin{equation} y^{'} = f(t,y), \end{equation}
numerical approximates $y$ the at time point $t_i$ as $w_i$
with the  formula:
\begin{equation} w_{i+1}=w_i+\frac{h}{2}\big[3f(t_i,w_i)-f(t_{i-1},w_{i-1})\big],\end{equation}
for $i=0,...,N-1$, where 

and $h$ is the stepsize.

To illustrate the method we will apply it to three intial value problems:
## 1. Linear 
Consider the linear population Differential Equation
\begin{equation} y^{'}=0.1y, \ \ (2000 \leq t \leq 2020), \end{equation}
with the initial condition,
\begin{equation}y(2000)=6.\end{equation}

## 2. Non-Linear Population Equation 
Consider the non-linear population Differential Equation
\begin{equation} y^{'}=0.2y-0.01y^2, \ \ (2000 \leq t \leq 2020), \end{equation}
with the initial condition,
\begin{equation}y(2000)=6.\end{equation}

## 3. Non-Linear Population Equation with an oscillation 
Consider the non-linear population Differential Equation with an oscillation 
\begin{equation} y^{'}=0.2y-0.01y^2+\sin(2\pi t), \ \ (2000 \leq t \leq 2020), \end{equation}
with the initial condition,
\begin{equation}y(2000)=6.\end{equation}

#### Setting up Libraries


```python
## 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 $a\leq t \leq b $ is discretised into $N$ points seperated by a constant stepsize
\begin{equation} h=\frac{b-a}{N}.\end{equation}
Here the interval is $2000\leq t \leq 2020,$ 
\begin{equation} h=\frac{2020-2000}{200}=0.1.\end{equation}
This gives the 201 discrete points:
\begin{equation} t_0=2000, \ t_1=2000.1, \ ... t_{200}=2020. \end{equation}
This is generalised to 
\begin{equation} t_i=2000+i0.1, \ \ \ i=0,1,...,200.\end{equation}
The plot below shows the discrete time steps:


```python
### DISCRETE TIME
N=20
t_end=2020.0
t_start=2000.0
h=((t_end-t_start)/N)
t=np.arange(t_start,t_end+h/2,h)

## PLOTS TIME
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()
len(t)
```

# 1. Linear Population Equation
## Exact Solution 
The linear population equation
\begin{equation} y^{'}=0.1y, \ \ (2000 \leq t \leq 2020), \end{equation}
with the initial condition,
\begin{equation}y(2000)=6.\end{equation}
has a known exact (analytic) solution
\begin{equation} y(t)=6e^{0.1(t-2000)}. \end{equation}

## Specific 2 step Adams Bashforth
The specific 2 step Adams Bashforth for the linear population equation is:

\begin{equation}w_{i+1}=w_{i}+\frac{h}{2}\big[3(f(t_i,w_i))-f(t_{i-1},w_{i-1}))\big] \end{equation}
where
\begin{equation}f(t,y)=0.1y.\end{equation}


```python
## THIS IS THE RIGHT HANDSIDE OF THE LINEAR POPULATION DIFFERENTIAL 
## EQUATION
def linfun(t,w):
    ftw=0.1*w
    return ftw
```

this gives

\begin{equation} w_{i+1}=w_{i}+\frac{0.1}{2}\big[ 3(0.1w_i)-0.1w_{i-1} \big]\end{equation}
for $i=1,...,199$, where $w_i$ is the numerical approximation of $y$ at time $t_i$, with step size $h$ and the initial condition
\begin{equation}w_0=6.\end{equation}


```python
### INSERT METHOD HERE
w=np.zeros(N+1) # a list of 2000+1 zeros
w[0]=6 # INITIAL CONDITION
w[1]=6.06
for i in range(1,N):
    w[i+1]=w[i]+h/2*(3*linfun(t[i],w[i])-linfun(t[i-1],w[i-1]))

```

## Plotting Results


```python
## PLOTTING METHOD
y=6*np.exp(0.1*(t-2000)) # EXACT SOLUTION
fig = plt.figure(figsize=(8,4))
plt.plot(t,w,'o:',color='purple',label='Taylor')
plt.plot(t,y,'s:',color='black',label='Exact')
plt.legend(loc='best')
plt.show()
```

## Table
The table below shows the time, the numerical approximation, $w$,  the exact solution, $y$, and the exact error $|y(t_i)-w_i|$ for the linear population equation:


```python


d = {'time t_i': t, 'Adams w': w,'Exact y(t_i)':y,'Exact Error |w_i-y_i|':np.abs(y-w)}
df = pd.DataFrame(data=d)
df
```




<div>
<style scoped>
    .dataframe tbody tr th:only-of-type {
        vertical-align: middle;
    }

    .dataframe tbody tr th {
        vertical-align: top;
    }

    .dataframe thead th {
        text-align: right;
    }
</style>
<table border="1" class="dataframe">
  <thead>
    <tr style="text-align: right;">
      <th></th>
      <th>time t_i</th>
      <th>Adams w</th>
      <th>Exact y(t_i)</th>
      <th>Exact Error |w_i-y_i|</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <th>0</th>
      <td>2000.0</td>
      <td>6.000000</td>
      <td>6.000000</td>
      <td>0.000000</td>
    </tr>
    <tr>
      <th>1</th>
      <td>2001.0</td>
      <td>6.060000</td>
      <td>6.631026</td>
      <td>0.571026</td>
    </tr>
    <tr>
      <th>2</th>
      <td>2002.0</td>
      <td>6.669000</td>
      <td>7.328417</td>
      <td>0.659417</td>
    </tr>
    <tr>
      <th>3</th>
      <td>2003.0</td>
      <td>7.366350</td>
      <td>8.099153</td>
      <td>0.732803</td>
    </tr>
    <tr>
      <th>4</th>
      <td>2004.0</td>
      <td>8.137852</td>
      <td>8.950948</td>
      <td>0.813096</td>
    </tr>
    <tr>
      <th>5</th>
      <td>2005.0</td>
      <td>8.990213</td>
      <td>9.892328</td>
      <td>0.902115</td>
    </tr>
    <tr>
      <th>6</th>
      <td>2006.0</td>
      <td>9.931852</td>
      <td>10.932713</td>
      <td>1.000861</td>
    </tr>
    <tr>
      <th>7</th>
      <td>2007.0</td>
      <td>10.972119</td>
      <td>12.082516</td>
      <td>1.110397</td>
    </tr>
    <tr>
      <th>8</th>
      <td>2008.0</td>
      <td>12.121345</td>
      <td>13.353246</td>
      <td>1.231901</td>
    </tr>
    <tr>
      <th>9</th>
      <td>2009.0</td>
      <td>13.390940</td>
      <td>14.757619</td>
      <td>1.366678</td>
    </tr>
    <tr>
      <th>10</th>
      <td>2010.0</td>
      <td>14.793514</td>
      <td>16.309691</td>
      <td>1.516177</td>
    </tr>
    <tr>
      <th>11</th>
      <td>2011.0</td>
      <td>16.342994</td>
      <td>18.024996</td>
      <td>1.682002</td>
    </tr>
    <tr>
      <th>12</th>
      <td>2012.0</td>
      <td>18.054768</td>
      <td>19.920702</td>
      <td>1.865934</td>
    </tr>
    <tr>
      <th>13</th>
      <td>2013.0</td>
      <td>19.945833</td>
      <td>22.015780</td>
      <td>2.069947</td>
    </tr>
    <tr>
      <th>14</th>
      <td>2014.0</td>
      <td>22.034970</td>
      <td>24.331200</td>
      <td>2.296230</td>
    </tr>
    <tr>
      <th>15</th>
      <td>2015.0</td>
      <td>24.342924</td>
      <td>26.890134</td>
      <td>2.547211</td>
    </tr>
    <tr>
      <th>16</th>
      <td>2016.0</td>
      <td>26.892614</td>
      <td>29.718195</td>
      <td>2.825581</td>
    </tr>
    <tr>
      <th>17</th>
      <td>2017.0</td>
      <td>29.709360</td>
      <td>32.843684</td>
      <td>3.134325</td>
    </tr>
    <tr>
      <th>18</th>
      <td>2018.0</td>
      <td>32.821133</td>
      <td>36.297885</td>
      <td>3.476752</td>
    </tr>
    <tr>
      <th>19</th>
      <td>2019.0</td>
      <td>36.258835</td>
      <td>40.115367</td>
      <td>3.856532</td>
    </tr>
    <tr>
      <th>20</th>
      <td>2020.0</td>
      <td>40.056603</td>
      <td>44.334337</td>
      <td>4.277733</td>
    </tr>
  </tbody>
</table>
</div>



## 2. Non-Linear Population Equation 
\begin{equation} y^{'}=0.2y-0.01y^2, \ \ (2000 \leq t \leq 2020), \end{equation}
with the initial condition,
\begin{equation}y(2000)=6.\end{equation}
## Specific 2 step Adams-Bashforth method for the Non-Linear Population Equation
The specific Adams-Bashforth difference equation for the non-linear population equations is:

\begin{equation}w_{i+1}=w_{i}+\frac{0.1}{2}\big[3(0.2w_{i}-0.01w_{i}^2)-
(0.2w_{i-1}-0.01w_{i-1}^2)\big], \end{equation}

for $i=1,...,199$, where $w_i$ is the numerical approximation of $y$ at time $t_i$, with step size $h$ and the initial condition
\begin{equation}w_0=6.\end{equation}
To solve the 2 step method we need a value for $w_1$, here, we will use the approximation from the 2nd order Taylor method (see other notebook),
\begin{equation}w_1=6.084.\end{equation}


```python
def nonlinfun(t,w):
    ftw=0.2*w-0.01*w*w
    return ftw
```


```python
### INSERT METHOD HERE
w=np.zeros(N+1)
w[0]=6
w[1]=6.084 # FROM THE THE TAYLOR METHOD
for n in range(1,N):
    w[n+1]=w[n]+h/2*(3*nonlinfun(t[n],w[n])-nonlinfun(t[n-1],w[n-1]))
```

## Results
The plot below shows the numerical approximation, $w$ (circles) for the non-linear population equation:


```python
fig = plt.figure(figsize=(8,4))
plt.plot(t,w,'o:',color='purple',label='2 step Adams Method ')
plt.title('Non Linear Population Equation')
plt.legend(loc='best')
plt.xlabel('time (yrs)')
plt.ylabel('Population in billions')
plt.show()
```

## Table
The table below shows the time and the numerical approximation, $w$,  for the non-linear population equation:


```python

d = {'time t_i': t, 'Adams approx of non-linear w': w}
df = pd.DataFrame(data=d)
df
```




<div>
<style scoped>
    .dataframe tbody tr th:only-of-type {
        vertical-align: middle;
    }

    .dataframe tbody tr th {
        vertical-align: top;
    }

    .dataframe thead th {
        text-align: right;
    }
</style>
<table border="1" class="dataframe">
  <thead>
    <tr style="text-align: right;">
      <th></th>
      <th>time t_i</th>
      <th>Adams approx of non-linear w</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <th>0</th>
      <td>2000.0</td>
      <td>6.000000</td>
    </tr>
    <tr>
      <th>1</th>
      <td>2001.0</td>
      <td>6.084000</td>
    </tr>
    <tr>
      <th>2</th>
      <td>2002.0</td>
      <td>6.933974</td>
    </tr>
    <tr>
      <th>3</th>
      <td>2003.0</td>
      <td>7.869642</td>
    </tr>
    <tr>
      <th>4</th>
      <td>2004.0</td>
      <td>8.848568</td>
    </tr>
    <tr>
      <th>5</th>
      <td>2005.0</td>
      <td>9.851373</td>
    </tr>
    <tr>
      <th>6</th>
      <td>2006.0</td>
      <td>10.857671</td>
    </tr>
    <tr>
      <th>7</th>
      <td>2007.0</td>
      <td>11.846747</td>
    </tr>
    <tr>
      <th>8</th>
      <td>2008.0</td>
      <td>12.799268</td>
    </tr>
    <tr>
      <th>9</th>
      <td>2009.0</td>
      <td>13.698782</td>
    </tr>
    <tr>
      <th>10</th>
      <td>2010.0</td>
      <td>14.532747</td>
    </tr>
    <tr>
      <th>11</th>
      <td>2011.0</td>
      <td>15.292965</td>
    </tr>
    <tr>
      <th>12</th>
      <td>2012.0</td>
      <td>15.975461</td>
    </tr>
    <tr>
      <th>13</th>
      <td>2013.0</td>
      <td>16.579947</td>
    </tr>
    <tr>
      <th>14</th>
      <td>2014.0</td>
      <td>17.109042</td>
    </tr>
    <tr>
      <th>15</th>
      <td>2015.0</td>
      <td>17.567443</td>
    </tr>
    <tr>
      <th>16</th>
      <td>2016.0</td>
      <td>17.961143</td>
    </tr>
    <tr>
      <th>17</th>
      <td>2017.0</td>
      <td>18.296777</td>
    </tr>
    <tr>
      <th>18</th>
      <td>2018.0</td>
      <td>18.581128</td>
    </tr>
    <tr>
      <th>19</th>
      <td>2019.0</td>
      <td>18.820774</td>
    </tr>
    <tr>
      <th>20</th>
      <td>2020.0</td>
      <td>19.021862</td>
    </tr>
  </tbody>
</table>
</div>



## 3. Non-Linear Population Equation with an oscilation 
\begin{equation} y^{'}=0.2y-0.01y^2+\sin(2\pi t), \ \ (2000 \leq t \leq 2020), \end{equation}
with the initial condition,
\begin{equation}y(2000)=6.\end{equation}

## Specific 2 Step Adams Bashforth for the Non-Linear Population Equation with an oscilation
To write the specific 

\begin{equation} w_{i+1}=w_{i}+\frac{0.1}{2} \big[ 3(0.2w_{i}-0.01w_{i}^2+\sin(2\pi t_{i}))- (0.2w_{i-1}-0.01w_{i-1}^2+\sin(2\pi t_{i-1}))\big] \end{equation}
            
for $i=1,...,199$, where $w_i$ is the numerical approximation of $y$ at time $t_i$, with step size $h$ and the initial condition
\begin{equation}w_0=6.\end{equation}
 As $w_1$ is required for the method but unknown we will use the numerical solution of a one step method to approximate the value. Here, we use the 2nd order Runge Kutta approximation (see [Runge Kutta notebook](https://github.com/john-s-butler-dit/Numerical-Analysis-Python/blob/master/Chapter%2003%20-%20Runge%20Kutta/01_2nd%20Order%20Runge%20Kutta%20Population%20Equations.ipynb) )
\begin{equation}w_1=6.11.\end{equation}


```python
def nonlin_oscfun(t,w):
    ftw=0.2*w-0.01*w*w+np.sin(2*np.math.pi*t)
    return ftw
```


```python
## INSERT METHOD HERE
w=np.zeros(N+1)
w[0]=6
w[1]=6.11
for n in range(1,N):
    w[n+1]=w[n]+h/2*(3*nonlin_oscfun(t[n],w[n])
                     -nonlin_oscfun(t[n-1],w[n-1]))
```

## Results
The plot below shows the  numerical approximation, $w$ (circles) for the non-linear population equation:


```python
fig = plt.figure(figsize=(8,4))
plt.plot(t,w,'o:',color='purple',label='Adams-Bashforth')
plt.title('Population Equation with seasonal oscilation')
plt.xlabel('time (yrs)')
plt.ylabel('Population in Billions')
plt.legend(loc='best')
plt.show()
```

## Table
The table below shows the time and the numerical approximation, $w$,  for the non-linear population equation with oscilations:


```python
d = {'time t_i': t, 'Adams Approx w': w}
df = pd.DataFrame(data=d)
df
```




<div>
<style scoped>
    .dataframe tbody tr th:only-of-type {
        vertical-align: middle;
    }

    .dataframe tbody tr th {
        vertical-align: top;
    }

    .dataframe thead th {
        text-align: right;
    }
</style>
<table border="1" class="dataframe">
  <thead>
    <tr style="text-align: right;">
      <th></th>
      <th>time t_i</th>
      <th>Adams Approx w</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <th>0</th>
      <td>2000.0</td>
      <td>6.000000</td>
    </tr>
    <tr>
      <th>1</th>
      <td>2001.0</td>
      <td>6.110000</td>
    </tr>
    <tr>
      <th>2</th>
      <td>2002.0</td>
      <td>6.963018</td>
    </tr>
    <tr>
      <th>3</th>
      <td>2003.0</td>
      <td>7.900330</td>
    </tr>
    <tr>
      <th>4</th>
      <td>2004.0</td>
      <td>8.880317</td>
    </tr>
    <tr>
      <th>5</th>
      <td>2005.0</td>
      <td>9.883555</td>
    </tr>
    <tr>
      <th>6</th>
      <td>2006.0</td>
      <td>10.889620</td>
    </tr>
    <tr>
      <th>7</th>
      <td>2007.0</td>
      <td>11.877816</td>
    </tr>
    <tr>
      <th>8</th>
      <td>2008.0</td>
      <td>12.828881</td>
    </tr>
    <tr>
      <th>9</th>
      <td>2009.0</td>
      <td>13.726473</td>
    </tr>
    <tr>
      <th>10</th>
      <td>2010.0</td>
      <td>14.558187</td>
    </tr>
    <tr>
      <th>11</th>
      <td>2011.0</td>
      <td>15.315964</td>
    </tr>
    <tr>
      <th>12</th>
      <td>2012.0</td>
      <td>15.995957</td>
    </tr>
    <tr>
      <th>13</th>
      <td>2013.0</td>
      <td>16.597982</td>
    </tr>
    <tr>
      <th>14</th>
      <td>2014.0</td>
      <td>17.124739</td>
    </tr>
    <tr>
      <th>15</th>
      <td>2015.0</td>
      <td>17.580977</td>
    </tr>
    <tr>
      <th>16</th>
      <td>2016.0</td>
      <td>17.972719</td>
    </tr>
    <tr>
      <th>17</th>
      <td>2017.0</td>
      <td>18.306611</td>
    </tr>
    <tr>
      <th>18</th>
      <td>2018.0</td>
      <td>18.589435</td>
    </tr>
    <tr>
      <th>19</th>
      <td>2019.0</td>
      <td>18.827758</td>
    </tr>
    <tr>
      <th>20</th>
      <td>2020.0</td>
      <td>19.027711</td>
    </tr>
  </tbody>
</table>
</div>




```python

```

4c605fa2f4b79978e96dd0160bbcd0cc97ac11e5
ipynb
Jupyter Notebook
Chapter 04 - Multistep Methods/402_Adams Bashforth Population Equations.ipynb
jjcrofts77/Numerical-Analysis-Python
97e4b9274397f969810581ff95f4026f361a56a2
MIT
2019-09-05T21:39:12.000Z
2022-03-26T14:00:25.000Z
Chapter 04 - Multistep Methods/402_Adams Bashforth Population Equations.ipynb
jjcrofts77/Numerical-Analysis-Python
97e4b9274397f969810581ff95f4026f361a56a2
MIT
Chapter 04 - Multistep Methods/402_Adams Bashforth Population Equations.ipynb
jjcrofts77/Numerical-Analysis-Python
97e4b9274397f969810581ff95f4026f361a56a2
MIT
2021-06-17T15:34:04.000Z
2022-01-14T14:53:43.000Z
Qwen/Qwen-72B
1. YES
2. YES