【问题标题】:sympy.solve() doesn't give one of the solutions with LambertWsympy.solve() 没有给出 LambertW 的解决方案之一
【发布时间】:2018-04-13 13:16:58
【问题描述】:

背景:
我正在尝试实现一个执行inverse transform sampling 的函数。我使用 计算CDF 并得到它的反函数。虽然对于一些简单的PDFs 我得到正确的结果,但对于 CDF 的反函数包含Lambert-W function 的 PDF,结果是错误的。

示例:
考虑以下示例 CDF:

import sympy as sym

y = sym.Symbol('y')
cdf = (-y - 1) * sym.exp(-y) + 1  # derived from `pdf = x * sym.exp(-x)`
sym.plot(cdf, (y, -1, 5))


现在计算这个函数的逆:

x = sym.Symbol('x')
inverse = sym.solve(sym.Eq(x, cdf), y)
print(inverse)

输出:

[-LambertW((x - 1)*exp(-1)) - 1]

事实上,这只是给定 CDF 的负 y 的左分支:

sym.plot(inverse[0], (x, -0.5, 1))

问题: 如何获得给定 CDF 的正 y 的正确分支?

我尝试了什么:

  1. xy 指定为仅是正数:

    x = sym.Symbol('x', positive=True)
    y = sym.Symbol('y', positive=True)
    

    这没有任何影响,即使对于第一个 CDF 图。

  2. 使 CDF 成为 Piecewise 函数:

    cdf = sym.Piecewise((0, y < 0),
                        ((-y - 1) * sym.exp(-y) + 1, True))
    

    再次没有效果。这里奇怪的是,在另一台计算机上绘制这个函数给出了一个正确的图形,负 y 为零,但求解正 y 分支在任何地方都不起作用。 (不同的版本?我还必须将adaptive=False 指定为sympy.plot 才能让它在那里工作。)

  3. 使用sympy.solveset 代替sympy.solve
    结果,这只会产生无用的ConditionSet(y, Eq(x*exp(y) + y - exp(y) + 1, 0), Complexes(S.Reals x S.Reals, False))。显然,solveset 仍然不知道如何处理LambertW 函数。来自文档:

    当案件没有解决或只能不完全解决时, ConditionSet 用作未评估的求解集对象。 <...> 还有几件事solveset做不到,老的solve 可以,比如求解非线性多元& LambertW类型 方程。

这是一个错误还是我错过了什么?是否有任何解决方法可以获得所需的结果?

【问题讨论】:

标签: sympy python sympy solver inverse


【解决方案1】:

sympy 产生的逆几乎是正确的。问题在于 LambertW 函数在域 (-1/e, 0) 上有多个分支。默认情况下,它使用上分支,但是对于您的问题,您需要下分支。可以通过向 LambertW 传递值为 -1 的第二个参数来访问较低的分支。

inverse = -sym.LambertW((x - 1)*sym.exp(-1), -1) - 1
sym.plot(inverse, (x, 0, 0.999))

给予

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-30
    相关资源
    最近更新 更多