在exp()中使用符号时,sympy求解器的内存不足

时间:2019-04-30 22:06:39

标签: python sympy

我正在尝试学习如何使用sympy,因此我选择了一个简单的问题来尝试。当我尝试使用Sympy的求解器来解决e^(-(ln(2)/8) * t) - 10^-6时,我的repl最终因内存不足错误而崩溃。它似乎与如何解释exp()方法有关,我不太确定自己在做什么错。

from math import log as ln
from sympy import exp as e, symbols as sym, solve

t = sym('t')
hl = 8.0197
k = ln(2)/hl #lambda 
expression = e(-k * t) -10**-6

# 10^6 = e^(-k * t)
days = solve(,t)
print(days)

应该可以解决159.5,但是如前所述,它会导致repl崩溃。与“ipython3” terminated by signal SIGSEGV (Address boundary error)

1 个答案:

答案 0 :(得分:2)

10**-6是一个可疑的小数字。

由于浮点数为scary,因此我们可以使用美观,安全的整数解决与您提出的问题类似的问题:

from math import log as ln
import sympy
from sympy import symbols as sym

t  = sym('t')
hl = 8.0197
k  = 4
expression = sympy.exp(-k * t) - 3

days = sympy.solve(expression,t)
print(days)

这立即返回:

[log(3**(3/4)/3) + I*pi, log(3**(3/4)/3), log(-3**(3/4)*I/3), log(3**(3/4)*I/3)]

因此,我们立即知道问题与浮点数的使用有关。事实证明,这是SymPy中的known problem。请注意,由于该方程有四种可能的解决方案,因此处理浮点数所需的工作却翻了两番。

由于使用浮点数会导致lost precision,特别是如果数字的动态范围很大,SymPy会将浮点输入转换为精确的小数表示形式。这会导致很大的数字,使计算速度变慢。

解决方案是在可能的情况下避免浮点数,更一般地,以符号方式求解方程式,然后替换:

from math import log as ln
import sympy
from sympy import symbols as sym

t = sym('t')
k = sym('k')
c = sym('c')
expression = sympy.exp(-k * t) - c

days = sympy.solve(expression,t)
print(days)

这给出了:

[log(1/c)/k]

可以使用以下哪个进行评估

hl   = 8.0197
kval = ln(2)/hl #lambda 
days[0].subs([(k,kval), (c, 10**-6)])

给出

159.845200455409