【问题标题】:c++: strategies for stability of floating point arithmeticc++:浮点运算稳定性的策略
【发布时间】:2012-06-29 15:56:06
【问题描述】:

谁能推荐任何包含维护各种浮点运算稳定性的策略的 C++ 库/例程/包?

示例:假设您想在单位间隔 (0,1) 内对一百万个long double 的向量/数组求和,并且每个数字的数量级大致相同。天真地求和 for (int i=0;i<1000000;++i) sum += array[i]; 是不可靠的 - 对于足够大的 isum 将比 array[i] 大得多,因此 sum += array[i] 将等效于 sum += 0.00。 (注意:这个例子的解决方案是二元求和策略。)

我处理数千/数百万个微小概率的总和和乘积。我正在使用具有 2048 位有效位的任意精度库 MPFRC++,但同样的问题仍然适用。

我主要关心:

  1. 精确求和多个数字的策略(例如上面的示例)。
  2. 什么时候乘法和除法可能不稳定? (如果我想对大量数字进行归一化,我的归一化常数应该是多少?最小值?最大值?中位数?)

【问题讨论】:

    标签: c++ math floating-accuracy stability numerical-stability


    【解决方案1】:

    二进制求和不能保证准确的结果。最可靠(尽管速度较慢)的方法是使用Kahan summationBoost.Accumulators 实现了上述以及更多。

    乘法和除法稳定性:除非您使用非规范化浮点数,否则它们不会遇到与求和和减法相同的问题。实际上乘法的误差最多 0.5 ulp(单位最后一位)。

    ...我的归一化常数应该是多少?

    “标准化”是什么意思?这取决于您使用的norm。可能的候选者:使用数组中的最大绝对值,或任何其他广义平均值。 (您列出的其他选项不起作用,因为即使对于非零数组,它们也可能为零。)

    【讨论】:

    • 通过“标准化”,我的意思是:在第 X 步,我有一组微小但非零的概率。在第 X+1 步,我将把这些数字乘以更小的概率。根据我的数学模型的详细信息,我可以将步骤 X 的数字乘以任何常数(即归一化),然后再转到步骤 X+1。这具有帮助避免下溢的实际好处。
    • @CycoMatto:那么你应该偶尔乘以 2 的幂。避免下溢/上溢的唯一方法是保证最大和最小数字之间的比率可以用手头的浮点数表示(如果不是,你什么也做不了)。
    • 或者存储它们的对数并使用求和。但不能说这种方法的稳定性。
    • 为什么是 2 的幂?目前,我在第 X 步乘以最小数字的倒数 - 这样,数字都 >= 1。在第 X+1 步乘以概率将“将数字拖回 0”。对吗?
    • @CycoMatto:乘以或除以 2 的幂根本不会降低准确性。我只想指出,如果您担心下溢,并且按照您的描述对其进行规范化,那么您还必须考虑规范化期间可能出现的溢出。
    猜你喜欢
    • 2018-07-01
    • 1970-01-01
    • 2012-12-15
    • 2010-12-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多