【问题标题】:Statistically collecting rounding error in a program (C)统计收集程序中的舍入误差 (C)
【发布时间】:2012-10-18 17:36:13
【问题描述】:

我写了一个计算 1000000 的程序!使用 FFT。

(请允许我简短一点,省略一些理论上的共鸣:))

我想要做的是测量一个双精度值和 round()-ed 值之间的所有舍入误差(使用 math.h 函数)来检查这个错误是如何表现的(如果它高于 1/2) .

我这样做是通过在每次进行舍入时打印around(a) 之间的差异,并将结果写入文件,我们称之为diffs.txt,即~532Mb,使用

fprintf(my_file,"%e\n",a-round(a));

我现在需要计算该文件中出现的每个值的出现次数。

在我看来,这是一种复杂的方式,使用 grepsort 和 bash for,如下所示:

./compute-rounding-err #It creates diffs.txt
sort -u diffs.txt -o diff-sorted-unique
for i in `cat diff-sorted-unique`
do
 grep -e "$i" | wc -l >> diff-counted
done

结果是两个文件。如果我将获得的文件配对

diff-sorted-unique:     diff_counted:
-9.013892e-20           1           
...                     ...
0.000000e0              200
...                     ...
9.930234e               1

我可以获取这些值并用它们制作直方图。

我担心在带有~532Mb 文件的笔记本电脑上这样做会花费很长时间。

有人知道如何加快速度吗?

谢谢。

【问题讨论】:

  • 你为什么要这样做?你真的需要一个〜532 Mb(523 * 10 ^ 6位?532 MiB?)文件,还是你只需要一个直方图(出于某种未知/模糊的原因),或者你只需​​要知道最坏的情况错误?对于使用 double 引起的错误,你在做什么(有效数字太小而无法应对 10000!没有累积精度损失)?

标签: c bash histogram


【解决方案1】:

假设您正在编写每个 8 字节的双精度数,包含 11-12 个字符,那么您需要的总内存应该在 ~450MB 左右,这意味着您拥有的项目数应该在 50,000,000 左右。

对 5000 万个值进行排序应该不会花费很长时间。需要很长时间的是您的 for 循环,您可以在其中扫描每个项目的整个文件。

更有效的方法是对文件进行排序,但保留重复值。然后,您只需要遍历文件,将相似的值(或相等的值,基于直方图的精度)分组,并用值-计数对替换它们。

例如,如果您有以下文件:

1
0.6
-2
0
-1
-0.6
0
0
3

排序后你会得到:

-2
-1
-0.6
0
0
0
0.6
1
3

如果你遵循这个算法:

current_bucket = first value in file, floored to histogram_precision
bucket_count = 0
for all values v
    ; write current bucket + additional empty buckets
    while v > current_bucket + histogram_precision
        output   current_bucket   bucket_count
        current_bucket += histogram precision
        bucket_count = 0
    ; add v to current_bucket
    bucket_count += 1

例如,给定histogram_precision 为 1,您将得到:

-2       1
-1       2
0        4
1        1
2        0
3        1

每行num count 显示[num, num+histogram_precision) 范围内的值(count)的数量。

您可能希望使用像 [0.5, 1.5) 这样的存储桶来代替 [1 2),在这种情况下,您只需调整计算初始存储桶的第一行,或者将 while 循环的条件更改为 @ 987654333@.

【讨论】:

  • 你的回答在理论上很好,但我正在寻找一个使用 bash 或任何你喜欢的东西的实用实现:) 抱歉没有明确说明。
  • 与您所听到的相反,Stackoverflow 不是免费编程的来源。 @shahbaz 为您提供了关于您需要做什么的出色伪代码描述。欢迎您在此处发布后续问题,包括示例输入、所需的示例输出、您创建的代码、任何错误消息以及该代码的当前输出以及有关如何解决您的问题的问题。
  • @AlessandroL.,我不是awk 专家,但我相信如果用awk 实现,算法应该和我在那里写的一样短。即使在 C 语言中也不会超过 15 行。
  • 我不明白你会如何处理这个问题。理论预期误差在 (-0.5,0.5) 中,但采样误差实际上假定随机值明显小于预期范围。例如,我有这些值,表示为几个值,出现次数: (-8.731149e-11 , 342), ... , (-2.328306e-10,4369) , (0.000,45981), ... (6.585445e-10,1721)。
  • 另外,如果您获得的值大多仅在预期范围的一小部分内,那么这可能意味着大多数时候您的错误非常小,这是一件好事。它仍然是一个以 0 为中心的高斯分布,但方差很小。在这种情况下,稍微降低精度可能会得到视觉上更好的图表。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-11-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多