# Derivative of a spline approximation

To approximate an experimental data function $f(t)$ with $t \in (t_{min},t_{max})$ I used a cubic spline $s(p)=(t(p),f(p))$ with the parameter $p \in (0,1)$ and $p = t/(t_{max}-t_{min})$ by using the command BSplineFunction. To take the time derivative I use the chain rule $s'=ds/dt = ds/dp \cdot dp/dt = s'(p)/(t_{max}-t_{min})$. When I try plotting the derivative $df/dt = s'[[2]]$ by

Show[ParametricPlot[{93*p, 1/93 s'[p][[2]]}, {p, 0, 1}], AspectRatio -> 1]


it shows me the error warning

Part::partw: Part 2 of BSplineFunction[{{0.,1.}},<>][t] does not exist. >>

but still shows the correct graph. What went wrong?

data = {{3.107, 0.997}, {6.851, 1.008}, {10.594, 1.011}, {14.338,
1.007}, {18.081, 0.977}, {21.825, 0.967}, {25.568, 0.917}, {29.311,
0.852}, {33.055, 0.736}, {36.798, 0.533}, {40.542, 0.336}, {44.285,
0.205}, {48.029, 0.111}, {51.772, 0.074}, {55.516, 0.044}, {59.259,
0.032}, {63.003, 0.034}, {66.746, 0.01}, {70.49, 0.026}, {74.233,
0.01}, {77.977, 0.016}, {81.72, 0.002}, {85.464, -0.002}, {89.207,
0.01}, {92.951, 0.01}}
s = BSplineFunction[data, SplineDegree -> 3];


There is a caveat to the method. When fitting a spline to data p is not necessarily proportional to the independent variable. In my case the relationship between $p$ and $t(p)$ deviates substantially from linearity outside the range $p \in (0.025, 0.975)$.

Is there a better way to get the derivative?

-

The warning is probably caused by premature evaluation (no pun intended). Because of the symbolic parameter t, s[t] evaluates to BSplineFunction[{{0.,1.}},<>][t] instead of a list of the form {x,y}, and only evaluates to numeric values when t assumes numeric values, too. The normal solution to this is to postpone the access of the y-variable [[2]] to when t assumes numeric values by hiding it in a wrapper-function with the help of SetDelayed / :=

YDerivative[t_?NumericQ] := (1/93) s'[t][[2]]
Show[ParametricPlot[{93*t, YDerivative[t]}, {t, 0, 1}], AspectRatio -> 1]

-
 Works great, thanks very much! – malumno Jan 23 at 10:07

I would have used the "Spline" method of Interpolation[] myself:

sa = Interpolation[data, InterpolationOrder -> 3, Method -> "Spline"];
sp = sa';

Plot[{sa[t], sp[t]}, {t, data[[1, 1]], data[[-1, 1]]}, Axes -> None,
Epilog -> {AbsolutePointSize[4], Red, Point /@ data}, Frame -> True]


-
 One important difference between the two methods is, as far as I know, that Interpolation[] does an interpolation and forces the spline to go through all the data points, while BSplineFunction[] creates a smoothing spline, which only uses the points as knots, but doesn't pass through them. I wanted to use a smoothing spline to decrease the level of noise in the derivative. – malumno Feb 11 at 12:48