Interpolation of a Curve

Tutorial Video

Original Data

Data to Interpolate

t=[0;10;15;20;22.5;30];
v=[0;227.04;362.78;517.35;602.97;901.67];
rocket=table(t,v);
clear t;
clear v;

Plotting Original Data

figure(1);
scatter(rocket.t,rocket.v,100,'fill');
grid('minor');
xlabel('t');
ylabel('v');

Nearest Point

Interpolation is essentially a guess of an unknown data point inferred from the known data. We are wanting to know

v(16)

The nearest time point to 16 we have is 15 so our first estimate is:

\displaystyle v(16)=v(15)

v16nearest=rocket.v(3)

v16nearest=362.78

Linear Interpolation

Here instead of referencing only the nearest data point, we reference the nearest 2 data points, we then fit a line between them and calculate the value of v on the line at t=16 and use that as our estimate for v(16):

Show Table

The nearest two time points to 16 are 15 and 20.

The equation for a straight line is:

\displaystyle v(t)={{a}_{0}}+{{a}_{1}}*t

To solve for two unknowns:

\displaystyle {{a}_{0}},{{a}_{1}}

We require 2 equations:

\displaystyle \left[ {\begin{array}{*{20}{c}} {{{v}_{1}}} \\ {{{v}_{2}}} \end{array}} \right]=\left[ {\begin{array}{*{20}{c}} 1 & {15} \\ 1 & {20} \end{array}} \right]*\left[ {\begin{array}{*{20}{c}} {{{a}_{0}}} \\ {{{a}_{1}}} \end{array}} \right]

Inputting our known values:

\displaystyle \left[ {\begin{array}{*{20}{c}} {362.78} \\ {517.35} \end{array}} \right]=\left[ {\begin{array}{*{20}{c}} 1 & {15} \\ 1 & {20} \end{array}} \right]*\left[ {\begin{array}{*{20}{c}} {{{a}_{0}}} \\ {{{a}_{1}}} \end{array}} \right]

Creating these three as matrices:

\displaystyle \text{vlin}=\left[ {\begin{array}{*{20}{c}} {362.78} \\ {517.35} \end{array}} \right]

\displaystyle \text{tlin}=\left[ {\begin{array}{*{20}{c}} 1 & {15} \\ 1 & {20} \end{array}} \right]

\displaystyle \text{alin}=\left[ {\begin{array}{*{20}{c}} {{{a}_{0}}} \\ {{{a}_{1}}} \end{array}} \right]

We can re-write the above:

\displaystyle \text{vlin}=\text{tlin}*\text{alin}

Solving for alin:

\displaystyle \text{inv(tlin)*vlin}=\text{invt(tlin)}*\text{tlin}*\text{alin}

Where:

\displaystyle \text{invt(tlin)}*\text{tlin}=\text{I}

\displaystyle \text{inv(tlin)*vlin}=\text{alin}

Rearranging:

\displaystyle \text{alin}=\text{inv(tlin)*vlin}

You can calculate this by hand on a piece of paper. In MATLAB we can also use the inverse to solve this equation however what we want to solve involves the inverse term being on the left hand side of the term we want to divide by. We can therefore use MATLAB to solve these sets of equations using the left slash:

\displaystyle \text{alin}=\text{tlin }\!\!\backslash\!\!\text{ vlin}

Once we have these, it is simply a case of inserting them into the equation at t=16:

\displaystyle v(16)={{a}_{0}}+{{a}_{1}}*16

\displaystyle \text{v16lin}=\left[ {\begin{array}{*{20}{c}} 1 & {16} \end{array}} \right]*\text{alin}

vlin=[rocket.v(3);...
rocket.v(4)];
tlin=[1,rocket.t(3);...
1,rocket.t(4)];
alin=tlin\vlin;
v16lin=[1,16]*ali

v16lin=393.694

Quadratic Interpolation

Here instead we reference the nearest 3 data points, we then fit a quadratic curve between them and calculate the value of v on the line at t=16 and use that as our estimate for v(16):

Show Table

The nearest three time points to 16 are 10, 15 and 20.

The equation for a quadratic curve is:

