# Interpolation¶

In [2]:
import numpy as np                        # numerics
import matplotlib.pyplot as plt           # plotting
%matplotlib inline


## Key concept¶

• Given two arrays of $x_g$, $y_g$ data points (e.g., a plot of points).
• You want to estimate the $x_w$, $y_w$ value of an intermediate data point.
• You know the value of $x_w$ (cause it's where you want the point).
• You need to interpolate to find the corresponding $y_w$.
In [3]:
#### Just plotting some data to visualize
x_given = np.array([0,1,2,3,4,5,6,7,8,9,10])
y_given = np.cos(x_given**2.0/8.0) + 1

plt.rc('font', size=16)
plt.plot(x_given, y_given, 'o:')
plt.plot([2.5,2.5],[-0.1,1.6], '--', color='gray')
plt.plot([-0.1,2.5],[1.6,1.6], '--', color='gray')
plt.plot([2.5], [1.6], '*', markersize=20)
plt.xlim([-0.1,11]); plt.ylim([-0.1,2.2])
plt.xlabel('x');     plt.ylabel('y')
plt.text(2.6,0, r"$x_w$", fontsize=16);  plt.text(0,1.7, r"$y_w$", fontsize=16);


### Question¶

• How to get intermediate values, that is, values between those that are part of the given data?

• Fit a curve to the data, then evaluate from that curve.
• Take the closest data point
• Linear interpolation
• Higher order interpolation
• (Others?)

### Question¶

• How does curve fitting differ from interpolation?

• Normally, interpolation is done locally, between a few (often two) bounding points.
• Curve fitting involves making a best fit curve everywhere
• Usually, a best-fit curve will not pass through all data points.
• Useful when there is noise and we want the underlying curve, or a model equation for the data.
• Interpolation normally considers the points themselves, not a single curve through everything.
• Even with noisy data, we might want to interpolate an intermediate point.
• If you want an intermediate point to some given data, use interpolation.
• If you want to fit a model though some scattered data, and then evaluate the model, use curve fitting.

### Examples?¶

• Think of some examples where you might use this.

## Linear Interpolation Exercise¶

• Given the xg and yg data below.
• Write a function called Linterp that takes the following arguments:
• xg an array of given x data
• yg an array of given y data corresponding to xg
• xw the value of x we want to interpolate at
• The function returns yw corresponding to xw
• Assume xg are uniformly spaced, and ascending.

Questions

• What is the linear interpolation formula at a given location?
• We write the equation for a line based on two points, then evaluate the line at the intermediate point:
• equate slopes, then solve for y_w: $$\frac{y_w-y_0}{x_w-x_0} = \frac{y_1-y_0}{x_1-x_0},$$ $$y_w = y_0 + (x_w-x_0)\frac{y_1-y_0}{x_1-x_0}.$$
In [4]:
#-------------------- Set some "given" x, y data, (normally given to us)

xg = np.array([0,1,2,3,4,5,6,7,8,9,10.])   # given x data
yg = np.cos(xg**2.0/8.0)+1                 # given y data
print("xg = "+np.array2string(xg, formatter={'float_kind':lambda x: f"{x:4.2f}"}))
print("yg = "+np.array2string(yg, formatter={'float_kind':lambda x: f"{x:4.2f}"}))

#-------------------- interpolate to xw=2.5

xw = 2.5

xg = [0.00 1.00 2.00 3.00 4.00 5.00 6.00 7.00 8.00 9.00 10.00]
yg = [2.00 1.99 1.88 1.43 0.58 0.00 0.79 1.99 0.85 0.24 2.00]


### New library¶

In [4]:
from scipy.interpolate import interp1d

• interp1d takes the given x array and the given y array as arguments.
• Returns a function.
• Call that function wherever you want to interpolate to.
In [14]:
xg = np.array([0,1,2,3,4,5,6,7,8,9,10])   # given x data
yg = np.cos(xg**2.0/8.0)+1           # given y data

#---------------

f_interp = interp1d(xg, yg)

#---------------

xw = 2.5
yw = f_interp(xw)

print(yw)

1.6543795393445195


### Exercise¶

• Take the previous xg, yg data and plot the data as points.
• Plot 1000 points of the underlying function used to get xg and yg, called xx
• Also, plot values of a linear interpolant at the same 1000 points.
In [5]:
xg = np.array([0,1,2,3,4,5,6,7,8,9,10]) # given x data
yg = np.cos(xg**2.0/8.0)+1              # given y data


#### Try replacing¶

f_interp = interp1d(xg, yg)

#### with this¶

f_interp = interp1d(xg, yg, kind='cubic')

• This uses a cubic spline interpolant instead of a linear interpolant.
• That is, we use cubic functions between points that match up smoothly at interfaces.

Try this:

• Interpolate an x value that is outside of the bounds of the given xg data.
• What happens?

### Extrapolation¶

• As listed above, you will get an error if you try to call f_interp with an x value that is outside of the upper and lower bounds of the original xg array.
• This can be avoided using the fill_value='extrapolate' argument, like so:
• f_interp = interp1d(xg, yg, fill_value='extrapolate'

## Summary¶

1. Import library
2. You have some data from somewhere, xg, yg
3. Get ther interpolant function fi=interp1d(xg, yg)
4. Set desired xw intermediate points to interpolate at (can be an array).
5. Perform the interpolation to yw=fi(xw)
In [6]:
from scipy.interpolate import interp1d

xg = np.array([1,2,3,4,5])             # some data you have
yg = np.array([11, 2.2, 3.3, -88, 9])

fi = interp1d(xg,yg)
xw = 2.5
yw = fi(xw)


## Question¶

• What if you have given xg and yg arrays and you know the yw and want to interpolate to the corresponding xw?
In [ ]: