【问题标题】:How to 'checksum' an array of noisy floating point numbers?如何“校验和”一组嘈杂的浮点数?
【发布时间】:2012-03-19 01:09:04
【问题描述】:

什么是“校验和”浮点数数组的快速简便方法,同时允许指定的少量不准确?

例如我有两种算法应该(理论上,具有无限精度)输出相同的数组。但是它们的工作方式不同,因此浮点错误的累积方式也不同,尽管数组长度应该完全相同。我想要一种快速简便的方法来测试数组是否相同。我当然可以成对比较数字,并报告最大误差;但是一种算法在 C++ 中,另一种在 Mathematica 中,我不希望将数字写入文件或将它们从一个系统粘贴到另一个系统。这就是为什么我想要一个简单的校验和。

我可以简单地将数组中的所有数字相加。如果数组长度为 N,并且我可以容忍每个数字中的错误为 0.0001,那么我会检查 abs(sum1-sum2)<0.0001*N。但是这种简单的“校验和”并不可靠,例如一个条目中的错误为+10,另一条目中的错误为-10。 (无论如何,概率论说错误可能会像 sqrt(N) 一样增长,而不是像 N。)当然,任何校验和都是数据块的低维摘要,因此它会错过 一些 错误,如果不是大多数的话……但简单的校验和对于查找非恶意错误类型的错误仍然很有用。

或者我可以创建一个二维校验和,[sum(x[n]), sum(abs(x[n]))]。但这是我能做的最好的吗,即我可能会使用与sum(x[n])“更正交”的不同功能吗?如果我使用了一些任意函数,例如[sum(f1(x[n])), sum(f2(x[n]))],那么我的“原始容错”应该如何转化为“校验和容错”?

我正在使用 C++ 编程,但我很高兴看到任何语言的答案。

【问题讨论】:

  • 这不是校验和的目的。校验和用于确定位精确性,而不是用于容差测试。
  • 有趣的问题。您是否考虑过傅里叶变换数据,可能与低通滤波结合使用?
  • @Oli:我的问题清楚地表明了我在寻找什么,我不知道我想要什么更好的词。如果您知道更好的词,请告诉我,我会改用它。目前,我已将单词校验和放在引号中。
  • 我相信你所寻求的是不可能的,因为空间的维度是不同的。 (当您将 n 维空间映射到较小维空间时,您会“丢失信息”。)即使是一组整数的校验和也只能保证不同的校验和 => 不同的集合,反之亦然。 tlb 的建议可能与您在实践中得到的一样好。
  • 我知道校验和会丢失信息。我已经编辑了问题以使其更清楚。尽管如此,校验和作为对愚蠢错误的第一次检查很有用,我想要具有相同属性的东西。

标签: testing encoding floating-point error-correction


【解决方案1】:

我有一种感觉,你想要的东西可能通过gray codes 之类的东西成为可能。如果您可以将您的值转换为格雷码并使用某种能够纠正 n 位的校验和,您可以检测这两个数组是否相同,除了 n-1 位错误,对吗? (每一位错误意味着一个数字“减一”,其中映射将使得这是最低有效数字的变化)。

但确切的细节超出了我的范围 - 特别是浮点值。

我不知道它是否有帮助,但格雷码解决的是病理四舍五入的问题。四舍五入听起来会解决问题 - 一个天真的解决方案可能会四舍五入然后校验和。但是简单的舍入总是有病态的情况——例如,如果我们使用 floor,那么 0.9999999 和 1 是不同的。格雷码方法似乎解决了这个问题,因为相邻值总是一个位,所以基于位的校验和将准确地反映“距离”。

[update:] 更准确地说,您想要的是一个校验和,它可以估计您的灰色编码序列之间的hamming distance(如果您只关心 0.0001,那么灰色编码部分很容易,因为您可以对所有内容进行多重处理乘以 10000 并使用整数)。

看起来像这样的校验和do exist任何纠错码都可以用于错误检测。具有最小汉明距离 d 的代码可以在一个代码字中检测多达 d - 1 个错误。如果需要严格限制要检测的最小错误数,则可以使用基于最小距离的纠错码进行错误检测。

所以,以防万一不清楚:

  • 乘以最小误差得到整数
  • 转换为等效格雷码
  • 使用最小汉明距离大于您可以容忍的错误的错误检测代码。

但我仍然不确定这是对的。在从浮点数到整数的转换中,您仍然会得到病态的舍入。所以看起来你需要一个最小的汉明距离,即 1 + len(data) (最坏的情况,每个值都有一个舍入误差)。这可行吗?可能不适用于大型数组。

既然大方向是可能的,也许可以用更好的标签/描述再次询问?还是现在添加标签?我们需要一个以此为生的人。 [我添加了几个标签]

