使用 SymPy 评估正态分布的 CDF 时出错

Error when evaluating the CDF of normal distribution with SymPy

我想使用 SymPy 正态分布,因为我用它做了一些符号计算。

from sympy.stats import Normal, cdf
from scipy.stats import norm

norm.cdf(10, 10, 0.1)

def survival(x):
    y = Normal("x", 10, 0.1)
    return cdf(y)(x)

survival(10)

此代码产生以下错误:

UnboundLocalError: local variable 'reprec' referenced before assignment

请注意,通过以下调整似乎有效:

return cdf(y, meijerg=False)(x)

有人可以解释这种行为吗?

总分:

  1. SymPy 统计模块有一些改进的空间。特别是,文档承认 CDF 从 simplify 返回正常随机变量 "needs some help" 变得可用。
  2. 浮点数,尤其是那些在二进制系统中不能精确表示的数,是 SymPy 的毒药。您认为您传递的是 0.1,但它实际上是 3602879701896397/36028797018963968 并且符号积分例程很合适。

关于第一点;以下示例表明 cdf(x)(t) 是一个有风险的命题。

>>> x = Normal('x', 1, 1)
>>> cdf(x)(1)
nan

问题是未简化的 cdf 除以 _z-1。更好的方法:

>>> simplify(cdf(x))(1)
1/2 

关于第二个:由于 CDF 是通过符号积分计算的,将浮点数作为参数传递会使积分器的工作变得非常困难,以至于它使用 Meijer G 函数进行积分时会遇到一些隐藏得很深的错误。使用 Rational(1, 10)S(1)/10 创建有理数 1/10 而不是小数 0.1。

>>> from sympy import S
>>> x = Normal("x", 10, S(1)/10)
>>> simplify(cdf(x))(10)
1/2