【发布时间】:2019-03-21 14:06:57
【问题描述】:
我有两个计算相同指标的函数。一个最终使用列表推导来循环计算,另一个只使用 numpy 张量操作。这些函数采用 (N, 3) 数组,其中 N 是 3D 空间中的点数。当 N ~ 3000 时,列表理解更快。就 N 而言,两者似乎都具有线性时间复杂度,即两条时间 N 线在 N=~3000 处交叉。
def approximate_area_loop(section, num_area_divisions):
n_a_d = num_area_divisions
interp_vectors = get_section_interp_(section)
a1 = section[:-1]
b1 = section[1:]
a2 = interp_vectors[:-1]
b2 = interp_vectors[1:]
c = lambda u: (1 - u) * a1 + u * a2
d = lambda u: (1 - u) * b1 + u * b2
x = lambda u, v: (1 - v) * c(u) + v * d(u)
area = np.sum([np.linalg.norm(np.cross((x((i + 1)/n_a_d, j/n_a_d) - x(i/n_a_d, j/n_a_d)),\
(x(i/n_a_d, (j +1)/n_a_d) - x(i/n_a_d, j/n_a_d))), axis = 1)\
for i in range(n_a_d) for j in range(n_a_d)])
Dt = section[-1, 0] - section[0, 0]
return area, Dt
def approximate_area_tensor(section, num_area_divisions):
divisors = np.linspace(0, 1, num_area_divisions + 1)
interp_vectors = get_section_interp_(section)
a1 = section[:-1]
b1 = section[1:]
a2 = interp_vectors[:-1]
b2 = interp_vectors[1:]
c = np.multiply.outer(a1, (1 - divisors)) + np.multiply.outer(a2, divisors) # c_areas_vecs_divs
d = np.multiply.outer(b1, (1 - divisors)) + np.multiply.outer(b2, divisors) # d_areas_vecs_divs
x = np.multiply.outer(c, (1 - divisors)) + np.multiply.outer(d, divisors) # x_areas_vecs_Divs_divs
u = x[:, :, 1:, :-1] - x[:, :, :-1, :-1] # u_areas_vecs_Divs_divs
v = x[:, :, :-1, 1:] - x[:, :, :-1, :-1] # v_areas_vecs_Divs_divs
sub_area_norm_vecs = np.cross(u, v, axis = 1) # areas_crosses_Divs_divs
sub_areas = np.linalg.norm(sub_area_norm_vecs, axis = 1) # areas_Divs_divs (values are now sub areas)
area = np.sum(sub_areas)
Dt = section[-1, 0] - section[0, 0]
return area, Dt
为什么列表推导版本在大 N 时工作得更快?当然张量版本应该更快?我想知道这是否与计算的大小有关,这意味着它太大而无法在缓存中完成?请问我是否没有提供足够的信息,我真的很想深入了解这一点。
【问题讨论】:
-
我不确定您使用的是什么算法以及近似面积张量的意思,但是您在 numpy 函数中大量使用的外部产品使 3d 数组对于大 Ns 可以真正增长制作大而耗时。您的列表理解似乎不会生成它们。可能有更简单的方法来计算这些面积,或者有人已经这样做了。
-
u的形状是什么?您的代码足够复杂,难以一目了然。许多 SO 问题已经观察到,对于非常大的数组,内存管理复杂性和迭代时间之间存在权衡。我想知道部分循环情况将如何执行 - 您仅在i上循环。 -
总体而言,您的代码非常复杂,使用了
cross和norm等复杂函数。所以很难区分大内存情况在哪里变慢。您可能需要做一些更集中的时间安排。
标签: python-3.x numpy numpy-ndarray array-broadcasting