问题描述
我正在用python编写一些代码,这些代码需要频繁地反转大型平方矩阵(100-200行/列).
I'm writing some code in python that requires frequently inverting large square matrices (100-200 rows/colums).
我正在达到机器精度的极限,因此开始尝试使用mpmath
进行任意精度的矩阵求逆,但是即使使用gmpy
,它也非常慢.
I'm hitting the limits of machine precision so have started trying to use mpmath
to do arbitrary precision matrix inversion but it is very slow, even using gmpy
.
将精度为30(十进制)的大小为20、30、60的随机矩阵反转需要大约0.19、0.60和4.61秒,而mathematica
中的相同运算需要0.0084、0.015和0.055秒.
Inverting random matrices of size 20, 30, 60 at precision 30 (decimal) takes ~ 0.19, 0.60, and 4.61 seconds whereas the same operations in mathematica
take 0.0084, 0.015, and 0.055 seconds.
这是在Arch Linux计算机上使用python3
和mpmath 0.17
(不确定gmpy版本).我不确定为什么mpmath这么慢,但是是否有任何开放源代码库可以达到mathematica所能达到的速度(即使是1/2的速度也不错)?
This is using python3
and mpmath 0.17
(not sure of gmpy version) on an arch linux machine. I'm not sure why mpmath is so much slower but is there any open source library that will approach the speeds mathematica manages for this (even 1/2 as fast would be good)?
我不需要任意精度-128位可能就足够了.我也只是不明白mpmath怎么会这么慢.它必须使用非常不同的矩阵求逆算法.具体来说,我正在使用M**-1
.
I don't need arbitrary precision -- 128 bit would probably be good enough. I also just don't understand how mpmath can be so much slower. It must be using a very different matrix inversion algorithm. To be specific I'm using M**-1
.
有没有一种方法可以使它使用更快的算法或加快其运行速度.
Is there a way to get it to use a faster algorithm or to speed it up.
推荐答案
mpmath中的Linera代数相当慢.有许多库可以更好地解决此问题(例如, Sage ).就是说,作为Stuart建议的后续措施,使用定点算术在不安装任何库的情况下在Python中进行相当快速的高精度矩阵乘法是相当容易的.这是使用mpmath矩阵进行输入和输出的版本:
Linera algebra in mpmath is rather slow, unfortunately. There are many libraries that solve this problem much better (Sage for example). That said, as a followup to Stuart's suggestion, it is fairly easy to do reasonably fast high-precision matrix multiplication in Python without installing any libraries, using fixed-point arithmetic. Here is a version using mpmath matrices for input and output:
def fixmul(A, B, prec):
m = A.rows; p = B.rows; n = B.cols;
A = [[A[i,j].to_fixed(prec) for j in range(p)] for i in range(m)]
B = [[B[i,j].to_fixed(prec) for j in range(n)] for i in range(p)]
C = [([0] * n) for r in range(m)]
for i in range(m):
for j in range(n):
s = 0
for k in range(p):
s += A[i][k] * B[k][j]
C[i][j] = s
return mp.matrix(C) * mpf(2)**(-2*prec)
在256位精度下,这对两个200x200矩阵的乘积比mpmath快16倍.用这种方法直接编写矩阵求逆程序也不难.当然,如果矩阵条目非常大或非常小,则需要先重新缩放它们.一个更可靠的解决方案是使用 gmpy 中的浮点类型编写自己的矩阵函数. ,其速度应该基本上一样快.
At 256-bit precision, this multiplies two 200x200 matrices 16 times faster than mpmath for me. It is also not difficult to write a matrix inversion routine directly this way. Of course if the matrix entries are very large or very small, you want to rescale them first. A more solid solution would be to write your own matrix functions using the floating-point types in gmpy, which should be essentially as fast.
这篇关于mpmath矩阵求逆的替代方案或加速方案的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!