\displaystyle v(16)={{a}_{0}}+{{a}_{1}}*t+{{a}_{2}}*{{t}^{2}}

To solve for three unknowns:

\displaystyle {{a}_{0}},{{a}_{1}},{{a}_{2}}

We require 3 equations:

\displaystyle \left[ {\begin{array}{*{20}{c}} {{{v}_{1}}} \\ {{{v}_{2}}} \\ {{{v}_{3}}} \end{array}} \right]=\left[ {\begin{array}{*{20}{c}} 1 & {{{v}_{1}}} & {v_{1}^{2}} \\ 1 & {{{v}_{2}}} & {v_{2}^{2}} \\ 1 & {{{v}_{3}}} & {v_{3}^{2}} \end{array}} \right]*\left[ {\begin{array}{*{20}{c}} {{{a}_{0}}} \\ {{{a}_{1}}} \\ {{{a}_{2}}} \end{array}} \right]

Inputting our known values:

\displaystyle \left[ {\begin{array}{*{20}{c}} {10} \\ {15} \\ {20} \end{array}} \right]=\left[ {\begin{array}{*{20}{c}} 1 & {10} & {{{{10}}^{2}}} \\ 1 & {15} & {{{{15}}^{2}}} \\ 1 & {20} & {{{{20}}^{2}}} \end{array}} \right]*\left[ {\begin{array}{*{20}{c}} {{{a}_{0}}} \\ {{{a}_{1}}} \\ {{{a}_{2}}} \end{array}} \right]

Creating these three as matrices:

\displaystyle \text{vquad}=\left[ {\begin{array}{*{20}{c}} {10} \\ {15} \\ {20} \end{array}} \right]

\displaystyle \text{tquad}=\left[ {\begin{array}{*{20}{c}} 1 & {10} & {{{{10}}^{2}}} \\ 1 & {15} & {{{{15}}^{2}}} \\ 1 & {20} & {{{{20}}^{2}}} \end{array}} \right]

\displaystyle \text{aquad=}\left[ {\begin{array}{*{20}{c}} {{{a}_{0}}} \\ {{{a}_{1}}} \\ {{{a}_{2}}} \end{array}} \right]

We can re-write the above:

\displaystyle \text{vquad}=\text{tquad}*\text{aquad}

Solving for alin using the left slash:

\displaystyle \text{aquad}=\text{tquad }\!\!\backslash\!\!\text{ vquad}

Once we have these, it is simply a case of inserting them into the equation at t=16:

\displaystyle \text{v16quad}=\left[ {\begin{array}{*{20}{c}} 1 & {16} & {{{{16}}^{2}}} \end{array}} \right]*\text{aquad}

vquad=[rocket.v(2);...
rocket.v(3);...
rocket.v(4)];
tquad=[1,rocket.t(2),(rocket.t(2))^2;...
1,rocket.t(3),(rocket.t(3))^2;...
1,rocket.t(4),(rocket.t(4))^2];
aquad=tquad\vquad;
v16quad=[1,16,16^2]*aquad

v16quad=392.1876

Cubic Interpolation

Here instead we reference the nearest 4 data points, we then fit a cubic curve between them and calculate the value of v on the line at t=16 and use that as our estimate for v(16):

Show Table

The nearest three time points to 16 are 10, 15, 20 and 22.5.

The equation for a quadratic curve is:

\displaystyle v(16)={{a}_{0}}+{{a}_{1}}*t+{{a}_{2}}*{{t}^{2}}+{{a}_{3}}*{{t}^{3}}

To solve for four unknowns:

\displaystyle {{a}_{0}},{{a}_{1}},{{a}_{2}},{{a}_{3}}

We require 4 equations:

\displaystyle \left[ {\begin{array}{*{20}{c}} {{{v}_{1}}} \\ {{{v}_{2}}} \\ {{{v}_{3}}} \\ {{{v}_{4}}} \end{array}} \right]=\left[ {\begin{array}{*{20}{c}} 1 & {{{t}_{1}}} & {t_{1}^{2}} & {t_{1}^{3}} \\ 1 & {{{t}_{2}}} & {t_{2}^{2}} & {t_{2}^{3}} \\ 1 & {{{t}_{3}}} & {t_{3}^{2}} & {t_{3}^{3}} \\ 1 & {{{t}_{4}}} & {t_{4}^{2}} & {t_{4}^{3}} \end{array}} \right]*\left[ {\begin{array}{*{20}{c}} {{{a}_{0}}} \\ {{{a}_{1}}} \\ {{{a}_{2}}} \\ {{{a}_{3}}} \end{array}} \right]

