Python 符号行列式的计算速度慢

Python 符号行列式的计算速度慢,python,matrix,sympy,determinants,Python,Matrix,Sympy,Determinants,我正在进行的一些研究需要象征性地采用大型矩阵的行列式;矩阵范围从18x18到318x318。矩阵项是同一变量中的数值或二次多项式,omega 目前,我正在尝试在Symphy中使用.det()方法,但速度非常慢;一个18x18矩阵已经运行了超过45分钟,在我写这篇文章的时候,它仍然在计算。我意识到行列式计算非常密集,但我能做些什么来加快计算速度吗? 我已经在上读过这篇文章,但没有从文章中删去任何东西来说明可以做些什么来加速这个过程。我能做什么 SymPy对行列式并不幼稚(参见),但在整个计算过程中

我正在进行的一些研究需要象征性地采用大型矩阵的行列式;矩阵范围从18x18到318x318。矩阵项是同一变量中的数值或二次多项式,
omega

目前,我正在尝试在Symphy中使用
.det()
方法,但速度非常慢;一个18x18矩阵已经运行了超过45分钟,在我写这篇文章的时候,它仍然在计算。我意识到行列式计算非常密集,但我能做些什么来加快计算速度吗?
我已经在上读过这篇文章,但没有从文章中删去任何东西来说明可以做些什么来加速这个过程。我能做什么

SymPy对行列式并不幼稚(参见),但在整个计算过程中处理符号表达式似乎是一个缓慢的过程。当已知行列式是某种程度的多项式时(因为矩阵项是多项式),计算变量的几个值的数值并插值会更快

我的测试用例是一个密集的15×15矩阵,充满了变量为ω的二次多项式,具有整数系数。对于数值行列式,我仍然使用Symphy的
.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都是相同的多项式。运行时间(在相当慢的机器上,来自Amazon的t2.nano):

  • 74.6秒用于直接计算
  • 插值时间为5.4秒
如果您的系数是浮点数,并且在处理它们时不希望得到精确的算术结果,则可以通过将矩阵作为NumPy数组进行计算,并对行列式使用NumPy方法来实现进一步的加速:

Anum = lambdify(omega, A)
yarr = [np.linalg.det(Anum(x)) for x in xarr]

作为对其他研究这个问题的人的补充:自从几年前尝试解决这个问题以来,我学到了很多关于数值方法和一般计算的知识,并且意识到对这么大的矩阵进行符号行列式是多么不可行。最后,我把这个问题转化为特征值问题,用数值方法解决了这个问题。故事的寓意。。。解决一个问题通常有多种方法,有些方法可能比其他方法更可行。

你怎么认为这是可能的?稠密符号NxN矩阵的行列式具有
math.factorial(N)
项。例如,对于18x18矩阵,这是6402373705728000个术语。我想说,我们会在那之前就死了,除非你会在那之前很久耗尽内存;-)@蒂姆彼得斯:我认为这应该是一个答案。@TimPeters,我不确定你从哪里得到N个阶乘,但是有比标准的协因子展开更有效的算法来计算行列式。例如,使用LU分解可以大大减少计算大型矩阵行列式所需的计算开销。对于15x15矩阵,使用共因子展开计算行列式将需要约2.3万亿次乘法。使用LU因子分解只需要大约1100次乘法即可计算行列式。一定有什么东西我可以改变,让它运行得更快。所以你的矩阵似乎有特殊的结构:它不像[[a,b],[c,d]]有符号a,b,c,d,而是更像[[x+1,x],[x-1,x-3]],矩阵中有一个符号。这一点很重要,因为这样的答案确实要小得多,人们可以希望优化计算。请编辑你的问题来描述符号矩阵的结构。好的,但如果这些都是欧米茄的一般函数,那么行列式中就不能有任何简化。它们是ω的线性函数,还是其他阶的多项式?系数是整数还是浮点数?