set extrapolation to connect last point values to the first (extrapolated) ones with interp1

11 views (last 30 days)
Hi, I have a periodic functions with intermediate values and I want to extrapolate that in a way that the end of the extrapolation would connect to the first extrapolatin point (as it happens in a periodic functions like sine, as to say). Unfortunately using and I cannot afford it because the last extrapolated values of the following series decrease too fast and don't "link" to the first ones.
y = [788.54 827.7 846.66 960.09 136.16 53.991 36.994 904.47 882.32 1417.8 1191.6 154.91];
x = [15 45 74 105 135 166 196 227 258 288 319 349];
yy = interp1(x,y,1:365,'spline','extrap');
plot(x,y,'o',1:365,yy,'.');
I tried to look up the documentation but couldn't find nything helpful. Hope someone here does.
Thanks in advance

Accepted Answer

Matt J
Matt J on 15 Apr 2021
Edited: Matt J on 15 Apr 2021
Is this what you want?
y = [788.54 827.7 846.66 960.09 136.16 53.991 36.994 904.47 882.32 1417.8 1191.6 154.91];
x = [15 45 74 105 135 166 196 227 258 288 319 349];
xx=x(1):365;
yy = interp1([x,365],[y,y(1)],xx,'spline','extrap');
plot(x,y,'o',xx,yy,'.');hold on
plot(xlim,[yy(1),yy(end)],'k--'); hold off
  2 Comments
William Rose
William Rose on 15 Apr 2021
@gabriele fadanelli, the solution from @Matt J is nice, but incorrect, if the period is 365, as I assume it is. Matt takes the first point (x=15,y=788) and adds it at the end, but he adds it at x=365. It should be at x=380, if the data repeats every 365 days. Even if he had done it at x=380, there would be a discontinuity of the slope at the wrap-around point. You can see that his plotted solution (which is only 351 days long) has a slope discontinuity, if you wrap the end round to the start.
I thought you wanted a periodic solution with period 365 that is continuous and smooth. To do that with a spline interpolation, you need to copy more points at the front and back ends, as I noted in my post, and you need to add or subtract 365, not 350, from the x-values.

Sign in to comment.

More Answers (1)

William Rose
William Rose on 15 Apr 2021
Edited: William Rose on 15 Apr 2021
@gabriele fadanelli, Since you know your function is periodic with period 365, add a new last point to x() and to y(). The new last point is x(1)+365, y(1). Then do the interpolation.
  3 Comments
William Rose
William Rose on 15 Apr 2021
The points from x=1 to 14 in the lot above are extrapolated. Therefore they will not match the points you would get from x=366 to x=380, if you had plotted them. Two options for fixing this issue are
  1. Do the interpolation from x=15 to x=380.
  2. If you want to have a plot that goes from x=1 to 365, add a new first point, with a negative x-value. It will be a copy of your original last point, but it will be 365 days earlier. Then interpolate from 1 to 365 as before. Now all the plotted points, from 1 to 365, are truly interpolated, because your first data point is at x=-16 and the last is at x=380.
William Rose
William Rose on 15 Apr 2021
Demonstration of the idea above:
>> x = [-16 15 45 74 105 135 166 196 227 258 288 319 349 380];
>> y = [154.91 788.54 827.7 846.66 960.09 136.16 53.991 36.994,...
904.47 882.32 1417.8 1191.6 154.91, 788.54];
>> yy = interp1(x,y,1:365,'spline');
>> plot(x,y,'o',1:365,yy,'.');
Plot:
We still have a problem: points 364,365 do not lead into points 1,2, as we would like. The reason is that a cubic spline fit between two points is affected by the points farther away on each side, and we have not included those points in our input data set. Therefore, for a cubic spline interpolation that wraps around perfectly, we must add two more points on each end, again by taking copies of the known points, and adding or subtracting 365 from the x-values.
>> x = [-77 -46 -16 15 45 74 105 135 166 196 227 258 288 319 349 380 410 439];
>> y = [1417.8 1191.6 154.91 788.54 827.7 846.66 960.09 136.16 53.991 36.994,...
904.47 882.32 1417.8 1191.6 154.91 788.54 827.7 846.66];
>> yy = interp1(x,y,1:365,'spline');
>> xx1=[-16:1:1,365:1:380];
>> yy1 = interp1(x,y,xx1,'spline');
>> plot(x,y,'o',1:365,yy,'.',xx1,yy1,'x');
I interpolated some extra points to show that now the interpolation is wrapping around nicely. See plot below.

Sign in to comment.

Categories

Find more on Interpolation in Help Center and File Exchange

Community Treasure Hunt

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

Start Hunting!