【发布时间】:2018-04-13 13:16:58
【问题描述】:
背景:
我正在尝试实现一个执行inverse transform sampling 的函数。我使用sympy 计算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 的正确分支?
我尝试了什么:
-
将
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代替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类型 方程。
这是一个错误还是我错过了什么?是否有任何解决方法可以获得所需的结果?
【问题讨论】:
-
一个长期存在的issue with solve。像这样的问题推动了
solveset的发展,但它还没有达到与solve相同的功能,尤其是LambertW solutions are not implemented in solveset。
标签: sympy python sympy solver inverse