1

I am trying to implement a clamped cubic spline with a zero slope (flat extrapolation) at the boundary knots, but I am unable to obtain the desired results.

For instance setting:

x = [3 4 7 9];
y = [2 1 2 0.5];

I can use the CSAPE function to obtain the piecewise polynomial

pp = csape(x,y,'variational');

Next, evaluating the pp in the range [0-10] yields,

xx = 0:0.1:10;
yy =ppval(pp,xx);
plot(xx,yy) 

enter image description here

However, this method do not achieve a flat extrapolation outside the [3-9] range (i.e for x<3 all values for y should be 2, and for x>9 all values for y should be 0.5)

Is there any way to achieve the desired result?

Edit: Continuity at the boundary knot should be preserved

sets
  • 169
  • 7

1 Answers1

2

I don't think there's any need to use csape, you can just use spline. From the documentation for spline:

If Y is a vector that contains two more values than x has entries, the first and last value in Y are used as the endslopes for the cubic spline.

Also, spline allows you to obtain the interpolated yy values directly, so:

x = [3 4 7 9];
y = [2 1 2 0.5];
xx = 0:0.1:10;
yy = spline(x,[0 y 0], xx);
plot(xx,yy)

This gives me the plot below.

Spline Plot

Looking at this, the slope is zero at the boundaries (x=3 and x=9), which is what we are asking of a 'clamped' spline with zero gradient at the boundaries. If you wish to have zero gradient beyond the boundaries, I would recommend just doing the following:

yy(xx<x(1)) = y(1);
yy(xx>x(length(x))) = y(length(y));

Giving:

enter image description here

Edit

This gives a continuous y function at the end-knots, but y' is not smooth at the end-knots. If you would like y' to be smooth you could pad your input arrays and use this as the input to your spline function. This would give you some oscillations as shown below, though, which may or may not be what you want.

% Spline on padded input arrays
x = [0 1 2 3 4 7 9 10 11 12];
y = [2 2 2 2 1 2 0.5 0.5 0.5 0.5];
yy = spline(x,y, xx);

enter image description here

RPM
  • 1,704
  • 12
  • 15
  • Thank you RPM. This is very useful. Indeed what I need is to have a zero gradient beyond the boundaries, as in the second plot. Just one additional question: do the substitution of the values outside the boundaries by y(1) and y(length(y)) preserve the continuity of the function at the boundary knots? – sets Mar 04 '16 at 12:58
  • Well, just looking at the plot, you can see `y` is continuous, but I don't think `y'` will be smooth. If you do want these to be smooth, you could pad your arrays (add `2`s to the beginning and `0.5`s to the end in your case), but you will then find that the curve oscillates instead of being flat. I'll make an edit to this effect. – RPM Mar 07 '16 at 09:50