[Scipy-svn] r2998 - trunk/Lib/interpolate
scipy-svn@scip...
scipy-svn@scip...
Mon May 14 17:11:54 CDT 2007
Author: oliphant
Date: 2007-05-14 17:11:48 -0500 (Mon, 14 May 2007)
New Revision: 2998
Modified:
trunk/Lib/interpolate/interpolate.py
Log:
Fix spline interpolation.
Modified: trunk/Lib/interpolate/interpolate.py
===================================================================
--- trunk/Lib/interpolate/interpolate.py 2007-05-14 20:35:36 UTC (rev 2997)
+++ trunk/Lib/interpolate/interpolate.py 2007-05-14 22:11:48 UTC (rev 2998)
@@ -4,7 +4,8 @@
# !! Need to find argument for keeping initialize. If it isn't
# !! found, get rid of it!
-__all__ = ['interp1d', 'interp2d', 'cspline', 'cspeval', 'csprep']
+__all__ = ['interp1d', 'interp2d', 'cspline', 'cspeval', 'csprep', 'csp2pp',
+ 'ppval']
from numpy import shape, sometrue, rank, array, transpose, \
swapaxes, searchsorted, clip, take, ones, putmask, less, greater, \
@@ -296,7 +297,7 @@
return out_of_bounds
-def _get_cspline_Bb(yk, xk, kind, conds):
+def _get_cspline_Bb(xk, yk, kind, conds):
# internal function to compute different tri-diagonal system
# depending on the kind of spline requested.
# conds is only used for 'second' and 'first'
@@ -346,7 +347,7 @@
sl_N += (xN0-xN1)*(xN0-xN3)/((xN2-xN0)*(xN2-xN1)*(xN3-xN2))*yk[-3]
sl_N += (xN0-xN1)*(xN0-xN2)/((xN3-xN0)*(xN3-xN1)*(xN3-xN2))*yk[-4]
elif kind == 'clamped':
- sl_0,sl_N = 0.0, 0.0
+ sl_0, sl_N = 0.0, 0.0
elif kind == 'first':
sl_0, sl_N = conds
@@ -375,8 +376,9 @@
else:
B[0,:2] = [2*d1,d1]
B[-1,-2:] = [dN,2*dN]
-
- b = np.empty((Np1,)*yk.shape[1:])
+
+ # Set up RHS (b)
+ b = np.empty((Np1,)+yk.shape[1:])
dyk = (yk[1:]-yk[:-1])*1.0
if kind in ['not-a-knot', 'runout', 'parabolic']:
b[0] = b[-1] = 0.0
@@ -386,7 +388,7 @@
raise NotImplementedError
else:
b[0] = (dyk[0]/d1 - sl_0)
- b[-1] = (dyk[-1]/dN - sl_N)
+ b[-1] = -(dyk[-1]/dN - sl_N)
b[1:-1,...] = (dyk[1:]/alpha[1:]-dyk[:-1]/alpha[:-1])
b *= 6.0
return B, b, None, None
@@ -404,6 +406,7 @@
The first-dimension will be considered the interpolating dimension.
"""
indxs = np.searchsorted(xk, xnew)
+ indxs[indxs==0] = 1
indxsm1 = indxs-1
xkm1 = xk[indxsm1]
xkvals = xk[indxs]
@@ -417,15 +420,46 @@
val += (yk[indxs]/dk - mk0*dk/6.)*dm1
return val
-def csprep(yk,xk=None,kind='not-a-knot',conds=None):
- """Return a (Spp,xk,yk) representation of a cubic spline given data-points
+def csp2pp(mk,xk,yk):
+ """Return an N-d array providing the piece-wise polynomial form.
- yk can be a 2-d array to represent more than one curve, through
+ mk - second derivative at the knots
+ xk - knot-points
+ yk - values of the curve at the knots
+
+ The first 2 dimensions are the polynomial for a particular
+ curve. The first dimension provides the coefficients for the
+ polynomial and the second dimension provides the different pieces
+ """
+ dk = xk[1:] - xk[:-1]
+ temp1 = mk[1:] - mk[:-1]
+ temp2 = mk[1:]*xk[:-1]-mk[:-1]*xk[1:]
+ c3 = temp1/(6*dk)
+ c2 = -temp2/(2*dk)
+ c1 = (mk[1:]*xk[:-1]**2 - mk[:-1]*xk[1:]**2)/(2*dk)
+ c1 -= temp1*dk/6.
+ c1 += (yk[1:]-yk[:-1])/dk
+ c0 = (mk[:-1]*xk[1:]**3 - mk[1:]*xk[:-1]**3)/(6*dk)
+ c0 += temp2*dk/6.
+ c0 += (yk[:-1]*xk[1:] - yk[1:]*xk[:-1])/dk
+ return np.array([c3,c2,c1,c0])
+
+def ppval(pp, xk, xnew):
+ """Compute a piece-wise polynomial defined by the array of
+ coefficents pp and the break-points xk on the grid xnew
+ """
+ indxs = numpy.searchsorted(xk, xnew)-1
+ indxs[indxs<0]=0
+ return array([numpy.polyval(pp[:,k],xnew[i]) for i,k in enumerate(indxs)])
+
+def csprep(xk,yk,kind='not-a-knot',conds=None):
+ """Return a (Spp,xk,yk) representation of a cubic spline given
+ data-points
+
+ yk can be an N-d array to represent more than one curve, through
the same xk points. The first dimension is assumed to be the
interpolating dimenion.
- If xk is None, then x=arange(len(yk)) will be assumed
-
kind can be 'natural', 'second', 'clamped', 'endslope', 'periodic',
'symmetric', 'parabolic', 'not-a-knot', 'runout'
@@ -435,19 +469,13 @@
"""
yk = np.asanyarray(yk)
N = yk.shape[0]-1
- if xk is None:
- xk = arange(N+1,dtype=float)
- factor = 1.0
- else:
- deltax = (xk[-1]-xk[0])/float(N)
- factor = deltax**2
- B,b,first,last = _get_cspline_Bb(yk, xk, kind, conds)
+ B,b,first,last = _get_cspline_Bb(xk, yk, kind, conds)
mk = np.dual.solve(B,b)
if first is not None:
mk = np.concatenate((first, mk), axis=0)
if last is not None:
mk = np.concatenate((mk, last), axis=0)
- return mk/factor, xk, yk
+ return mk, xk, yk
-def cspline(yk,xk,xnew,kind='not-a-knot',conds=None):
- return cspeval(csprep(yk,xk,kind=kind,conds=conds),xnew)
+def cspline(xk,yk,xnew,kind='not-a-knot',conds=None):
+ return cspeval(csprep(xk,yk,kind=kind,conds=conds),xnew)
More information about the Scipy-svn
mailing list