{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Interpolation\n",
"\n",
"This notebook uses the [Interpolations](https://github.com/JuliaMath/Interpolations.jl) package. As an alternative, consider [Dierckx](https://github.com/kbarbary/Dierckx.jl)."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Load Packages and Extra Functions"
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"printyellow (generic function with 1 method)"
]
},
"execution_count": 1,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"using Printf, Interpolations\n",
"\n",
"include(\"jlFiles/printmat.jl\")"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [],
"source": [
"using Plots\n",
"\n",
"#pyplot(size=(600,400))\n",
"gr(size=(480,320))\n",
"default(fmt = :svg)"
]
},
{
"cell_type": "markdown",
"metadata": {
"collapsed": true
},
"source": [
"# Interpolation of y = f(x)\n",
"\n",
"Interpolations are particularly useful when *(a)* we repeatedly want to evaluate a function $f(x)$ that is time consuming to calculate but we are willing to accept approximate results, or *(b)* when we only know $f(x)$ for a grid of $x$ values but we are willing to assume that the function is pretty smooth (perhaps even linear over short intervals).\n",
"\n",
"In either case, we do something like this:\n",
"\n",
"1. Calculate $f(x)$ values for a grid of $x$. This creates a \"look-up\" table.\n",
"2. Replace the calculation of $f(x_i)$ by interpolating $f(x_i)$ from the \"look-up\" table."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Some Values to Be Interpolated\n",
"\n",
"As a simple illustration, we interpolate the sine function. (In practice, the interpolation technique is typically applied to more complicated functions.)"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [
{
"data": {
"image/svg+xml": [
"\n",
"\n"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"xGrid = range(-pi,stop=pi,length=101) #uniformly spaced grid\n",
"yGrid = sin.(xGrid) #y values at xGrid\n",
"\n",
"p1 = plot( xGrid,yGrid,\n",
" linecolor = :red,\n",
" linewidth = 2,\n",
" legend = nothing,\n",
" title = \"the sine function\",\n",
" xlabel = \"x\",\n",
" ylabel = \"y\" )\n",
"display(p1)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Interpolate\n",
"\n",
"The next cell calls on `CubicSplineInterpolation()` to create the \"look-up\" table (more precisely, create an interpolation object). \n",
"\n",
"To use a cubic spline it is required that the $x_i$ grid is *uniformly spaced* (for instance, 0.1,0.2,...). The case of a non-uniformly spaced $x$ grid is discussed later.\n",
"\n",
"The option `extrapolation_bc=...` determines how extrapolation beyond the range of the $x_i$ grid is done.\n",
"\n",
"The second cell interpolates and extrapolates $y$ at some specific $x$ values. "
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [],
"source": [
"itp = CubicSplineInterpolation(xGrid,yGrid,extrapolation_bc=Flat());"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
" x interpolated y true y\n",
" 0.250 0.247 0.247\n",
" 0.750 0.682 0.682\n",
"\n",
" x2 extrapolated y\n",
" 1.250 0.949\n",
" 3.242 0.000\n",
" 3.642 0.000\n",
"\n"
]
}
],
"source": [
"x = [0.25,0.75] #to interpolate the y values at\n",
"\n",
"y_interpolated = itp(x)\n",
"printmat([x y_interpolated sin.(x)],colNames=[\"x\",\"interpolated y\",\"true y\"],width=17)\n",
"\n",
"x2 = [1.25,pi+0.1,pi+0.5] #to extrapolate the y values at\n",
"y_extrapolated = itp(x2) #\"extrapolation\" can be done\n",
" #inside and outside the range xGrid\n",
"printmat([x2 y_extrapolated],colNames=[\"x2\",\"extrapolated y\"],width=17)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Plotting the Results"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
"outputs": [
{
"data": {
"image/svg+xml": [
"\n",
"\n"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"p1 = plot( xGrid,yGrid,\n",
" linecolor = :red,\n",
" linewidth = 2,\n",
" label = \"sine function\",\n",
" title = \"the sine function\",\n",
" xlabel = \"x\",\n",
" ylabel = \"y\" )\n",
"scatter!(x,y_interpolated,markercolor=:magenta,markersize=5,marker=:square,label=\"interpolated\")\n",
"scatter!(x2,y_extrapolated,markercolor=:blue,markersize=8,label=\"extrapolated\")\n",
"display(p1)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Interpolation of y = f(x) for General Vectors\n",
"\n",
"That is, when we cannot guarantee that the look-up table of $y_i=f(x_i)$ is from uniformly spaced $x_i$ values (the grid is irregular). This is useful, for instance, when we have empirical data on $(x_i,y_i)$.\n",
"\n",
"The approach works similar to before, except that the `CubicSplineInterpolation` must be replaced by `LinearInterpolation`."
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {},
"outputs": [
{
"data": {
"image/svg+xml": [
"\n",
"\n"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"xGrid2 = deleteat!(collect(xGrid),55:60) #non-uniformly spaced grid\n",
"yGrid2 = sin.(xGrid2)\n",
"\n",
"p1 = scatter( xGrid2,yGrid2,\n",
" linecolor = :red,\n",
" legend = false,\n",
" title = \"y\",\n",
" xlabel = \"x\" )\n",
"display(p1)"
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
" x interpolated y true y\n",
" 0.250 0.243 0.247\n",
" 0.750 0.682 0.682\n",
"\n",
" x2 extrapolated y\n",
" 1.250 0.949\n",
" 3.242 0.000\n",
" 3.642 0.000\n",
"\n"
]
}
],
"source": [
"itp2 = LinearInterpolation(xGrid2,yGrid2,extrapolation_bc=Flat())\n",
"\n",
"y_interpolated = itp2(x)\n",
"printmat([x y_interpolated sin.(x)],colNames=[\"x\",\"interpolated y\",\"true y\"],width=17)\n",
"\n",
"y_extrapolated = itp2(x2)\n",
"printmat([x2 y_extrapolated],colNames=[\"x2\",\"extrapolated y\"],width=17)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"@webio": {
"lastCommId": null,
"lastKernelId": null
},
"anaconda-cloud": {},
"kernelspec": {
"display_name": "Julia 1.6.0",
"language": "julia",
"name": "julia-1.6"
},
"language_info": {
"file_extension": ".jl",
"mimetype": "application/julia",
"name": "julia",
"version": "1.6.0"
}
},
"nbformat": 4,
"nbformat_minor": 1
}