python - 如何从 scipy.interpolate.BSpline 中提取 BSpline 基础

标签 python numpy scipy

this question 中,我向社区询问了 scipy.interpolate.splev 如何计算样条曲线基础。我的目标是通过预计算比 splev 更快地计算样条曲线bspline 基础,并通过对控制点点积执行基础来生成曲线。

此后,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基础控制点返回曲线上的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.        ]

最佳答案

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

所以这是一个八阶样条线。

如果你想要二次样条,你会这样做

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 样条函数。 使用数组参数调用它的结果相当于直接运行示例代码在数组每个元素的循环中的 BSpline 文档字符串中,https://docs.scipy.org/doc/scipy/reference/generated/scipy.interpolate.BSpline.html

编辑:如果您正在使用 Cox-de Boor 算法的变体来计算给定点的所有非零样条线,那么您可以查看 _bspl.evaluate_all_bsplines 函数,https://github.com/scipy/scipy/blob/v0.19.1/scipy/interpolate/_bspl.pyx#L161 (它本身只是 C 例程的包装,它完成了所有繁重的工作;请注意,在性能方面很难击败后一个例程。)

但是,它不是公共(public)函数,因此不保证在未来版本中可用。如果您对它有很好的用途,并且对面向用户的 API 有建议,请将讨论转移到 scipy bug 跟踪器。

关于python - 如何从 scipy.interpolate.BSpline 中提取 BSpline 基础,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45927965/

相关文章:

python - 根据其他两个数组中公共(public)值的索引从数组返回值

python - 使用 Plotly Python 在条形图中生成随机颜色

python - 使用 Python 将值分解为唯一行

python - Pandas 中数据框行中的数据框列

python - N点与numpy/scipy中的引用之间的有效距离计算

python - python中的并行/多线程差异进化

python - 同时使用带参数和不带参数的装饰器

python - 如何获取 ctypes.c_char_p 实例的指针地址

python - 如何根据最后一行/下一行过滤 Pandas 行?

python - 错误 : Could not build wheels for scipy which use PEP 517 and cannot be installed directly