如何解决计算双变量样条曲线的B样条曲线基础
我需要在bivariate spline
中的B-spline basis
上计算uv查询。 With this answer我有一个很好的函数(在下面复制),可以利用scipy.dfitpack.bispeu
获得我需要的结果。
import numpy as np
import scipy.interpolate as si
def fitpack_bispeu(cv,u,v,count_u,count_v,degree_u,degree_v):
# cv = grid of control vertices
# u,v = list of u,v component queries
# count_u,count_v = grid counts along the u and v directions
# degree_u,degree_v = curve degree along the u and v directions
# Calculate knot vectors for both u and v
tck_u = np.clip(np.arange(count_u+degree_u+1)-degree_u,count_u-degree_u) # knot vector in the u direction
tck_v = np.clip(np.arange(count_v+degree_v+1)-degree_v,count_v-degree_v) # knot vector in the v direction
# Compute queries
positions = np.empty((u.shape[0],cv.shape[1]))
for i in range(cv.shape[1]):
positions[:,i] = si.dfitpack.bispeu(tck_u,tck_v,cv[:,i],degree_v,v)[0]
return positions
该函数有效,但是对我而言,我可以通过提前计算bivariate basis
来获得更好的性能,然后通过点积获得我的结果。这是我为计算基础而写的。
def basis_bispeu(cv,degree_v):
# Calculate knot vectors for both u and v
tck_u = np.clip(np.arange(count_u+degree_u+1)-degree_u,count_v-degree_v) # knot vector in the v direction
# Compute basis for each control vertex
basis = np.empty((u.shape[0],cv.shape[0]))
cv_ = np.identity(len(cv))
for i in range(cv.shape[0]):
basis[:,cv_[i],v)[0]
return basis
让我们与cProfile进行比较和分析:
# A test grid of control vertices
cv = np.array([[-0.5,-0.,0.5 ],[-0.5,0.33333333],0. ],0.,-0.33333333],-0.5 ],[-0.16666667,1.,0.5,[ 0.16666667,[ 0.5,-0.5,-0.5 ]])
count_u = 4
count_v = 5
degree_u = 3
degree_v = 3
n = 10**6 # make 1 million random queries
u = np.random.random(n) * (count_u-degree_u)
v = np.random.random(n) * (count_v-degree_v)
# get the result from fitpack_bispeu
result_bispeu = fitpack_bispeu(cv,degree_v) # 0.482 seconds
# precompute the basis for the same grid
basis = basis_bispeu(cv,degree_v) # 2.124 seconds
# get results via dot product
result_basis = np.dot(basis,cv) # 0.028 seconds (17x faster than fitpack_bispeu)
# all close?
print np.allclose(result_basis,result_bispeu) # True
速度提高了17倍,预计算基础似乎是路要走,但是basis_bispeu
却很慢。
问题
有没有一种更快的方法来计算二元样条的基础?我知道deBoor's algorithm会在曲线上计算出相似的基础。对于bivariates
是否有类似的算法,一旦用numba
或cython
编写,就可以产生更好的性能?
否则可以改进上面的basis_bispeu
函数来更快地计算基数吗?也许我不知道内置的numpy
函数会有所帮助。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。