什么是在numpy数组乘法中实现二次形式最快的方法?

11

我已经尝试了这两种替代方案

objective = lambda A, x : (np.dot(x.T ,np.dot(A, x)))[0,0]
objective = lambda A, x : (np.matrix(x).T * np.matrix(A) * np.matrix(x))[0,0]

我的算法在primary中运行了5秒钟,在secondary中运行了14秒。

使用MATLAB只需要2秒。

我想使用Numpy,但显然我需要一种改进这个糟糕结果的方法。如何获得更快的二次形式矩阵、向量乘积?

注意:我对代码进行了分析,发现这个lambda函数耗费了很多时间。 改进:我仅删除了原生的Ubuntu scipy和numpy包,然后使用以下安装程序进行安装。

sudo pip install numpy
sudo apt-get install libatlas-base-dev gfortran
sudo pip install scipy
sudo apt-get install libpng-dev libfreetype6-dev
sudo pip install matplotlib 

我稍微提高了性能,但仍然低于Matlab。


最后的 [0, 0] 是什么意思? - Bi Rico
1
你的矩阵有多大?如果它们很大,速度瓶颈不在Numpy上。获取与Intel MKL或其他高性能线性代数库链接的Numpy副本。 - pv.
作为一个对加速Python感兴趣的人,您可能会发现这篇关于Cython的博客很有意思。不幸的是,在这种情况下,cython并没有改进np.dot - yardsale8
1
@Erogol:Matlab使用Intel MKL,它比ATLAS更优化。你可以尝试免费的Openblas,它可能表现更好,而不是ATLAS。 - pv.
@pv 我也发现了这个。你有什么评论吗?http://queforum.com/python/418459-python-build-numpy-eigen-instead-atlas-openblas.html - erogol
显示剩余4条评论
2个回答

7
我已经安装了NumPy和Matlab,它们分别需要大约45毫秒来处理一个10000x10000的矩阵。
考虑到你提供的计时数据,我怀疑x不是仅仅一个列向量。 如果你想一次进行多列向量的计算,请看看我在这个问题中的回答: Calculate "v^T A v" for a matrix of vectors v。 如果x只是一个列向量(在NumPy或者Matlab中),你列出的计时非常慢。
然而,我怀疑差异也可能来源于您的NumPy编译方式。 这实际上是由NumPy和Matlab使用的BLAS函数的计时决定的。 我相信在我的机器上,两者都会调用相同的底层库,因为我已经将NumPy关联到Intel的MKL上。 如果NumPy使用了像Intel MKL这样优化良好的BLAS,则类似于此类的大型向量操作应以与Matlab相同的速度运行,因为它们都很可能调用相同的底层BLAS函数。 如果您的版本的NumPy没有使用优化的BLAS进行编译,则性能将更差。
如果您知道自己的NumPy安装已经与MKL关联,则可以尝试设置MKL_NUM_THREADS环境变量以匹配您系统上的处理器数量。
获得正确编译版本的NumPy的一种简单方法是使用预构建的发行版。 Anaconda和Enthought都很好,但需要订阅才能获得优化版本。学术许可证可免费获取。 您还可以看看这里:http://www.lfd.uci.edu/~gohlke/pythonlibs/

1
+1,因为我得到了类似的结果。在使用Anaconda学术许可证的一台4年旧的廉价笔记本电脑上,10000x10000矩阵大约需要400毫秒。 - yardsale8
1
我怀疑“我的算法运行时间为5秒”的报告意味着该算法多次计算二次形式。 - Warren Weckesser
好的观点。这是相当开放性的问题。我怀疑他们正在计时使用1500x1500数组的x和A的乘法,但这可能是错误的。 - IanH
如何检查我的安装是否绑定到正确的后端库集? - erogol
好的,如果还有其他人有这个问题,你可以使用 import numpy 然后 numpy.show_config() 来检查是否正在使用 MKL。如果你正在使用 MKL,不同的 "libraries" 选项应该有几个项目提到了 MKL。 - IanH

3
最后,我所做的是更改numpy线性代数函数的有界库。它默认使用ATLAS,但我花了很多时间(大约4个小时)将其更改为OpenBlas。我发现了这篇指南Compiling numpy with OpenBLAS integration并逐步跟随。结果是运行速度更快。虽然与Matlab(Intel MLK)2.5秒相比仍有所不足,但在3秒内执行是可以接受的。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接