微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

java – 如何处理科学计算中的下溢?

我正在研究概率模型,当对这些模型进行推理时,估计的概率可能变得非常小.为了避免下溢,我目前正在日志域中工作(我存储概率的日志).乘以概率等于一个加法,并且通过使用公式来求和:
log(exp(a) + exp(b)) = log(exp(a - m) + exp(b - m)) + m

其中m = max(a,b).

我使用一些非常大的矩阵,我必须采取这些矩阵的元素指数来计算矩阵向量乘法.这个步骤是相当昂贵的,我想知道是否有其他方法来处理下溢,当使用概率.

编辑:出于效率原因,我正在寻找使用原始类型的解决方案,而不是存储实数的任意精度表示的对象.

编辑2:我正在寻找比日志域技术更快的解决方案,而不是更准确的解决方案.我很高兴我目前得到的准确性,但我需要一个更快的方法.特别地,在矩阵向量乘法期间发生求和,并且我希望能够使用有效的BLAS方法.

解决方案:在与Jonathan Dursi进行讨论之后,我决定将每个矩阵和向量按其最大元素进行分解,并将该因子存储在日志域中.乘法是直接的.在添加之前,我必须按照两个因素的比例,将一个添加的矩阵/向量进行因式分解.我每十个操作更新一次.

解决方法

这个问题最近也在 computational science stack exchange site出现,尽管立即担心溢出,但问题或多甚少.

转换为日志空间当然是一个合理的方法.无论你身处何地,要正确地做大量的金额,你可以用几种方法来提高你的总和的准确性.补偿总结方法,最着名的是Kahan summation,保留了一个总和,有效地是“剩余”;它为您提供了使用更高精度的arithmeite而没有所有成本(并且仅使用原始类型)的一些优点.其余的术语也给你一些迹象表明你在做什么.

除了改善您的添加的实际力学外,更改添加条款的顺序可能会有很大的不同.排序您的条款,以便您从最小到最大的总和可以帮助,因为您不再添加非常不同的术语(可能会导致重大的roundoff问题);在某些情况下,做log2 N重复的成对总和也可以是一个改进,只是做直线性和,取决于你的术语是什么样子.

所有这些方法的有用性都取决于数据的属性.任意的精密数学库虽然在计算时间(可能是内存)使用上非常昂贵,但是具有相当一般的解决方案的优点.

原文地址:https://www.jb51.cc/java/124390.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