为什么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
答案 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。