{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Asymptotic stability domains for Adams-Bashforth, Adams-Moulton methods, and BDF."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"See here for the schemes\n",
"\n",
"http://en.wikipedia.org/wiki/Linear_multistep_method\n",
"\n",
"For stability we require the roots $w$ of\n",
"$$\n",
"\\rho(w) - z \\sigma(w)\n",
"$$\n",
"to be less than one\n",
"$$\n",
"|w_i(z)| < 1\n",
"$$\n",
"We find the values of $z$ for which $|w|=1$\n",
"$$\n",
"w = e^{i \\theta}, \\qquad z = \\frac{\\rho(e^{i\\theta})}{\\sigma(e^{i\\theta})}\n",
"$$"
]
},
{
"cell_type": "code",
"execution_count": 31,
"metadata": {},
"outputs": [],
"source": [
"%matplotlib inline\n",
"%config InlineBackend.figure_format = 'svg'\n",
"import numpy as np\n",
"from matplotlib import pyplot as plt"
]
},
{
"cell_type": "code",
"execution_count": 32,
"metadata": {},
"outputs": [],
"source": [
"def AB2(theta):\n",
" w = np.exp(1j*theta)\n",
" return (w**2 - w)/(3.0*w/2.0 - 1.0/2.0)\n",
"\n",
"def AB3(theta):\n",
" w = np.exp(1j*theta)\n",
" return (w**3 - w**2)/(23.0*w**2/12.0 - 4.0*w/3.0 + 5.0/12.0)"
]
},
{
"cell_type": "code",
"execution_count": 33,
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"/Users/praveen/Applications/anaconda/lib/python3.6/site-packages/matplotlib/cbook/deprecation.py:107: MatplotlibDeprecationWarning: Adding an axes using the same arguments as a previous axes currently reuses the earlier instance. In a future version, a new instance will always be created and returned. Meanwhile, this warning can be suppressed, and the future behavior ensured, by passing a unique label to each axes instance.\n",
" warnings.warn(message, mplDeprecation, stacklevel=1)\n"
]
},
{
"data": {
"image/svg+xml": [
"\n",
"\n",
"\n",
"\n"
],
"text/plain": [
""
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"theta = np.linspace(0,2*np.pi,1000)\n",
"\n",
"z = AB2(theta)\n",
"plt.plot(np.real(z),np.imag(z))\n",
"\n",
"z = AB3(theta)\n",
"plt.plot(np.real(z),np.imag(z))\n",
"\n",
"plt.legend((\"AB2\",\"AB3\"))\n",
"plt.grid(True)\n",
"plt.xlim([-2, 1])\n",
"plt.ylim([-1, 1])\n",
"plt.axes().set_aspect('equal')"
]
},
{
"cell_type": "code",
"execution_count": 34,
"metadata": {},
"outputs": [],
"source": [
"def AM2(theta):\n",
" w = np.exp(1j*theta)\n",
" return (w**2 - w)/(5.0*w**2/12.0 + 2.0*w/3.0 - 1.0/12.0)\n",
"\n",
"def AM3(theta):\n",
" w = np.exp(1j*theta)\n",
" return (w**3 - w**2)/(3.0*w**3/8.0 + 19.0*w**2/24.0 - 5.0*w/24.0 - 1.0/24.0)"
]
},
{
"cell_type": "code",
"execution_count": 35,
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"/Users/praveen/Applications/anaconda/lib/python3.6/site-packages/matplotlib/cbook/deprecation.py:107: MatplotlibDeprecationWarning: Adding an axes using the same arguments as a previous axes currently reuses the earlier instance. In a future version, a new instance will always be created and returned. Meanwhile, this warning can be suppressed, and the future behavior ensured, by passing a unique label to each axes instance.\n",
" warnings.warn(message, mplDeprecation, stacklevel=1)\n"
]
},
{
"data": {
"image/svg+xml": [
"\n",
"\n",
"\n",
"\n"
],
"text/plain": [
""
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"z = AM2(theta)\n",
"plt.plot(np.real(z),np.imag(z))\n",
"\n",
"z = AM3(theta)\n",
"plt.plot(np.real(z),np.imag(z))\n",
"\n",
"plt.legend((\"AM2\",\"AM3\"))\n",
"plt.xlim([-7, 2])\n",
"plt.ylim([-4, 4])\n",
"plt.grid(True)\n",
"plt.axes().set_aspect('equal')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"These discs are bigger than those for the AB methods, but they are also not A-stable methods."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Stability domains for Backward Differentiation Formula"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"See here for the schemes\n",
"\n",
"http://en.wikipedia.org/wiki/Backward_differentiation_formula"
]
},
{
"cell_type": "code",
"execution_count": 36,
"metadata": {},
"outputs": [],
"source": [
"def BDF1(theta):\n",
" w = np.exp(1j*theta)\n",
" return (w-1)/w\n",
"\n",
"def BDF2(theta):\n",
" w = np.exp(1j*theta)\n",
" return (w**2 - 4.0*w/3.0 + 1.0/3.0)/(2.0*w**2/3.0)\n",
"\n",
"def BDF3(theta):\n",
" w = np.exp(1j*theta)\n",
" return (w**3 - 18.0*w**2/11.0 + 9.0*w/11.0 - 2.0/11.0)/(6.0*w**3/11.0)\n",
"\n",
"def BDF4(theta):\n",
" w = np.exp(1j*theta)\n",
" return (w**4 - 48.0*w**3/25.0 + 36.0*w**2/25.0 - 16.0*w/25.0 + 3.0/25.0)/(12.0*w**4/25.0)"
]
},
{
"cell_type": "code",
"execution_count": 37,
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"/Users/praveen/Applications/anaconda/lib/python3.6/site-packages/matplotlib/cbook/deprecation.py:107: MatplotlibDeprecationWarning: Adding an axes using the same arguments as a previous axes currently reuses the earlier instance. In a future version, a new instance will always be created and returned. Meanwhile, this warning can be suppressed, and the future behavior ensured, by passing a unique label to each axes instance.\n",
" warnings.warn(message, mplDeprecation, stacklevel=1)\n"
]
},
{
"data": {
"image/svg+xml": [
"\n",
"\n",
"\n",
"\n"
],
"text/plain": [
""
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"z = BDF1(theta)\n",
"plt.plot(np.real(z),np.imag(z))\n",
"\n",
"z = BDF2(theta)\n",
"plt.plot(np.real(z),np.imag(z))\n",
"\n",
"z = BDF3(theta)\n",
"plt.plot(np.real(z),np.imag(z))\n",
"\n",
"z = BDF4(theta)\n",
"plt.plot(np.real(z),np.imag(z))\n",
"\n",
"plt.legend((\"BDF1\",\"BDF2\",\"BDF3\",\"BDF4\"))\n",
"plt.xlim([-1, 18])\n",
"plt.ylim([-8, 8])\n",
"plt.grid(True)\n",
"plt.axes().set_aspect('equal')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The region of asymptotic stability is the exterior of these discs. Only the BDF1 and BDF2 discs are entirely to the right of the imaginary axis and these are A-stable."
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.6.6"
}
},
"nbformat": 4,
"nbformat_minor": 1
}