lambdified sympy 表达式 returns 不正确的结果
lambdified sympy expression returns incorrect result
我遇到了以下问题,我先简单解释一下是怎么回事:
f(x)
g(x, y) = f(x) - y
从那里我们期待
g(x, f(x)) = f(x) - f(x) = 0
lambdified g(x,y)
returns 非常接近零而不是零的东西。这是重现问题的代码。只有当我在 f(x)
中输入足够数量的 log
评价时它才会出现
要点:https://gist.github.com/marekyggdrasil/39a24213ebaba6293464d116821cc334
来源:
from sympy import Symbol, pprint, log, lambdify
# setting symbols
g1 = Symbol("gamma1")
g2 = Symbol("gamma2")
g3 = Symbol("gamma3")
g4 = Symbol("gamma4")
rt = Symbol("rt")
# setting expressions
criteria = (g1 * log(g1, 2.0))/2.0
criteria += (g2 * log(g2, 2.0))/2.0
criteria += (g3 * log(g3, 2.0))/2.0
criteria += (g4 * log(g4, 2.0))/2.0
rooteq = criteria - rt
print "\ncriteria function: "
pprint(criteria)
print "\ncriteria function - rt: "
pprint(rooteq)
# lambdifying expressions to callable functions
tsymbols = [g1, g2, g3, g4, rt]
lambfun_criteria = lambdify(tsymbols, criteria)
lambfun_rooteq = lambdify(tsymbols, rooteq)
# example point x
x = [0.25006462253641376, 2.2501938662000542, 2.2501938662000542, 2.2501938662000542, 0.0]
# evaluating of criteria on x
rootval = lambfun_criteria(*x)
# setting rt to this evaluation
x[4] = rootval
print "\nactual evaluation of rooteq: " + str(lambfun_rooteq(*x))
print "\nexpected evaluation of rooteq: " + str(- x[4] + lambfun_criteria(*x))
产出
$ python lambdifytest.py
criteria function:
0.721347520444482⋅γ₁⋅log(γ₁) + 0.721347520444482⋅γ₂⋅log(γ₂) + 0.721347520444482⋅γ₃⋅log(γ₃) + 0.721347520444482⋅γ₄⋅log(γ₄)
criteria function - rt:
0.721347520444482⋅γ₁⋅log(γ₁) + 0.721347520444482⋅γ₂⋅log(γ₂) + 0.721347520444482⋅γ₃⋅log(γ₃) + 0.721347520444482⋅γ₄⋅log(γ₄) - rt
actual evaluation of rooteq: 4.4408920985e-16
expected evaluation of rooteq: 0.0
我发现当 SymPy
表达式被 lambdified 时,可以指定自定义数学模块。就我而言 mpmath
有帮助。
导入 mpmath
并将精度设置为您认为足够的值
from mpmath import mp
mp.dps = 15
告诉 SymPy 你希望你的 lambda 函数使用 mpmath
来处理浮点运算
lambfun_criteria = lambdify(tsymbols, criteria, "mpmath")
lambfun_rooteq = lambdify(tsymbols, rooteq, "mpmath")
然后我终于得到了输出
actual evaluation of rooteq: 0.0
expected evaluation of rooteq: 0.0
问题的原因如下,创建的 lambda 函数中使用的默认浮点运算与比较结果的脚本中使用的不同。
如果有人需要,我用完整的解决方案文件更新了要点copy-paste
编辑:忘记提供文档参考
我遇到了以下问题,我先简单解释一下是怎么回事:
f(x)
g(x, y) = f(x) - y
从那里我们期待
g(x, f(x)) = f(x) - f(x) = 0
lambdified g(x,y)
returns 非常接近零而不是零的东西。这是重现问题的代码。只有当我在 f(x)
log
评价时它才会出现
要点:https://gist.github.com/marekyggdrasil/39a24213ebaba6293464d116821cc334
来源:
from sympy import Symbol, pprint, log, lambdify
# setting symbols
g1 = Symbol("gamma1")
g2 = Symbol("gamma2")
g3 = Symbol("gamma3")
g4 = Symbol("gamma4")
rt = Symbol("rt")
# setting expressions
criteria = (g1 * log(g1, 2.0))/2.0
criteria += (g2 * log(g2, 2.0))/2.0
criteria += (g3 * log(g3, 2.0))/2.0
criteria += (g4 * log(g4, 2.0))/2.0
rooteq = criteria - rt
print "\ncriteria function: "
pprint(criteria)
print "\ncriteria function - rt: "
pprint(rooteq)
# lambdifying expressions to callable functions
tsymbols = [g1, g2, g3, g4, rt]
lambfun_criteria = lambdify(tsymbols, criteria)
lambfun_rooteq = lambdify(tsymbols, rooteq)
# example point x
x = [0.25006462253641376, 2.2501938662000542, 2.2501938662000542, 2.2501938662000542, 0.0]
# evaluating of criteria on x
rootval = lambfun_criteria(*x)
# setting rt to this evaluation
x[4] = rootval
print "\nactual evaluation of rooteq: " + str(lambfun_rooteq(*x))
print "\nexpected evaluation of rooteq: " + str(- x[4] + lambfun_criteria(*x))
产出
$ python lambdifytest.py
criteria function:
0.721347520444482⋅γ₁⋅log(γ₁) + 0.721347520444482⋅γ₂⋅log(γ₂) + 0.721347520444482⋅γ₃⋅log(γ₃) + 0.721347520444482⋅γ₄⋅log(γ₄)
criteria function - rt:
0.721347520444482⋅γ₁⋅log(γ₁) + 0.721347520444482⋅γ₂⋅log(γ₂) + 0.721347520444482⋅γ₃⋅log(γ₃) + 0.721347520444482⋅γ₄⋅log(γ₄) - rt
actual evaluation of rooteq: 4.4408920985e-16
expected evaluation of rooteq: 0.0
我发现当 SymPy
表达式被 lambdified 时,可以指定自定义数学模块。就我而言 mpmath
有帮助。
导入 mpmath
并将精度设置为您认为足够的值
from mpmath import mp
mp.dps = 15
告诉 SymPy 你希望你的 lambda 函数使用 mpmath
来处理浮点运算
lambfun_criteria = lambdify(tsymbols, criteria, "mpmath")
lambfun_rooteq = lambdify(tsymbols, rooteq, "mpmath")
然后我终于得到了输出
actual evaluation of rooteq: 0.0
expected evaluation of rooteq: 0.0
问题的原因如下,创建的 lambda 函数中使用的默认浮点运算与比较结果的脚本中使用的不同。
如果有人需要,我用完整的解决方案文件更新了要点copy-paste
编辑:忘记提供文档参考