using polyval with one of the polynomials of a spline obtained with the unmkpp command, the results do not overlap! Why?

6 views (last 30 days)
I first interpolated some data using the spline command. Then I calculated the coefficients of the different cubic polynomials that make up the spline. Then I used the polyval command to check the first polynomial but the spline and polyval curves do not overlap.
What am I doing wrong?.
There is definitely something related to the various polynomials that I have not understood correctly. I thank anyone who helps me understand better. See the file script please:
%butta_sto_test
%
clear all
clc
% Data
% Time
Time=[7, 9, 11, 12]
% Temperture
Temperature=[49, 57, 71, 75]
% Data Time query
Timeq=[7:0.1:12];
% Results
% piecewise polynomial structure
pp=spline(Time, Temperature);
% Timeq data interpolation
Temperatureq=spline(Time, Temperature, Timeq);
% Calculating the coefficients of the 3 polynomials that make up the spline
[breaks, coeffs, m, n] = unmkpp(spline(Time,Temperature));
% First polinomial p1
p1=coeffs(1,:)
% First time interval corresponding to the first polynomial of the spline
Timeq1=[7:0.1:9];
% using polyval to calculate the values corresponding to Timeq1 using the polynomial p1
Temperatureq1=polyval(p1,Timeq1);
% Spline plot
figure(1)
plot(Timeq, Temperatureq, Time, Temperature, 'o', Time, Temperature, '--')
hold on
plot(Timeq1, Temperatureq1,'*')
grid on

Accepted Answer

David Goodmanson
David Goodmanson on 18 Jun 2024
Edited: David Goodmanson on 18 Jun 2024
Hello TH,.
spline polynomials are local to the secgment in question starting from x = 0, so if an interval is, for example 3 to 4.4, polyval uses 0 to 1.4. If you use
Timeq1=[7:0.1:9]; % existing line
Timeq1poly = Timeq1-Timeq1(1);
% using polyval to calculate the values corresponding to Timeq1 using the polynomial p1
Temperatureq1=polyval(p1,Timeq1poly);
then it works.
  3 Comments

Sign in to comment.

More Answers (2)

dpb
dpb on 18 Jun 2024
% Data
% Time
Time=[7, 9, 11, 12];
% Temperture
Temperature=[49, 57, 71, 75];
% Data Time query
Timeq=[7:0.1:12];
% Results
% piecewise polynomial structure
pp=spline(Time, Temperature);
% Timeq data interpolation
Temperatureq=spline(Time, Temperature, Timeq);
plot(Time,Temperature,'*')
hold on
plot(Timeq,Temperatureq)
Ts=ppval(pp,Timeq);
plot(Timeq,Ts,'x')
[bk,p]=unmkpp(pp)
bk = 1x4
7 9 11 12
<mw-icon class=""></mw-icon>
<mw-icon class=""></mw-icon>
p = 3x4
-0.3500 2.8500 -0.3000 49.0000 -0.3500 0.7500 6.9000 57.0000 -0.3500 -1.3500 5.7000 71.0000
<mw-icon class=""></mw-icon>
<mw-icon class=""></mw-icon>
T1=bk(1):0.1:bk(2);
Tp=polyval(p(1,:),T1-bk(1));
plot(T1,Tp,'+')
xlim([7 9]), ylim([45 60])
Spline coefficients are local to the break region so to evaluate by conventional polynomial functions you must subract the leading breakpoint from each section. Since this is done for you automagically by ppval, it's nonsense to not use the toolset for the job.
  3 Comments
dpb
dpb on 18 Jun 2024
I didn't say it wasn't a worthwhile exercise to figure out; only to not use the wrong toolset for the job... :)
Perhaps "nonsense" wasn't a good choice, granted.

Sign in to comment.


John D'Errico
John D'Errico on 18 Jun 2024
@David Goodmanson and @dpb and @Steven Lord have all said the polynomial segments are intended to be LOCAL with respect to the break points. I'm adding this as an answer only because I want to explain why it is done that way.
Supose I gave you two curves to interpolate using a spline, thus f(x1,y) and f(x2,y).
x1 = 0:1:10;
x2 = 1e8 + (0:1:10);
y = rand(1,11); % I dont give a hoot what values you choose for y.
spl1 = spline(x1,y);
spl2 = spline(x2,y);
The two curves should, in theory, be virtually identical. All I have done is horizontally translate the curve in x by some very large number.
Remember, these will be cubic splines. If the cubic segments for these splines were not local things, then in spl2, you would be forming a cubic polynomial where you are raising numbers on the order of 1e8 to the third power, and then adding and subtracting those values to other nubmers. Those polynomials would be unmanagable. You would expect to see massive numerical problems.
You don't want that. Even smaller shifts would cause serious problems. The solution is trivial. Just formulate each segment to be defined as a cubic polynomial, but where the LEFT end of each segment ALWAYS starts at zero, and has length given by diff(breaks). This resolves the numerical problems as much as possible.
  6 Comments
dpb
dpb on 18 Jun 2024
I was thinking specifically of both spline and interp1, but also are the options in Curve Fitting TB with fit based on the same algorithms/methods?
dpb
dpb on 19 Jun 2024
RE: your "archeology", I remember polyfit from the early 3.1 release thru R11 before started the self-employed consulting gig (coincidentally also in 2000) and bought the license from former employer and upgraded. Prior to that I had been browbeat/indoctrinated from reading GEP Box that I had built a standardized version around the existing implementation that also included normalizing shape transitions.
Interestingly enough, I hadn't ever taken the time to do the exercise @John D'Errico just illustrated to recognize that the zero shift accomplished the same thing numerically (although doesn't do anything about the shape transformation, of course). I just looked but I do not seem to have an archival copy of that code at hand although I'm sure I could dig it up...

Sign in to comment.

Categories

Find more on Spline Postprocessing in Help Center and File Exchange

Products


Release

R2015a

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!