Group Abstract Group Abstract

Message Boards Message Boards

0
|
56 Views
|
6 Replies
|
2 Total Likes
View groups...
Share
Share this post:

Splines without the Splines package

Posted 2 days ago

Hi there.
I want to compute Splines for a data set. Up to now I did this with the Splines package and the corresponding command SplineFit[...]. But it should also work with the command Interpolation[..], but I was not able to manage... Any idea?

6 Replies

You are right, the two interpolations are different:

sp1 = SplineFit[data, Cubic];
sp3 = Interpolation[data, Method -> "Spline", InterpolationOrder -> 3];
plot2 = ParametricPlot[sp1[t], {t, 0, 4}];
plot3 = ParametricPlot[{t, sp3[t]}, {t, -2, 2}, PlotStyle -> Red];
Show[plot2, plot3]

The documentation on SplineFit states that the second derivative of the spline at the endpoints is set to 0. Interpolation does not do that, apparently. Sorry I can't help you more on this.

POSTED BY: Gianluca Gorni

SplineFit gives a SplineFunction object, which spits out couples {x,y}, while Interpolation gives y values only. Try this:

sp2 = Interpolation[data, Method -> "Spline"];
plot3 = ParametricPlot[{t, sp2[t]}, {t, -2, 2}];
Show[plot1, plot3]
POSTED BY: Gianluca Gorni
Posted 7 hours ago

Some time back, I implemented a function that duplicated the functionality of the old Splines` package, but returned an InterpolatingFunction[] instead (original here ):

splinefit[dat_?MatrixQ] :=
          Module[{n = Length[dat], del = Differences[dat]},
                 del = LinearSolve[SparseArray[
                       {Band[{2, 1}] -> 1, 
                        Band[{1, 1}] -> ArrayPad[ConstantArray[4, n - 2], 1, 2], 
                        Band[{1, 2}] -> 1}], 
                       ListCorrelate[{{3}, {3}}, del, {-{1, 1}, {1, 1}}, {0}]];
                 BSplineFunction[#1, SplineDegree -> 3, SplineKnots -> #2] & @@
                 {Join[{dat[[1]]},
                       Riffle[Most[dat] + Most[del]/3, Rest[dat] - Rest[del]/3],
                       {dat[[-1]]}],
                  ArrayPad[Riffle[#, #] &[Range[0, n - 1]], 2, "Fixed"]}]

For your data, then:

data = {{-2, 1}, {-1, 4}, {0, 5}, {1, 3}, {2, 2}};
fun1 = splinefit[data];
ParametricPlot[fun1[t], {t, 0, 4}, AspectRatio -> 1/GoldenRatio]

However, I do not recommend using this old functionality. Instead, you can use a "not-a-knot" spline interpolation like what Michael describes. Here's a compact implementation (original here):

notAKnotSpline[pts_?MatrixQ] := Module[{dy, h, p1, p2, sl, s1, s2, tr},
    h = Differences[pts[[All, 1]]]; dy = Differences[pts[[All, 2]]]/h;
    s1 = Total[Take[h, 2]]; s2 = Total[Take[h, -2]];
    p1 = ({3, 2}.Take[h, 2] h[[2]] dy[[1]] + h[[1]]^2 dy[[2]])/s1;
    p2 = (h[[-1]]^2 dy[[-2]] + {2, 3}.Take[h, -2] h[[-2]] dy[[-1]])/s2;
    tr = SparseArray[{Band[{2, 1}] -> Append[Rest[h], s2], 
                      Band[{1, 1}] -> Join[{h[[2]]}, ListCorrelate[{2, 2}, h], {h[[-2]]}], 
                      Band[{1, 2}] -> Prepend[Most[h], s1]}];
    sl = LinearSolve[tr, Join[{p1}, 
                              3 Total[Partition[dy, 2, 1]
                                      Reverse[Partition[h, 2, 1], 2], {2}],
                              {p2}]];
    Interpolation[MapThread[{{#1[[1]]}, #1[[2]], #2} &, {pts, sl}], 
                  InterpolationOrder -> 3, Method -> "Hermite"]]

To try it out:

spl = notAKnotSpline[data];
Plot[spl[x], {x, -2, 2}, Epilog -> {Directive[AbsolutePointSize[6], ColorData[116, 4]], Point[data]}]
POSTED BY: J. M.

Maybe this will help:

Cubic spline conditions in general leave two degrees of freedom. The spline conditions themselves require the function to pass through the data and to have continuous derivatives up to order two at the interior data points. There are many ways to complete a spline by adding two more conditions. It appears that Interpolation[] makes a "natural" spline, and the "Splines`" package makes a "not-a-knot" spline.

POSTED BY: Michael Rogers

Thanks anyway!!

That's clear. But the point is that with the command Interpolation[...] one obtains the function value 4.203... whereas the command SplineFit[...] gives the function value 4.127..., both at the point x=0.5

Reply to this discussion
Community posts can be styled and formatted using the Markdown syntax.
Reply Preview
Attachments
Remove
or Discard