-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathbinning.h
69 lines (61 loc) · 1.43 KB
/
binning.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
#ifndef BINNING_H
#define BINNING_H
#include <inttypes.h>
#include <math.h>
#include <vector>
template <typename BorderT>
class Binning {
public:
Binning()
: min_(0)
, max_(0)
, width_(0)
, max_bin_(1)
{ }
Binning(const BorderT min, const BorderT width, const BorderT max)
: min_(min)
, max_(max)
, width_(width)
, max_bin_(ceil((max-min)/width) + 1)
{
assert(width_ > 0);
assert(min < max);
}
explicit Binning(const std::vector<BorderT> &borders)
: borders_(borders)
, min_(borders[0])
, max_(borders.back())
, width_(0)
, max_bin_(borders_.size())
{
assert(!borders.empty());
}
uint64_t FindBin(const BorderT val) const {
if (val < min_) return 0;
if (val >= max_) return max_bin_;
if (width_ > 0) return (val-min_)/width_ + 1;
uint64_t lo = 0;
uint64_t hi = max_bin_;
while (hi-lo > kSteps) {
uint64_t skip = (hi-lo)/kSteps;
unsigned i = lo + skip;
for ( ; i < hi; i += skip)
if (borders_[i] >= val) break;
hi = (i > hi) ? hi : i;
lo = i - skip;
}
unsigned i = lo;
for ( ; i < hi; ++i)
if (borders_[i] > val) break;
return i;
}
uint64_t num_bins() const { return max_bin_ + 1; }
private:
static const uint8_t kSteps = 8;
std::vector<BorderT> borders_;
BorderT min_;
BorderT max_;
BorderT width_;
uint32_t max_bin_;
};
#endif