# Cubic Splines Functions

I have this set of three data points and want the natural cubic spline functions for them:

  dat = {{-.0247500, .5}, {.3349375, -.25}, {1.101000, 0}};


I tried:

  f = SplineFit[dat, Cubic]


Using another approach and code, I get the two cubic functions (I am trying to verify the correctness) as:

-0.481347 + 0.753113 x - 0.0338047 x^2 - 0.455282 x^3

-0.506486 + 0.978281 x - 0.706073 x^2 + 0.213767 x^3


Is there anyway to see these results and the intermediate results to derive the two cubics using Mathematica (I tried looking at documentation and could not make sense of it)?

-
Are you saying there is no MMA approach to getting the spline points and we have to resort to an interpolating function? –  Amzoti Nov 5 '13 at 7:01
This is a very good question and the answer I believe is no, there is (frustratingly) no direct way to elicit the actual functional form (coefficients) produced by spline fit (or many similar functions) –  george2079 Nov 5 '13 at 16:09

f1[x_] = a1 + b1*x + c1*x^2 + d1*x^3;
f2[x_] = a2 + b2*x + c2*x^2 + d2*x^3;
s = Solve[{f1@dat[[1,1]] == dat[[1,2]],
f1@dat[[2,1]] == dat[[2,2]],
f2@dat[[2,1]] == dat[[2,2]],
f2@dat[[3,1]] == dat[[3,2]],
f1'@dat[[2,1]] == f2'@dat[[2,1]],
f1''@dat[[2,1]] == f2''@dat[[2,1]],
f1''@dat[[1,1]] == 0,
f2''@dat[[3,1]] == 0}, {a1,b1,c1,d1,a2,b2,c2,d2}]
(* {{a1 -> 0.438903, b1 -> -2.46492, c1 -> 0.221098, d1 -> 2.97775,
a2 -> 0.603324, b2 -> -3.93762, c2 -> 4.61804, d2 -> -1.39813}} *)
f[x_] = Piecewise[{{f1[x], x ≤ dat[[2,1]]}}, f2[x]] /. s;
Plot[f[x],{x,dat[[1,1]],dat[[3,1]]}, Frame->True, Axes->None, Prolog->{PointSize[.02], Point/@dat}]


EDIT, Re the comment by @george2079 -- SplineFit uses the same algebra that I used, but instead of fitting y to x, which is what I did, it fits x and y separately to their (zero-based) indices, Range[0, Length@dat-1].

( spline = SplineFit[dat, Cubic] )//InputForm


gives the following, which I have formatted, rounded, and annotated:

SplineFunction[Cubic,
{0., 2.},  (* index range *)
{{-0.02475,    0.5 },  (* x[[1]], y[[1]] *)
{ 0.3349375, -0.25},  (* x[[2]], y[[2]] *)
{ 1.101,      0   }}, (* x[[3]], y[[3]] *)
{{{-0.02475, 0.25809375, 0., 0.10159375},   (* coeffs for fitting x[[{1,2}]] *)
{ 0.5,    -1.,         0., 0.25      }},  (*   "     "     "    y[[{1,2}]] *)
{{ 0.3349375, 0.562875, 0.30478125, -0.10159375}, (*  "     "    x[[{2,3}]] *)
{-0.25,     -0.25,     0.75,       -0.25      }} (*  "     "    y[[{2,3}]] *) }]


There are two splines implicit in the above:

X[u_] = Piecewise[{{-.02475 + .25809375 u + .10159375 u^3, 0 ≤ u ≤ 1},
{.3349375 + .562875 (u-1) + .30478125 (u-1)^2 - .10159375 (u-1)^3, 1 < u ≤ 2}}];

Y[u_] = Piecewise[{{.5 - u + .25 u^3, 0 ≤ u ≤ 1},
{-.25 - .25 (u-1) + .75 (u-1)^2 - .25 (u-1)^3, 1 < u ≤ 2}}];


Note that u is shifted so that the argument of the polynomial is always in [0,1].

In the following, changing spline[u] to {X[u],Y[u]} does not change the plot:

ParametricPlot[spline[u],{u,0,2}, Frame->True, Axes->None,
AspectRatio->Automatic, Prolog->{PointSize[.02],Point/@dat}]


-
note this is a different result from SplineFit. Likely SplineFit uses some different end conditions.. –  george2079 Nov 5 '13 at 17:22
InputForm! .. +2 for that if I could.. –  george2079 Nov 6 '13 at 21:30