至少它是如何出现的。以下代码对3x3和6x6矩阵的行为正确。
deter = mat.det('method':'berkowitz')
#self.resultFileHandler.writeLogStr(str(deter))
a = sy_polys.Poly(deter, k)
对于3x3,执行此代码需要~0.8s,对于6x6需要~288s(det函数只有650ms,其余为Poly)。对于10x10,要么复杂性以巨大的速度增加,要么其他一些原因阻止它从Poly呼叫返回(我等了一周)。没有例外被抛出。
决定因素的元素由大符号多项式组成。
我在0.7.1,刚升级到1.0(两个版本都有问题)。
我添加了日志以尝试获取文件的行列式,但它再次粘在str(deter)函数调用中。如果我打破我的调试器无法显示阻止(对调试器来说太大了)。
这是一个堆栈:
MainThread - pid_135368_id_42197520
_print [printer.py:262]
_print_Add [str.py:56]
_print [printer.py:257]
parenthesize [str.py:29]
_print_Mul [str.py:290]
_print [printer.py:257]
_print_Add [str.py:56]
_print [printer.py:257]
parenthesize [str.py:29]
_print_Mul [str.py:290]
_print [printer.py:257]
_print_Add [str.py:56]
_print [printer.py:257]
parenthesize [str.py:29]
_print_Mul [str.py:290]
_print [printer.py:257]
_print_Add [str.py:56]
_print [printer.py:257]
parenthesize [str.py:29]
_print_Mul [str.py:290]
_print [printer.py:257]
_print_Add [str.py:56]
_print [printer.py:257]
parenthesize [str.py:29]
_print_Mul [str.py:290]
_print [printer.py:257]
_print_Add [str.py:56]
_print [printer.py:257]
parenthesize [str.py:29]
_print_Mul [str.py:290]
_print [printer.py:257]
_print_Add [str.py:56]
_print [printer.py:257]
parenthesize [str.py:29]
_print_Mul [str.py:290]
_print [printer.py:257]
_print_Add [str.py:56]
_print [printer.py:257]
parenthesize [str.py:29]
_print_Mul [str.py:290]
_print [printer.py:257]
_print_Add [str.py:56]
_print [printer.py:257]
parenthesize [str.py:29]
_print_Mul [str.py:290]
_print [printer.py:257]
_print_Add [str.py:56]
_print [printer.py:257]
parenthesize [str.py:29]
_print_Mul [str.py:290]
_print [printer.py:257]
_print_Add [str.py:56]
_print [printer.py:257]
doprint [printer.py:233]
sstr [str.py:748]
__str__ [basic.py:396]
_getRoots_sympy_Poly_nroots [__init__.py:91]
getRoots [__init__.py:68]
findPolyRoots [__init__.py:697]
_getNroots [polefinder.py:97]
_doForN [polefinder.py:60]
_incN [polefinder.py:52]
__init__ [polefinder.py:39]
_doPoleFind [polefinderwrap.py:33]
_polesForPos [polefinderwrap.py:47]
<module> [polefinderwrap.py:60]
run [pydevd.py:937]
<module> [pydevd.py:1530]
好的,我的str函数有一个例外。似乎多项式可能变得太大了。
Traceback (most recent call last):
File "E:\Peter's Documents\PhD\Code\Git\ProtoQScat\multichannel\qscat\ratsmat.\polefinder.py", line 60, in _doForN
roots = self._getNroots(N)
File "E:\Peter's Documents\PhD\Code\Git\ProtoQScat\multichannel\qscat\ratsmat.\polefinder.py", line 97, in _getNroots
roots = ratSmat.findPolyRoots(False)
File "E:\Peter's Documents\PhD\Code\Git\ProtoQScat\multichannel\qscat\numerical/..\ratsmat\__init__.py", line 697, in findPolyRoots
roots = self.polyRootSolve.getRoots(mat, k)
File "E:\Peter's Documents\PhD\Code\Git\ProtoQScat\multichannel\qscat\numerical/..\ratsmat\__init__.py", line 68, in getRoots
ret = self._getRoots_sympy_Poly_nroots(mat, k)
File "E:\Peter's Documents\PhD\Code\Git\ProtoQScat\multichannel\qscat\numerical/..\ratsmat\__init__.py", line 91, in _getRoots_sympy_Poly_nroots
self.resultFileHandler.writeLogStr(str(deter))
File "C:\Python27\lib\site-packages\sympy\core\basic.py", line 396, in __str__
return sstr(self, order=None)
File "C:\Python27\lib\site-packages\sympy\printing\str.py", line 748, in sstr
s = p.doprint(expr)
File "C:\Python27\lib\site-packages\sympy\printing\printer.py", line 233, in doprint
return self._str(self._print(expr))
File "C:\Python27\lib\site-packages\sympy\printing\printer.py", line 257, in _print
return getattr(self, printmethod)(expr, *args, **kwargs)
File "C:\Python27\lib\site-packages\sympy\printing\str.py", line 56, in _print_Add
t = self._print(term)
File "C:\Python27\lib\site-packages\sympy\printing\printer.py", line 257, in _print
return getattr(self, printmethod)(expr, *args, **kwargs)
File "C:\Python27\lib\site-packages\sympy\printing\str.py", line 290, in _print_Mul
a_str = [self.parenthesize(x, prec) for x in a]
File "C:\Python27\lib\site-packages\sympy\printing\str.py", line 29, in parenthesize
return "(%s)" % self._print(item)
File "C:\Python27\lib\site-packages\sympy\printing\printer.py", line 257, in _print
return getattr(self, printmethod)(expr, *args, **kwargs)
File "C:\Python27\lib\site-packages\sympy\printing\str.py", line 56, in _print_Add
t = self._print(term)
File "C:\Python27\lib\site-packages\sympy\printing\printer.py", line 257, in _print
return getattr(self, printmethod)(expr, *args, **kwargs)
File "C:\Python27\lib\site-packages\sympy\printing\str.py", line 290, in _print_Mul
a_str = [self.parenthesize(x, prec) for x in a]
File "C:\Python27\lib\site-packages\sympy\printing\str.py", line 29, in parenthesize
return "(%s)" % self._print(item)
File "C:\Python27\lib\site-packages\sympy\printing\printer.py", line 257, in _print
return getattr(self, printmethod)(expr, *args, **kwargs)
File "C:\Python27\lib\site-packages\sympy\printing\str.py", line 56, in _print_Add
t = self._print(term)
File "C:\Python27\lib\site-packages\sympy\printing\printer.py", line 257, in _print
return getattr(self, printmethod)(expr, *args, **kwargs)
File "C:\Python27\lib\site-packages\sympy\printing\str.py", line 290, in _print_Mul
a_str = [self.parenthesize(x, prec) for x in a]
File "C:\Python27\lib\site-packages\sympy\printing\str.py", line 29, in parenthesize
return "(%s)" % self._print(item)
File "C:\Python27\lib\site-packages\sympy\printing\printer.py", line 257, in _print
return getattr(self, printmethod)(expr, *args, **kwargs)
File "C:\Python27\lib\site-packages\sympy\printing\str.py", line 69, in _print_Add
return sign + ' '.join(l)
MemoryError
编辑: 以下答案如下所示是具有行列式大小(通道)的剖面图。忽略N(在y轴上)它是计算的另一个参数(控制元素中多边形的大小)。
答案 0 :(得分:1)
算法很慢。
Sympy解释the Berkowitz method in its documentation,并引用"On computing the determinant in small parallel time using a small number of processors";为了实施,look at the open-source sympy code。
Berkowitz的复杂性很难理解,看起来如果你不想强行证明其正确性then you need to get involved in some pretty hairy combinatorics。
该算法适用于高度并行的体系结构;这主要是因为高斯椭球不能很好地进行分裂。正式地,它在class NC^2
。我猜可能你的测试没有在这样的架构上运行。一些研究人员使用算法seem to be contributors on CS.SE,如果您对该主题有更多疑问。
多项式通话很慢
From the docs,有多种构造多项式的方法,取决于传递给构造函数的集合类型(列表[1]
,元组[2]
或字典{{1} });它们导致不同的验证并且具有非常不同的性能。我会在文档中指出你的这个注释(强调我的,大写他们的):
对于交互式使用,请选择
[3]
,因为它安全且相对较快。注意:在内部使用
[1]
或[2]
时间关键算法 你知道系数和单项式将是有效的同情 表达式。谨慎使用它们!如果系数是整数 而不是同情整数(例如1而不是S(1))多项式将 如果您尝试打印,可能会遇到问题 多项式即可。如果单项式不是作为整数元组给出的 会有问题。
Sympy还保留在需要输出之前懒惰地评估表达式的权利。这是符号计算的一个重要部分 - 数学简化可以带来精确增益和性能提升,但也可能意味着复杂表达式的实际评估可能会延迟到意外时间。
答案 1 :(得分:0)
好的,所以我在阅读了文献和感觉(强调这里)之后回到了这里,Berkowitz应该在O(n ^ 2)和O(n ^ 3)之间执行。
我发现det和Poly的输入类型对性能有很大影响(我承认输入类型没有显示在我的问题中)。将多维数据集中的原始表达式包装可以显着提高性能。
考虑以下三个代码
1:使用MatrixSymbol。 det需要1.1s然后在30分钟后仍然停留在str上
tabLayout.setupWithViewPager(viewPager)
2:代表我原来的问题代码。 det需要1.8秒,然后在30分钟后仍然停留在Poly。
from sympy import MatrixSymbol, Matrix
X = MatrixSymbol('X', 10, 10)
Xmat = Matrix(X)
deter = Xmat.det(method='berkowitz')
str(deter)
3:高于import sympy
from sympy import Matrix, I
from sympy.polys import Poly
matSz = 10
m = Matrix([[0.0]*matSz]*matSz)
x = sympy.symbols('x')
for i in range(matSz):
for j in range(matSz):
m[i,j] = 2.0*float(i+1)*x**2 + 2.0*float(j+1)*x - 5.0*float(i+1)
deter = m.det(method='berkowitz')
deter_poly = Poly(deter, x) #Required or exception
roots = deter_poly.nroots()
。 det需要3.0s,Poly 0.04和nroots 0.27
m[i,j] = poly(