我正在尝试尽可能快地计算许多3x1向量对的叉积。这个过程可以通过以下方式实现:
有没有什么想法可以改进
n = 10000
a = np.random.rand(n, 3)
b = np.random.rand(n, 3)
numpy.cross(a, b)
这个问题已经有正确的答案了,但是受到类似问题的这个答案的启发,我认为einsum
可能会对我有所帮助。我发现两种方法都可以:
eijk = np.zeros((3, 3, 3))
eijk[0, 1, 2] = eijk[1, 2, 0] = eijk[2, 0, 1] = 1
eijk[0, 2, 1] = eijk[2, 1, 0] = eijk[1, 0, 2] = -1
np.einsum('ijk,aj,ak->ai', eijk, a, b)
np.einsum('iak,ak->ai', np.einsum('ijk,aj->iak', eijk, a), b)
计算叉积的方法很多,但它们的性能令人失望:这两种方法的性能都比np.cross
差很多:
%timeit np.cross(a, b)
1000 loops, best of 3: 628 µs per loop
%timeit np.einsum('ijk,aj,ak->ai', eijk, a, b)
100 loops, best of 3: 9.02 ms per loop
%timeit np.einsum('iak,ak->ai', np.einsum('ijk,aj->iak', eijk, a), b)
100 loops, best of 3: 10.6 ms per loop
有没有什么想法可以改进
einsum
函数?
Cython
的优化可能并不显着。当以这种方式表达时,cross
更像是一种代数运算而不是数组运算。 - hpaulj