【讨论】:

  • 这是一个非常有用的建议。您已将其范围缩小到一个关于将浮点数舍入为整数的极端情况的问题,这是一个比我问的问题更严格的问题,并且可能可以解决。我会考虑一下,看看能不能把它变成算法。
  • 我不确定这是否能区分大量错误和大量错误。
【解决方案2】:

试试这个:

#include <complex>
#include <cmath>
#include <iostream>

// PARAMETERS
const size_t no_freqs = 3;
const double freqs[no_freqs] = {0.05, 0.16, 0.39}; // (for example)

int main() {
    std::complex<double> spectral_amplitude[no_freqs];
    for (size_t i = 0; i < no_freqs; ++i) spectral_amplitude[i] = 0.0;
    size_t n_data = 0;
    {
        std::complex<double> datum;
        while (std::cin >> datum) {
            for (size_t i = 0; i < no_freqs; ++i) {
                spectral_amplitude[i] += datum * std::exp(
                    std::complex<double>(0.0, 1.0) * freqs[i] * double(n_data)
                );
            }
            ++n_data;
        }
    }
    std::cout << "Fuzzy checksum:\n";
    for (size_t i = 0; i < no_freqs; ++i) {
        std::cout << real(spectral_amplitude[i]) << "\n";
        std::cout << imag(spectral_amplitude[i]) << "\n";
    }
    std::cout << "\n";
    return 0;
}

它只返回整个数据集傅里叶变换的几个任意点。可以这么说,这些构成了一个模糊的校验和。

【讨论】:

  • 嗯。鉴于 FT 只是输入的线性变换,您是否有任何理由相信这应该具有 OP 所需的属性?
  • 感谢您的建议。但是为什么傅里叶变换会比任何其他任意函数更好呢?我不明白原始数字中的误差容限如何转化为傅立叶系数中的误差容限。
  • 对。这取决于您想要什么,但是如果您从中选择任意频率,傅里叶变换就很难被愚弄。由于您预计会出现一些错误,因此您可以直接分析傅立叶,将错误在数学上表示为具有所需统计属性的随机变量 - 或者如果您不想弄乱随机数学,也可以将其表示为一些固定的误差函数。根据您的需要,也许您可​​以完全避开分析,只需尝试傅立叶并查看它是否无法满足您的需求。你比我更能判断你的需要。
  • @OliCharlesworth:如果线性是一个问题,可以在转换数据之前对每个数据点应用像 std::arctan2(std::log(x), 1.0) 这样的非线性函数。也可以以某种预先确定的方式重新排序数据点。
  • @DamonJW:也许你应该坚持总和。另一方面,对于 0.0 的频率,傅里叶变换 的和。在其他频率下,傅里叶变换就是您所说的“总和再混合”。这是查看总和的另一种方式——实际上,还有其他几种方式,每个频率都有一种方式。但我不会试图在傅立叶上卖给你!这只是一个想法。我不认为我可以更进一步地为它辩护,因为我已经拥有了。如果它不适合,足够公平。不过,当您决定使用什么时,请告诉我们。我会感兴趣的。
【解决方案3】:

我花了一段时间寻找确定性的答案,但一直找不到。如果有一个好的答案,可能需要大量的数学技能(泛函分析)。

我很确定没有基于“以某种巧妙的方式离散化,然后应用离散校验和”的解决方案,例如“离散为 0/1/? 的字符串,其中 ? 表示通配符”。任何离散化都会具有这样的性质,即两个非常接近的浮点数最终会得到不同的离散代码,然后离散校验和不会告诉我们我们想知道什么。

但是,一个非常简单的随机方案应该可以正常工作。从字母 {+1,-1} 生成一个伪随机字符串 S,并计算 csx=sum(X_i*S_i) 和 csy=sum(Y_i*S_i),其中 X 和 Y 是我的原始浮点数数组。如果我们将误差建模为均值为 0 的独立正态随机变量,则很容易计算 csx-csy 的分布。我们可以对几个字符串 S 执行此操作,然后进行平均误差为 0 的假设检验。测试所需的字符串 S 的数量是固定的,它不会随着数组的大小线性增长,所以它满足我需要一个“低维摘要”。该方法还给出了误差标准差的估计值,这可能会很方便。

【讨论】:

    【解决方案4】:

    如何计算通过将数据的最低有效数字归零获得的数据的标准整数校验和,这些数据是您不关心的?

    【讨论】:

      猜你喜欢
      • 2019-04-24
      • 1970-01-01
      • 2014-05-30
      • 2012-10-24
      • 1970-01-01
      • 2022-06-17
      • 1970-01-01
      • 1970-01-01
      • 2015-11-13
      相关资源
      最近更新 更多