获得矩阵和给定数组中每个点的点积的最快方法

2024-04-05

我有一个由 N 个点组成的 Nx3 数组,每个点都有 X、Y 和 Z 坐标。我需要旋转每个点,所以我有 3x3 的旋转矩阵。为此,我需要获得旋转矩阵和每个点的点积。问题是点数组非常庞大(~1_000_000x3),因此需要花费大量时间来计算旋转点。

到目前为止,我提出的唯一解决方案是简单的循环迭代点数组。这是带有一段数据的示例:

# Given set of points Nx3: np.ndarray
points = np.array([
     [285.679, 219.75,  524.733],
     [285.924, 219.404, 524.812],
     [285.116, 219.217, 524.813],
     [285.839, 219.557, 524.842],
     [285.173, 219.507, 524.606]
        ])
points_t = points.T 
# Array to store results
points_rotated = np.empty((points_t.shape))
# Given rotation matrix 3x3: np.ndarray
rot_matrix = np.array([
        [0.57423549, 0.81862056, -0.01067613],
        [-0.81866133, 0.57405696, -0.01588193],
        [-0.00687256, 0.0178601, 0.99981688]
            ])

for i in range(points.shape[0]):
    points_rotated[:, i] = np.dot(rot_matrix, points_t[:, i])

# Result
points_rotated.T 
# [[ 338.33677093 -116.05910163  526.59831864]
#  [ 338.1933725  -116.45955203  526.6694408 ]
#  [ 337.5762975  -115.90543822  526.67265381]
#  [ 338.26949115 -116.30261156  526.70275207]
#  [ 337.84863885 -115.78233784  526.47047941]]

我对使用 numpy 没有信心,因为我对它还很陌生,所以我确信至少有更优雅的方法。我听说过np.einsum()但我还不明白如何在这里实现它,我不确定它会让它更快。主要问题仍然是计算时间,所以我现在想知道如何让它工作得更快?

预先非常感谢您!


您可以在非 python 模式下使用 numba 并行化编写代码,如下所示:

@nb.njit("float64[:, ::1](float64[:, ::1], float64[:, ::1])", parallel=True)
def dot(a, b):  # dot(points, rot_matrix)

    dot_ = np.zeros((a.shape[0], b.shape[0]))
    for i in nb.prange(a.shape[0]):
        for j in range(b.shape[0]):
            dot_[i, j] = a[i, 0] * b[j, 0] + a[i, 1] * b[j, 1] + a[i, 2] * b[j, 2]
    return dot_

它一定比ko3 answer https://stackoverflow.com/a/72584947/13394817由于并行化和签名并使用代数代替np.dot。我已经测试了类似的代码(仅应用于数组的上三角形)而不是点积另一个答案 https://stackoverflow.com/a/72564802/13394817这表明至少快了两倍(据我记得)。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

获得矩阵和给定数组中每个点的点积的最快方法 的相关文章

随机推荐