使用scipy.stats正常cdf时Sympy TypeError

Joh*_*Doe 0 python sympy scipy

为什么Sympy在使用时会抛出Type错误scipy.stats.norm?我怎样才能解决这个问题?

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))
Run Code Online (Sandbox Code Playgroud)

输出:

TypeError: cannot determine truth value of Relational
Run Code Online (Sandbox Code Playgroud)

小智 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)
Run Code Online (Sandbox Code Playgroud)

请注意,我把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)
Run Code Online (Sandbox Code Playgroud)

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

数字解决方案

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

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
Run Code Online (Sandbox Code Playgroud)

答案是0.33622392.