sympy.solve() 没有给出 LambertW 的解决方案之一
sympy.solve() doesn't give one of the solutions with LambertW
背景:
我正在尝试实现一个执行 inverse transform sampling. I use sympy for calculating CDF and getting its inverse function. While for some simple PDFs I get correct results, for a PDF which CDF's inverse function includes Lambert-W function 的函数,结果是错误的。
示例:
考虑以下示例 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 的正确分支?
我试过的:
指定x
和y
只为正:
x = sym.Symbol('x', positive=True)
y = sym.Symbol('y', positive=True)
这没有任何效果,即使对于第一个 CDF 图也是如此。
使 CDF 成为 Piecewise
函数:
cdf = sym.Piecewise((0, y < 0),
((-y - 1) * sym.exp(-y) + 1, True))
同样无效。奇怪的是,在另一台计算机上绘制此函数给出了一个正确的图形,其中负 y 为零,但求解正 y 的分支在任何地方都不起作用。 (不同的版本?我还必须指定 adaptive=False
到 sympy.plot
才能在那里工作。)
使用sympy.solveset
instead of sympy.solve
:
结果只是给出了一个无用的 ConditionSet(y, Eq(x*exp(y) + y - exp(y) + 1, 0), Complexes(S.Reals x S.Reals, False))
。显然,solveset
仍然不知道如何处理 LambertW
函数。来自文档:
When cases which are not solved or can only be solved incompletely, a
ConditionSet
is used and acts as an unevaluated solveset object. <...>
There are still a few things solveset
can’t do, which the old solve
can, such as solving non linear multivariate & LambertW type
equations.
这是一个错误还是我遗漏了什么?是否有任何解决方法来获得所需的结果?
sympy 生成的逆函数几乎是正确的。问题在于 LambertW 函数在域 (-1/e, 0) 上有多个分支。默认情况下,它使用上分支,但是对于您的问题,您需要下分支。可以通过将第二个参数传递给值为 -1 的 LambertW 来访问下分支。
inverse = -sym.LambertW((x - 1)*sym.exp(-1), -1) - 1
sym.plot(inverse, (x, 0, 0.999))
给予
背景:
我正在尝试实现一个执行 inverse transform sampling. I use sympy for calculating CDF and getting its inverse function. While for some simple PDFs I get correct results, for a PDF which CDF's inverse function includes Lambert-W function 的函数,结果是错误的。
示例:
考虑以下示例 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 的正确分支?
我试过的:
指定
x
和y
只为正:x = sym.Symbol('x', positive=True) y = sym.Symbol('y', positive=True)
这没有任何效果,即使对于第一个 CDF 图也是如此。
使 CDF 成为
Piecewise
函数:cdf = sym.Piecewise((0, y < 0), ((-y - 1) * sym.exp(-y) + 1, True))
同样无效。奇怪的是,在另一台计算机上绘制此函数给出了一个正确的图形,其中负 y 为零,但求解正 y 的分支在任何地方都不起作用。 (不同的版本?我还必须指定
adaptive=False
到sympy.plot
才能在那里工作。)使用
sympy.solveset
instead ofsympy.solve
:
结果只是给出了一个无用的ConditionSet(y, Eq(x*exp(y) + y - exp(y) + 1, 0), Complexes(S.Reals x S.Reals, False))
。显然,solveset
仍然不知道如何处理LambertW
函数。来自文档:When cases which are not solved or can only be solved incompletely, a
ConditionSet
is used and acts as an unevaluated solveset object. <...> There are still a few thingssolveset
can’t do, which the oldsolve
can, such as solving non linear multivariate & LambertW type equations.
这是一个错误还是我遗漏了什么?是否有任何解决方法来获得所需的结果?
sympy 生成的逆函数几乎是正确的。问题在于 LambertW 函数在域 (-1/e, 0) 上有多个分支。默认情况下,它使用上分支,但是对于您的问题,您需要下分支。可以通过将第二个参数传递给值为 -1 的 LambertW 来访问下分支。
inverse = -sym.LambertW((x - 1)*sym.exp(-1), -1) - 1
sym.plot(inverse, (x, 0, 0.999))
给予