forked from wolfgangmauerer/libtrevisan
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathutils.hpp
94 lines (74 loc) · 1.82 KB
/
utils.hpp
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
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
#ifndef UTILS_HPP
#define UTILS_HPP
// don't use namespace std -- we may want to use this in code
// where std is not imported into the main namespace
#include<cstddef>
#include<cassert>
#include<cstdlib>
#include<cmath> // floating point logarithm
#include<iostream>
#include<limits>
#define BITS_PER_BYTE 8
#define BITS_PER_TYPE(_type) (sizeof(_type)*BITS_PER_BYTE)
// Compute \lceil log_{2}(n)\rceil. We don't care about efficiency here.
template<class T>
std::size_t ceil_log2(T num) {
assert(num > 0);
if (num & ((T)1 << (BITS_PER_TYPE(T) - 1))) {
if ((num & ((T)1 << (BITS_PER_TYPE(T) - 1) - 1)) > 0) {
std::cerr << "Internal error: Overflow in floor_log2"
<< std::endl;
std::exit(-1);
}
return BITS_PER_TYPE(T);
}
std::size_t log;
for (log = BITS_PER_TYPE(T)-1; log--; log >= 0) {
if (num & ((T)1 << log))
if ((num & (((T)1 << log) - 1)) > 0)
return log+1;
else
return log;
}
// Should never be reached
assert(1==0);
return 42;
}
// Determine how many bits are required to store a number num
// Could as well compute ceil_log2<T>(num+1)
template<class T>
std::size_t numbits(T num) {
assert(num >= 0);
std::size_t bits;
if (num == 0)
return 1;
bits = ceil_log2<T>(num);
if (num & ((T)1 << bits)) {
return bits + 1;
}
return bits;
}
// Same for floor.
template<class T>
std::size_t floor_log2(T num) {
assert(num > 0);
size_t log;
for (log = BITS_PER_TYPE(T)-1; log--; log >= 0) {
if (num & ((T)1 << log))
return log;
}
}
// Shannon entropy
template<class T>
T h(T x) {
if (x < 2*std::numeric_limits<T>::epsilon())
return(0);
if (x > 1-2*std::numeric_limits<T>::epsilon())
return(0);
return(-x*log2(x) -(1-x)*log2(1-x));
}
template<class C, class OutIter>
OutIter copy_container(const C& c, OutIter result) {
return std::copy(c.begin(), c.end(), result);
}
#endif