Python 中快速、小型且重复的矩阵乘法

2024-05-04

我正在寻找一种使用 Python/Cython/Numpy 快速将许多 4x4 矩阵相乘的方法,任何人都可以给出任何建议吗?

为了展示我当前的尝试,我有一个需要计算的算法

A_1 * A_2 * A_3 * ... * A_N 

哪里每个

A_i != A_j

Python 中的一个示例:

means = array([0.0, 0.0, 34.28, 0.0, 0.0, 3.4])
stds = array([ 4.839339, 4.839339, 4.092728, 0.141421, 0.141421, 0.141421])

def fn():
    steps = means+stds*numpy.random.normal(size=(60,6))
    A = identity(4)
    for step in steps:
        A = dot(A, transform_step_to_4by4(step))
%timeit fn()

1000 loops, best of 3: 570 us per loop

在 Cython/Numpy 中实现此算法比使用 Eigen/C++ 进行所有优化的等效代码慢大约 100 倍。不过,我真的不想使用 C++。


如果您必须调用 Python 函数来生成每个要相乘的矩阵,那么您的性能基本上就被搞砸了。但如果你可以向量化transform_step_to_4by4函数,并让它返回一个具有形状的数组(n, 4, 4)那么你可以使用节省一些时间matrix_multiply:

import numpy as np
from numpy.core.umath_tests import matrix_multiply

matrices = np.random.rand(64, 4, 4) - 0.5

def mat_loop_reduce(m):
    ret = m[0]
    for x in m[1:]:
        ret = np.dot(ret, x)
    return ret

def mat_reduce(m):
    while len(m) % 2 == 0:
        m = matrix_multiply(m[::2], m[1::2])
    return mat_loop_reduce(m)

In [2]: %timeit mat_reduce(matrices)
1000 loops, best of 3: 287 us per loop

In [3]: %timeit mat_loop_reduce(matrices)
1000 loops, best of 3: 721 us per loop

In [4]: np.allclose(mat_loop_reduce(matrices), mat_reduce(matrices))
Out[4]: True

现在,您有 log(n) 个 Python 调用而不是 n,这有利于 2.5 倍的加速,对于 n = 1024,这将接近 10 倍。显然matrix_multiply是一个 ufunc,因此有一个.reduce方法,这将允许您的代码在 Python 中不运行循环。但我无法让它运行,不断收到一个神秘的错误:

In [7]: matrix_multiply.reduce(matrices)
------------------------------------------------------------
Traceback (most recent call last):
  File "<ipython console>", line 1, in <module>
RuntimeError: Reduction not defined on ufunc with signature
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Python 中快速、小型且重复的矩阵乘法 的相关文章

随机推荐