Inputting our known values:

\displaystyle \left[ {\begin{array}{*{20}{c}} {227.04} \\ {362.78} \\ {517.35} \\ {602.97} \end{array}} \right]=\left[ {\begin{array}{*{20}{c}} 1 & {10} & {{{{10}}^{2}}} & {{{{10}}^{2}}} \\ 1 & {15} & {{{{15}}^{2}}} & {{{{15}}^{3}}} \\ 1 & {20} & {{{{20}}^{2}}} & {{{{20}}^{3}}} \\ 1 & {22.5} & {{{{22.5}}^{2}}} & {{{{22.5}}^{3}}} \end{array}} \right]*\left[ {\begin{array}{*{20}{c}} {{{a}_{0}}} \\ {{{a}_{1}}} \\ {{{a}_{2}}} \\ {{{a}_{3}}} \end{array}} \right]

Creating these three as matrices:

\displaystyle \text{vcubic}=\left[ {\begin{array}{*{20}{c}} {10} \\ {15} \\ {20} \end{array}} \right]

\displaystyle \text{tcubic}=\left[ {\begin{array}{*{20}{c}} 1 & {10} & {{{{10}}^{2}}} \\ 1 & {15} & {{{{15}}^{2}}} \\ 1 & {20} & {{{{20}}^{2}}} \end{array}} \right]

\displaystyle \text{acubic=}\left[ {\begin{array}{*{20}{c}} {{{a}_{0}}} \\ {{{a}_{1}}} \\ {{{a}_{2}}} \end{array}} \right]

We can re-write the above:

\displaystyle \text{vcubic}=\text{tcubic}*\text{acubic}

Solving for alin using the left slash:

\displaystyle \text{acubic}=\text{tcubic }\!\!\backslash\!\!\text{ vcubic}

Once we have these, it is simply a case of inserting them into the equation at t=16:

\displaystyle \text{v16cubic}=\left[ {\begin{array}{*{20}{c}} 1 & {16} & {16\hat{\ }2} & {16\hat{\ }3} \end{array}} \right]*\text{acubic}

vcubic=[rocket.v(2);...
rocket.v(3);...
rocket.v(4);...
rocket.v(5);];
tquad=[1,rocket.t(2),(rocket.t(2))^2,(rocket.t(2))^3;...
1,rocket.t(3),(rocket.t(3))^2,(rocket.t(3))^2;...
1,rocket.t(4),(rocket.t(4))^2,(rocket.t(4))^2;...
1,rocket.t(5),(rocket.t(5))^2,,(rocket.t(5))^2];
acubic=tcubic\vcubic;
v16cubic=[1,16,16^2]*acubic

v16cubic=392.1876

Interpolation of a Curve

MATLAB has a function for interpolation it has the form

[newy]=interp1(oldx,oldy,newx,'method')

First we will want to create a new table with the new t data we want to interpolate with:

newt=[0:10]'
interdata.newt=table(newt);
clearnewt;

[interdata.vnearest]=interp1(rocket.t,rocket.v,interdata.newt,'Nearest')
[interdata.vlinear]=interp1(rocket.t,rocket.v,interdata.newt,'Linear')
[interdata.vcubic]=interp1(rocket.t,rocket.v,interdata.newt,'Pchip')

This gives us the table of interpolated data as we can see the data at v(16) matches closely to that manually calculated above. The cubic interpolation (piecewise) is slightly more advanced and may smooth the function slightly accounting for the slight difference:

It is insightful to plot the interpolated data with respect to the original points.

For the plot using Nearest interpolation, we can unsurprisingly see the plot is step like.

For the linear interpolation we see straight lines between each individual points as expected:

For the cubic or piecewise interpolation we see the plot is more smooth:

 

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.