我正在使用 64 位 Python 3.3.1、pylab 和 32GB 系统 RAM。这个功能:
def sqrt2Expansion(limit):
x = Symbol('x')
term = 1+1/x
for _ in range(limit):
term = term.subs({x: (2+1/x)})
return term.subs({x: 2})
产生这种表达式:
1 + 1/(2 + 1/(2 + 1/(2 + 1/(2 + 1/(2 + 1/(...))))))
.调用时:
sqrt2Expansion(100)
返回有效结果,但 sqrt2Expansion(200)
生产 RuntimeError
有很多页的回溯并挂起 pylab/IPython 解释器,并且有大量系统内存未使用。任何想法如何更有效地实现它?我想调用sqrt2Expansion(1000)
仍然得到结果。
最佳答案
我将尝试详细说明我在上面发布的评论。
Sympy 表达式是树。每个操作都是一个节点,其操作数作为分支。例如 x+y
看起来像 Add(x, y)
和 x*(y+z)
喜欢 Mul(x, Add(y, z))
.
通常这些表达式会像 Add(x, Add(y, z))
一样自动变平。成为Add(x, y, z)
,但对于更复杂的情况,可以得到非常深的树。
深树可能会带来问题,尤其是当解释器或库本身限制允许的递归深度时(作为防止无限递归和爆炸性内存使用的保护)。这很可能是您的 RuntimeError
的原因。 : 每个 subs
使树更深,随着树的深入,递归 subs
必须多次调用自己,直到它到达最深的节点。
您可以将树简化为 polynomial/polynomial
的形式。通过使用 factor
具有恒定的深度方法。只需更改 term = term.subs({x: (2+1/x)})
至term = term.subs({x: (2+1/x)}).factor()
.
关于python-3.x - 长表达式使 SymPy 崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16390875/