我正在研究的一些研究需要象征性地采用大矩阵的行列式;矩阵范围从18x18到318x318。矩阵条目是同一变量omega
中的数字2或多项式。
目前,我正在尝试在SymPy中使用.det()
方法,但它非常慢;一个18x18的矩阵现在已经运行了超过45分钟,并且在我写这篇文章的时候仍在运行。我意识到决定性计算是非常密集的,但我能做些什么来加快这个速度?
我已经在Speeding up computation of symbolic determinant in SymPy阅读了这篇文章,但是没有从帖子中删除任何可以加快进程的实际操作。我能做什么?
答案 0 :(得分:2)
SymPy对决定因素并不天真(参见MatrixDeterminant class)但似乎在整个计算过程中处理符号表达是一个缓慢的过程。当已知行列式是某种程度的多项式时(因为矩阵条目是),事实证明,为变量的几个值计算其数值并加以内插更快。
我的测试用例是一个密集的15乘15的矩阵,其中包含变量omega
的二次多项式,具有整数系数。我仍然使用SymPy的.det
方法作为数字行列式,因此系数最终都是完全相同的长整数。
import numpy as np
from sympy import *
import time
n = 15
omega = Symbol('omega')
A = Matrix(np.random.randint(low=0, high=20, size=(n, n)) + omega*np.random.randint(low=0, high=20, size=(n, n)) + omega**2 * np.random.randint(low=0, high=20, size=(n, n)))
start = time.time()
p1 = A.det() # direct computation
print('Time: ' + str(time.time() - start))
start = time.time()
xarr = range(-n, n+1) # 2*n+1 points to get a polynomial of degree 2*n
yarr = [A.subs(omega, x).det() for x in xarr] # numeric values
p2 = expand(interpolating_poly(len(xarr), omega, xarr, yarr)) # interpolation
print('Time: ' + str(time.time() - start))
p1和p2都是相同的多项式。运行时间(在相当慢的机器上,来自亚马逊的t2.nano):
如果你的系数是浮点数并且在处理它们时你不期望精确的算术结果,可以通过将矩阵评估为NumPy数组,并使用NumPy方法作为行列式来实现进一步的加速: / p>
Anum = lambdify(omega, A)
yarr = [np.linalg.det(Anum(x)) for x in xarr]
答案 1 :(得分:0)
作为其他任何关注此线程的人员的跟进:自从几年前尝试解决此问题以来,我已经学到了很多有关数值方法和通用计算的知识,并且意识到采用a的符号行列式是不可行的大的矩阵。通过将其转换为特征值问题,最终解决了这一问题。故事的寓意……解决问题通常有多种方式,有些可能比其他方式更可行。