我正在尝试反转函数并计算反转函数。基本上,我有等式:
y = 1 / f * ln(1+c*x) / x
其中 c
和 f
是数值常量。在 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 ,它有两个分支:
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
,下分支提供了正确的结果,之后必须考虑上分支。
关于python - 使用 sympy 反转函数并评估反转函数给了我一个错误的答案,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73598109/