关于C#:搜索快速/高效的直方图算法(具有预先指定的箱)

Searching for a fast/efficient histogram algorithm (with pre-specified bins)

我在Matlab之外没有做太多编码,但是我需要将Matlab代码导出为另一种语言,很可能是C。我的Matlab代码包括一个直方图函数histc(),该函数将我的输入数据( (是双精度而不是整数)到指定的bin数组中,以形成直方图。

我确定我可以将几个嵌套的循环拼凑在一起以生成直方图函数,但是我需要此函数要快速且内存轻巧,因为它将经常重复访问。

为避免重新发明轮子,有人知道C语言是否有可用的现有直方图函数可用,或者是否需要这种东西的人通常会自己创建它?

有人知道创建直方图的有效算法吗?伪代码很好。

预先感谢。


"理想"直方图算法将取决于您希望捕获的范围。通常,任何直方图算法都将如下所示:

1
2
3
4
5
6
7
const int NSAMPLES = whatever;
double samples[NSAMPLES] = { 1.0, 3.93, 1e30, ... }; // your data set
const int NBUCKETS = 10; // or whatever
int counts[NBUCKETS] = { 0 };
for (int i = 0; i != NSAMPLES; ++i) {
    counts[TRANSFER(samples[i])]++;
}

其中TRANSFER()是一些将输入映射到bin的功能(第0或第N个bin映射到适用的"超出范围")。

TRANSFER()的确切实现在很大程度上取决于样本的预期分布以及您对细节感兴趣的地方。我见过一些常见的方法:

  • [a,b]范围内的均匀分布(需要线性变换)
  • 无符号整数值的对数分布(最好与一些乱七八糟的技巧结合使用,以快速确定最接近的2的幂或相似方)。

如果您不预先知道分布,那么您实际上就没有有效的机制来有效地对它们进行装箱:您将不得不猜测(有偏或无结果的结果)或存储所有内容并将其排序在最后,合并到相同大小的存储桶中(性能不佳)。


GSL(GNU科学库)包含直方图实现。

以下是文档:http://www.gnu.org/software/gsl/manual/html_node/Histograms.html。

这是一个示例用法:http://www.gnu.org/software/gsl/manual/html_node/Example-programs-for-histograms.html。


我已经用C语言编写了自己的直方图代码,因为它很简单,我什至没有想到要寻找一个库。通常,您只需要创建一个数组来包含想要的[num_bins = (int)(max_val - min_val + 1);]箱数,当遇到每个样本时,您可以将其除以箱数[bin_idx = (int)((value - min_val) / bin_width);](其中bin_width = (max_val - min_val)/num_bins)来查找它所属的位置,然后递增bin计数器。这是一次简单,快速,一次性的数据传递。请检查我上面的算术是否存在边缘情况。

您可能遇到的问题是您输入的域可能未知。如果您的所有数据仅在其中很小的一部分内,则在整个double范围内具有100个bin不会有多好。解决方案是对数据进行第一遍查找以找到范围的最小值/最大值。确实没有快速解决方案,大多数库都会要求最小/最大数量。