“理想的”直方图算法将取决于您希望捕获的范围。通常,任何直方图算法都将如下所示:
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] 范围内的均匀分布(需要线性变换)
- 无符号整数值的对数分布(最好与一些位旋转技巧结合使用,以快速确定最接近的二的幂或类似值)。
如果你不知道预先的分布,那么你真的不能有一个有效的机制来有效地对它们进行分类:你要么必须猜测(有偏见或无信息的结果),要么存储所有内容并在最后进行排序,分箱成大小相等的桶(性能差)。