24

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

我确信我可以拼凑几个嵌套循环来生成直方图函数,但我需要这个函数快速且内存轻,因为它会被重复且经常访问。

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

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

提前致谢。

4

3 回答 3

20

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

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] 范围内的均匀分布(需要线性变换)
  • 无符号整数值的对数分布(最好与一些位旋转技巧结合使用,以快速确定最接近的二的幂或类似值)。

如果你不知道预先的分布,那么你真的不能有一个有效的机制来有效地对它们进行分类:你要么必须猜测(有偏见或无信息的结果),要么存储所有内容并在最后进行排序,分箱成大小相等的桶(性能差)。

于 2010-12-23T05:26:31.790 回答
16

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 。

于 2010-12-23T04:37:15.997 回答
14

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

您可能遇到的问题是您的输入域可能未知。如果您的所有数据都在其中的一小部分范围内,那么在整个范围内拥有 100 个 bindouble并不会很好。解决方案是对数据进行第一次遍历以找到您的范围的最小值/最大值。确实没有快速解决这个问题的方法,大多数库都会预先要求最小值/最大值。

于 2010-12-23T04:54:48.553 回答