[SciPy-User] Interpolate: Derivatives of parametric splines
Zachary Pincus
zachary.pincus@yale....
Thu Nov 12 09:31:14 CST 2009
Hi,
> thanks for your answer. Maybe I didn't get you right.
> The first derivative at pi/2 should be 0 ( cos(pi/2) ).
> What I get from interpolate.spalde(0.25, tckp) is
>
> 7.44935679e+00 and -3.47491248e-01.
The first value is dx/du at 0.25. If you look at der1[0] (e.g. dx/du),
you'll see it's basically constant, which is what you expect since x
and u are linear with one another.
> Why those different 'x' values at all?
> It should be always 1.57079633e+00, no?
I don't know why you think dx/du ought to be pi/2: x goes from 0 to
2pi while u goes from 0 to 1, therefore the slope of the line x(u) is
2pi; thus dx/du ought to be 2pi as well. Which it is, more or less,
except for endpoint effects. These effects are more pronounced with
parametric splines since, basically, there's more degrees of freedom
for what the spline can do beyond the range of the input data. (Check
out how the spline goes beyond the endpoints of your original data --
the parametric spline goes nuts, because, essentially, dx/du isn't
fixed at a constant, unlike in the nonparametric spline case. When
fitting a function with fewer constraints, it should not be a surprise
that the fit is worse.)
Now, the second value you show above (-3.47491248e-01) is dy/du at
0.25. Because dx/du is ~constant, dy/du should have the same zeros as
dy/dx. Now, -0.35 isn't exactly zero, but if you look at the plot of
der1[1], you'll see that der1[1] does have a zero pretty close to 0.25
that point. So again, you're getting more or less the expected result,
especially given that a parametric spline fit with all those extra
degrees of freedom just won't fit a function y(x) as well as the
nonparametric spline designed for fitting functions of the form y(x).
Make sense?
By the way, if I were to try to evaluate a periodic function with a
spline, I'd use interpolate.splrep with per=1. And if I had a periodic
parametric function (e.g. a closed plane curve), use splprep with
per=1. Periodic functions are the only case where endpoint effects can
be completely banished with spline fitting. Otherwise endpoints
effects are just par for the course with non-periodic spline fits, and
are, as above, more troublesome in the parametric case because there
are even more degrees of freedom. Feed splrep more data and you'll get
better results because there are more constraints.
Alternately, use a lower-order spline -- which are less prone to
"ringing" artifacts when under-constrained -- to get better results
with sparser data. (Not also below my use of numpy.linspace, which is
far easier than arange for the sort of things you're needing.)
# Not much data, high order spline
In [119]: x = np.linspace(0, 2*np.pi, 9)
In [120]: y = np.sin(x)
In [121]: tckp, u = interpolate.splprep([x, y], s=0, k=5)
In [122]: interpolate.spalde(0.25, tckp)[1]
array([ 1.00000000e+00, -3.47491248e-01, -5.16420728e+01,
2.05418849e+02, 3.66866738e+03, -5.71113127e+04])]
# More data, high order spline
In [123]: x = np.linspace(0, 2*np.pi, 20)
In [124]: y = np.sin(x)
In [125]: tckp, u = interpolate.splprep([x, y], s=0, k=5)
In [126]: interpolate.spalde(0.25, tckp)[1]
array([ 9.99945859e-01, 4.44888721e-03, -5.85188610e+01,
-3.32328600e+01, 1.61037915e+04, 2.86354557e+05])]
# Not much data, but lower order spline
In [127]: x = np.linspace(0, 2*np.pi, 9)
In [128]: y = np.sin(x)
In [129]: tckp, u = interpolate.splprep([x, y], s=0, k=3)
In [130]: interpolate.spalde(0.25, tckp)[1]
array([ 1.00000000e+00, -6.93498869e-02, -6.23269054e+01,
4.25319565e+02])]
Zach
More information about the SciPy-User
mailing list