科学中的样条插值系数


问题内容

我想通过scipy计算样条插值的系数。在MATLAB中:

x=[0:3];
y=[0,1,4,0];
spl=spline(x,y);
disp(spl.coefs);

它将返回:

ans =

   -1.5000    5.5000   -3.0000         0
   -1.5000    1.0000    3.5000    1.0000
   -1.5000   -3.5000    1.0000    4.0000

但是我无法通过scipy中的interpolate.splrep做到这一点。你能告诉我怎么计算吗?


问题答案:

我不确定是否有任何方法可以从scipy准确地获得这些系数。是什么scipy.interpolate.splrep让你对绳结的B样条系数。Matlab的样条曲线为您提供的似乎是描述连接传递点的三次方程的偏多项式系数,这使我相信Matlab样条曲线是基于控制点的样条曲线,例如Hermite或Catmull-
Rom而不是b样条曲线。

但是,scipy.interpolate.interpolate.spltopp确实提供了一种获取b样条的多项式系数的方法。不幸的是,它似乎不能很好地工作。

>>> import scipy.interpolate
>>> x = [0, 1, 2, 3]
>>> y = [0, 1, 4, 0]
>>> tck = scipy.interpolate.splrep(x, y)
>>> tck
Out: 
    (array([ 0.,  0.,  0.,  0.,  3.,  3.,  3.,  3.]),
    array([  3.19142761e-16,  -3.00000000e+00,   1.05000000e+01,
        0.00000000e+00,   0.00000000e+00,   0.00000000e+00,
        0.00000000e+00,   0.00000000e+00]),
    3)

>>> pp = scipy.interpolate.interpolate.spltopp(tck[0][1:-1], tck[1], tck[2])

>>> pp.coeffs.T
Out: 
    array([[ -4.54540394e-322,   0.00000000e+000,   0.00000000e+000,
           0.00000000e+000],
        [ -4.54540394e-322,   0.00000000e+000,   0.00000000e+000,
           0.00000000e+000],
        [ -4.54540394e-322,   0.00000000e+000,   0.00000000e+000,
           0.00000000e+000],
        [  0.00000000e+000,   0.00000000e+000,   0.00000000e+000,
           0.00000000e+000],
        [  0.00000000e+000,   0.00000000e+000,   0.00000000e+000,
           0.00000000e+000]])

请注意,每个结有一组系数,而不是传入的每个原始点都有一组系数。而且,将系数乘以b样条基础矩阵似乎没有什么帮助。

>>> bsbm = array([[-1,  3, -3,  1], [ 3, -6,  3,  0], [-3,  0,  3,  0], 
                 [ 1,  4,  1,  0]]) * 1.0/6
Out: 
    array([[-0.16666667,  0.5       , -0.5       ,  0.16666667],
        [ 0.5       , -1.        ,  0.5       ,  0.        ],
        [-0.5       ,  0.        ,  0.5       ,  0.        ],
        [ 0.16666667,  0.66666667,  0.16666667,  0.        ]])

>>> dot(pp.coeffs.T, bsbm)
Out: 
    array([[  7.41098469e-323,  -2.27270197e-322,   2.27270197e-322,
           -7.41098469e-323],
        [  7.41098469e-323,  -2.27270197e-322,   2.27270197e-322,
           -7.41098469e-323],
        [  7.41098469e-323,  -2.27270197e-322,   2.27270197e-322,
           -7.41098469e-323],
        [  0.00000000e+000,   0.00000000e+000,   0.00000000e+000,
           0.00000000e+000],
        [  0.00000000e+000,   0.00000000e+000,   0.00000000e+000,
           0.00000000e+000]])

FORTRAN分段多项式程序包PPPack具有bsplpp将B样条转换为分段多项式形式的命令,可以满足您的需要。不幸的是,目前没有用于PPPack的Python包装器。