遇到溢出:exp()乘以erfc()

时间:2019-01-15 10:04:46

标签: python numpy scipy

我要评估以下公式:

c = exp{x}*erfc{y}

(请参见下面的代码中xy的定义。)

问题在于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,并且会遇到精度问题。

有什么办法可以解决我的问题吗?

2 个答案:

答案 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,这当然最有效。