我要评估以下公式:
c = exp{x}*erfc{y}
(请参见下面的代码中x
和y
的定义。)
问题在于x和y变得很大,exp{x}
的值很大,而erfc(y)
的值很小。
import numpy as np
import scipy as sci
k = 5.7e-3
D = 1.53e-8
R = 1.5e-5
r = 1e-6
t = np.linspace(0.0,12,10)
x = (r/R) + (D/(R*R) - k)*t
y = (r/(2*np.sqrt(D*t))) + np.sqrt(D*t)/R
exp_x = np.exp(x)
erfc_y = sci.special.erfc(y)
print("x = \n{} ".format(x))
print("y = \n{}".format(y))
print("exp(x) = \n{}".format(exp_x))
print("erfc(y) = \n{}".format(erfc_y))
print("exp(x) * erfc(y)= \n{}".format(exp_x*erfc_y))
我的想法是将评估更改为
log{exp(x)*erfc(y)} = log{exp(x)} + log{erfc(y)} = x + log{erfc(y)}
之后,我可以计算
exp(x + log{erfc(y)})
但这是问题所在: 当我想计算
log{erfc(y)} = log{1 - erfc(y)}
我遇到了类似的问题,即erfc将接近1,并且会遇到精度问题。
有什么办法可以解决我的问题吗?
答案 0 :(得分:1)
此问题的解决方案由Cadena在本文中给出:
Cadena,F。(1989)。 使用个人计算机解决污染物传输模型的数字方法。 《教育中的计算机》, 9(2),34-6。
我无法获得本文,但解决方案也由
给出 Lin,J.S.和Hildemann,L.M.(1995)。 一种非稳态分析模型,可预测垃圾填埋场中挥发性有机化合物的气体排放。有害物质杂志,40(3),271-295。 卡德纳提出用具有负幂项的另一个指数函数来近似互补误差函数。它减少了原始指数函数引起的高功率,从而导致溢出。假设W
是需要求值的乘法:
W=exp(y)*erfc(x)
W
可以近似为:
W = (a1*t+a2*t^2+a3*t^3+a4*t^4+a5*t^5)*exp(y-x^2), t=1/(1+p*x), if x >= 0
W = 2*exp(y)-(a1*t+a2*t^2+a3*t^3+a4*t^4+a5*t^5)*exp(y-|x|^2), t=1/(1+p*|x|), if x < 0
其中
a1 = 0.254829592
a2 = -0.284496736
a3 = 1.42141741
a4 = -1.453152027
a5 = 1.061405429
p = 0.3275911
答案 1 :(得分:0)
使用scipy.special.erfcx()
来得到exp(x**2)*erfc(x)
。
然后,您只需实现erfcx(x)*exp(x-x**2)
,它再次给出erfc(x)*exp(x)
。
如果您的论点为x=y
,这当然最有效。