[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