Python 在exp()中使用符号时,Symphy解算器内存不足

Python 在exp()中使用符号时,Symphy解算器内存不足,python,sympy,Python,Sympy,我正在尝试学习如何使用Symphy,所以我选择了一个简单的问题来尝试。当我尝试使用Symphy的解算器求解e^(-ln(2)/8)*t)-10^-6时,我的repl最终崩溃,出现内存不足错误。这似乎与它如何解释exp()方法有关,我不太确定我做错了什么 从数学导入日志作为ln 从sympy导入exp为e,符号为sym,求解 t=sym('t') hl=8.0197 k=ln(2)/hl#lambda 表达式=e(-k*t)-10**-6 #10^6=e^(-k*t) 天数=求解(,t) 打印(天

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

从数学导入日志作为ln
从sympy导入exp为e,符号为sym,求解
t=sym('t')
hl=8.0197
k=ln(2)/hl#lambda
表达式=e(-k*t)-10**-6
#10^6=e^(-k*t)
天数=求解(,t)
打印(天)

它应该解到~159.5,但如前所述,它会导致repl崩溃。对于由信号SIGSEGV(地址边界错误)终止的
“ipython3”
10**-6
是一个可疑的小数字

由于浮点数是安全的,我们可以使用漂亮、安全的整数解决与您提出的问题类似的问题:

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)]
所以我们马上就知道这个问题与浮点数的使用有关。事实证明,这是一个很好的例子。请注意,由于方程有四种可能的解,因此处理浮点数所需的工作量是原来的四倍

由于使用浮点数会导致错误,特别是当数字的动态范围较大时,Symphy会将浮点输入转换为精确的分数表示。这可能会导致非常大的数字,从而降低计算速度

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

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

“令人怀疑的小”是什么意思?@alec_a:诸如
10^-6
之类的值通常在代码中显示为对浮点问题的规避或保护措施。即使在这些上下文之外使用,它们也可能导致问题。在这种情况下,两个常数之间有六个数量级。由于代码在其他方面似乎合理,所以高动态范围使我怀疑是浮点问题。