python - 使用 sympy 反转函数并评估反转函数给了我一个错误的答案

标签 python sympy substitution inverse

我正在尝试反转函数并计算反转函数。基本上,我有等式:

y = 1 / f * ln(1+c*x) / x

其中 cf 是数值常量。在 python 中,我有以下代码来查找 x 作为 y 的函数,并为 y = 1.5 计算 x >:

import sympy as sp
import math

x, y_prime = sp.symbols("x y_prime", positive=True)
c = 10
f = math.log(1+c) - c/(1+c)
y = 1 / f * sp.log(1+c*x) / x
eqn = sp.Eq(y_prime, y)
sol_x = sp.solve(eqn, x, rational=False)[0]
print(sol_x.subs(y_prime, 1.5))

get 的输出是x=0,我知道这是错误的。另外,我在 Mathematica 中尝试了这个,在那里我得到了 x = 1.120173048953996,我知道这是正确的,因为在 y< 的表达式中坚持 x 的这个值 给出 y = 1.5。我想知道如何在 python 中获得正确答案。感谢您的帮助。

最佳答案

from sympy import *
var("f, c, x, y")
eq = Eq(y,  1 / f * log(1+c*x) / x)
sol = solve(eq, x)
print(sol[0])
# out: -LambertW(-f*y*exp(-f*y/c)/c)/(f*y) - 1/c

如您所见,有 Lambert W function ,它有两个分支:

enter image description here

SymPy 返回的解决方案由上面的分支(图中的蓝线)表示。对于这种情况,较低的(橙色)分支是正确的。

那么,让我们修改解决方案:

mod_sol = sol[0].replace(lambda t: isinstance(t, LambertW), lambda t: LambertW(*t.args, -1))
print(mod_sol)
# out: -LambertW(-f*y*exp(-f*y/c)/c, -1)/(f*y) - 1/c

现在我们可以评估它以找到 x:

import math
c_val = 10
f_val = math.log(1+c_val) - c_val/(1+c_val)

print(mod_sol.subs({f: f_val, c: c_val, y: 1.5}).n())
# out: 1.120173048954

编辑以满足评论:

I know what the end goal of the code sol[0].replace(lambda t: isinstance(t, LambertW), lambda t: LambertW(*t.args, -1)) is, but I'm struggling to understand how the code goes about to achieve that.

replace是一种“高级”方法,允许执行模式匹配操作。在此示例中,我向 replace 传递了以下参数:

  • lambda 函数形式的查询:lambda t: isinstance(t, LambertW)。 SymPy 将把这个查询应用于符号表达式中包含的每个对象; t 参数表示 sympy 正在查看的当前对象。如果找到匹配项,查询返回 True,否则返回 False。例如,SymPy 开始查看 sol[0](请查看上面的内容以了解此表达式的组成方式):

    • 一开始,t 将是 sol[0]sol[0] 是 Lambert W 函数吗?不是,因为 sol[0] 是两项的加法,其中一项包含 Lambert W 函数。那么,让我们继续吧。
    • 那么,t 将是 -1/c:它是 Lambert W 函数吗?显然不是,让我们继续。
    • t 将是 -LambertW(-f*y*exp(-f*y/c)/c)/(f*y)。它是 Lambert W 函数吗?不,它是一个乘法,其中一项是 Lambert W 函数。那么,让我们继续吧。
    • 最终,t 将成为 LambertW(-f*y*exp(-f*y/c)/c)。这是 Lambert W 函数吗?是的,所以查询函数返回 True
  • 返回替换对象的函数:lambda t: LambertW(*t.args, -1))。如果查询函数为某个对象返回 True,SymPy 将获取该对象并将其传递给替换函数。具体来说,我在这里创建了一个新的 Lambert W 函数,其参数与原始术语 t 相同,但我要求它考虑带有 -1 的下分支>.

In the future, if I come across the LambertW function, how do I know which branch gives the correct solution?

这是我第一次接触 Lambert W 函数。我看了维基百科,看到了两个分支,我明白某处一定有一个极限值。所以我绘制了 sol[0]mod_sol(见下图)。如您所见,直到 y ~ 6.5,下分支提供了正确的结果,之后必须考虑上分支。

enter image description here

关于python - 使用 sympy 反转函数并评估反转函数给了我一个错误的答案,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73598109/

相关文章:

python - Piecewise PYTHON 的傅里叶级数

python - 通过spyder运行sympy时摆脱黑色控制台窗口

regex - Sed 用另一个字符的多次重复替换一个字符的多次重复

algorithm - Maxima- 以更多算法方式进行符号变量替换

vim - 如何在 Vim 中高效地跨多个文件执行替换命令?

python - conda-forge 安装旧版本时如何升级

python - 基于另外 2 列 python pandas 乘以 df 的 2 个子集

python - 为什么三元迭代比递归慢 2 倍?

python - 如何修复Pygame减速后角色不断向两个方向加速的问题?

python - 使用Python对每个符号求解方程式(String)