在this question中,我向社群询问了scipy.interpolate.splev
如何计算样条基础..我的目标是通过预先计算splev
来比bspline basis
更快地计算样条线并通过执行basis
到control point
点积生成曲线。
此后a new scipy.interpolate.BSpline
interpolator被添加到scipy
。 It comes with a basis_element
function,我认为可以用来返回用于计算样条曲线的基础。
例如,使用下面的输入代码from here:
import numpy as np
# Control points
cv = np.array([[ 50., 25., 0.],
[ 59., 12., 0.],
[ 50., 10., 0.],
[ 57., 2., 0.],
[ 40., 4., 0.],
[ 40., 14., 0.]])
kv = [0, 0, 0, 0, 1, 2, 3, 3, 3, 3] # knot vector
n = 10 # 10 samples (keeping it simple)
degree = 3 # Curve degree
我可以计算以下bspline基础:
[[ 1. 0. 0. 0. 0. 0. ]
[ 0.2962963 0.56481481 0.13271605 0.00617284 0. 0. ]
[ 0.03703704 0.51851852 0.39506173 0.04938272 0. 0. ]
[ 0. 0.25 0.58333333 0.16666667 0. 0. ]
[ 0. 0.07407407 0.54938272 0.36728395 0.00925926 0. ]
[ 0. 0.00925926 0.36728395 0.54938272 0.07407407 0. ]
[ 0. 0. 0.16666667 0.58333333 0.25 0. ]
[ 0. 0. 0.04938272 0.39506173 0.51851852 0.03703704]
[ 0. 0. 0.00617284 0.13271605 0.56481481 0.2962963 ]
[ 0. 0. 0. 0. 0. 1. ]]
在np.dot
和basis
上使用control points
会在曲线上返回10个样本:
[[ 50. 25. 0. ]
[ 55.12654321 15.52469136 0. ]
[ 55.01234568 11.19753086 0. ]
[ 53.41666667 9.16666667 0. ]
[ 53.14506173 7.15432099 0. ]
[ 53.1882716 5.17901235 0. ]
[ 51.58333333 3.83333333 0. ]
[ 47.20987654 3.87654321 0. ]
[ 42.31790123 6.7345679 0. ]
[ 40. 14. 0. ]]
问题:是否可以从scipy.interpolate.BSpline
中提取上述基础?
显然我一定是错了,因为当我尝试时,我会得到这样的东西:
from scipy.interpolate import BSpline
b = BSpline.basis_element(kv)
print b(np.linspace(kv[0],kv[-1],n)) # i'm not sure what these values represent
[ 0. 0.00256299 0.04495618 0.16555213 0.28691315 0.28691315
0.16555213 0.04495618 0.00256299 0. ]
答案 0 :(得分:2)
BSpline.basis_element
以内部结为参数。
在你的例子中,你填补了结,这没有按照你的想法做到:
In [3]: t = [0, 0, 0, 0, 1, 2, 3, 3, 3, 3]
In [4]: b = BSpline.basis_element(t)
In [5]: b.k
Out[5]: 8
所以它是一个8阶样条。
如果你想要一个二次样条,你可以
In [7]: b1 = BSpline.basis_element([0, 1, 2, 3])
In [8]: b1.k
Out[8]: 2
In [9]: b1.t
Out[9]: array([-1., -1., 0., 1., 2., 3., 4., 4.])
困惑?方法很简单:https://github.com/scipy/scipy/blob/v0.19.1/scipy/interpolate/_bsplines.py#L243-L302
BSpline.basis_element
返回的可调用实际上是一个b样条函数。使用数组参数调用它的结果等同于直接运行{{1}中的示例代码在数组的每个元素的循环中使用docstring https://docs.scipy.org/doc/scipy/reference/generated/scipy.interpolate.BSpline.html
编辑:如果您在Cox-de Boor算法的变体后计算给定点的所有非零样条线,那么您可以查看BSpline
函数,https://github.com/scipy/scipy/blob/v0.19.1/scipy/interpolate/_bspl.pyx#L161
(它本身只是一个C程序的包装器,可以完成所有繁重的工作;请注意, hard 可以击败后者的表现。)
但是,它不是公共功能,因此不保证在将来的版本中可用。如果您对它有很好的用处,并建议使用面向用户的API,请将讨论带到scipy bug跟踪器。