use*_*772 5 python numpy underflow numerical-analysis numerical-methods
我正在尝试计算以下比率:
使用指数递减函数更新w(i) / (sum(w(j))
其中,即作为正参数。所有数字都是非负数。然后将该比率用于公式(乘以一个常数并添加另一个常数)。正如预期的那样,我很快就遇到了下溢问题。w
w(i) = w(i) * exp(-k)
k
我想这种情况经常发生,但是有人可以给我一些关于如何处理这个问题的参考吗?我没有找到合适的转换,所以我尝试做的一件事是将一些最小正数设置为安全阈值,但我没有设法找到哪个是最小正浮点数(我代表 中的数字numpy.float128
)。我怎样才能在我的机器上真正获得这样的最小正数?代码如下所示:
w = np.ones(n, dtype='float128')
lt = np.ones(n)
for t in range(T):
p = (1-k) * w / w.sum() + (k/n)
# Process a subset of the n elements, call it set I, j is some range()
for i in I:
s = p[list(j[i])].sum()
lt /= s
w[s] *= np.exp(-k * lt)
Run Code Online (Sandbox Code Playgroud)
其中 k 是 (0,1) 中的某个常数,n 是数组的长度
当处理指数较小的数字时,通常最好在日志空间中工作。例如,log(w*exp(-k)) = log(w) - k
,不会有任何上溢/下溢问题,除非 k 本身呈指数级大或 w 为零。并且,如果w
为零,numpy 将正确返回-inf
。然后,在求和时,取出最大的项:
log_w = np.log(w) - k
max_log_w = np.max(log_w)
# Individual terms in the following may underflow, but then they wouldn't
# contribute to the sum anyways.
log_sum_w = max_log_w + np.log(np.sum(np.exp(log_w - max_log_w)))
log_ratio = log_w - log_sum_w
Run Code Online (Sandbox Code Playgroud)
这可能并不完全是您想要的,因为您可以完全分解出k
(假设它是一个常量而不是一个数组),但它应该可以让您上路。
scikit-learn实现了与 类似的东西extmath.logsumexp
,但是和上面的基本一样。