Python 尝试积分时指数函数溢出
我想数值积分一个离散数据集(给定的ad系列)-这里是橙色-它与给定的分析指数函数(费米-狄拉克分布的导数)-这里是蓝色-相乘。然而,当指数变大时(例如对于小T),我失败了,因此导数Python 尝试积分时指数函数溢出,python,numpy,scipy,integer-overflow,Python,Numpy,Scipy,Integer Overflow,我想数值积分一个离散数据集(给定的ad系列)-这里是橙色-它与给定的分析指数函数(费米-狄拉克分布的导数)-这里是蓝色-相乘。然而,当指数变大时(例如对于小T),我失败了,因此导数fermi_dT(e,mu,T)爆炸。我找不到一个合适的方法来重写费米dT(E,mu,t) 下面是一个最小的例子(不是熊猫系列),我用高斯函数模拟了数据集 如果T这种数值问题在处理指数导数时非常常见。诀窍是首先计算日志,然后应用指数: log(a*exp(b)/(1+c*exp(d))**k)=log(a)+b-k*l
fermi_dT(e,mu,T)
爆炸。我找不到一个合适的方法来重写费米dT(E,mu,t)
下面是一个最小的例子(不是熊猫系列),我用高斯函数模拟了数据集
如果T这种数值问题在处理指数导数时非常常见。诀窍是首先计算日志,然后应用指数:
log(a*exp(b)/(1+c*exp(d))**k)=log(a)+b-k*log(1+exp(log(c)+d))
现在,您需要找到一种方法来精确计算log(1+exp(x))
。根据这篇文章,你很幸运,人们以前做过。因此,也许您可以使用log1p
重写fermi_dT
:
import numpy as np
def softplus(x, limit=30):
val = np.empty_like(x)
val[x>=limit] = x[x>=limit]
val[x<limit] = np.log1p(np.exp(x[x<limit]))
return val
def fermi_dT(E, mu, T):
a = (E - mu) / (kB * T ** 2)
b = d = (E - mu) / (kB * T)
k = 2
val = np.empty_like(E)
val[E-mu>=0] = np.exp(np.log(a[E-mu>=0]) + b[E-mu>=0] - k * softplus(d[E-mu>=0]))
val[E-mu<0] = -np.exp(np.log(-a[E-mu<0]) + b[E-mu<0] - k * softplus(d[E-mu<0]))
return val
将numpy导入为np
def softplus(x,极限=30):
val=np.空的_样(x)
val[x>=限制]=x[x>=限制]
val[x=0])+b[E-mu>=0]-k*softplus(d[E-mu>=0]))
val[E-muLooks好像我的公式出了问题。我正在做。这很好!我试图重新缩放exp(x)或试图将exp(x)转换为exp(-x)。但这很好。你确定它有效吗?似乎是错的。我更新了我的答案,但我仍然不相信…tensorflow是否实现了所谓的softplus函数log(1+exp(x))
供参考。本主题的a部分。仅供参考:您也可以使用np.logaddexp(0,x)
进行log(1+exp(x))
。
import numpy as np
def softplus(x, limit=30):
val = np.empty_like(x)
val[x>=limit] = x[x>=limit]
val[x<limit] = np.log1p(np.exp(x[x<limit]))
return val
def fermi_dT(E, mu, T):
a = (E - mu) / (kB * T ** 2)
b = d = (E - mu) / (kB * T)
k = 2
val = np.empty_like(E)
val[E-mu>=0] = np.exp(np.log(a[E-mu>=0]) + b[E-mu>=0] - k * softplus(d[E-mu>=0]))
val[E-mu<0] = -np.exp(np.log(-a[E-mu<0]) + b[E-mu<0] - k * softplus(d[E-mu<0]))
return val