计算双变量样条曲线的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是否有类似的算法,一旦用numbacython编写,就可以产生更好的性能?

否则可以改进上面的basis_bispeu函数来更快地计算基数吗?也许我不知道内置的numpy函数会有所帮助。

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...