使用scipy.stats时的Sympy TypeError正常cdf

时间:2018-01-06 19:28:53

标签: python scipy sympy

为什么Sympy在使用scipy.stats.norm时会抛出Type错误?我该如何解决这个等式?

from sympy import Eq, Symbol, solve, Piecewise
from scipy.stats import norm
import numpy as np

x = Symbol('x')
eqn = Eq((x-0.2)/0.3, norm.cdf((np.log(100/110) + x**2/2)/x))

print(solve(eqn))

输出:

TypeError: cannot determine truth value of Relational

1 个答案:

答案 0 :(得分:5)

符号设置

如果您正在寻找符号解决方案,请使用符号功能:例如,SymPy的日志不是NumPy的日志。正常的CDF也可以从SymPy的统计模块中获得cdf(Normal("x", 0, 1))。正确的SymPy设置如下:

from sympy import Eq, Rational, Symbol, log
from sympy.stats import cdf, Normal
eqn = Eq((x-Rational('0.2'))/Rational('0.3'), cdf(Normal("x", 0, 1))(log(Rational(100, 110)) + x**2/2)/x)

请注意,我将Rational('0.2')放在0.2的位置。有理数和浮点数之间的区别对于符号数学很重要。从形式上来看,这个等式看起来很好:

Eq(10*x/3 - 2/3, (erf(sqrt(2)*(x**2/2 - log(11) + log(10))/2)/2 + 1/2)/x)

不幸的是,它看起来也毫无希望:对于像这样的东西没有封闭形式的解决方案,涉及一个等同于多项式的超越函数。当然,solve(eqn)会失败。因此,上述所有内容都证明了SymPy的正确使用,但它并没有改变没有符号解决方案的事实。

数字解决方案

要以数字方式解决这个问题,请执行相反的操作:删除SymPy部件并从SciPy导入fsolve

from scipy.stats import norm
from scipy.optimize import fsolve
import numpy as np

f = lambda x: (x-0.2)/0.3 - norm.cdf((np.log(100/110) + x**2/2)/x)
print(fsolve(f, 1))   # 1 is a random initial guess

答案是0.33622392。