-
Notifications
You must be signed in to change notification settings - Fork 7
Expand file tree
/
Copy pathHistogram.h
More file actions
88 lines (72 loc) · 3.02 KB
/
Histogram.h
File metadata and controls
88 lines (72 loc) · 3.02 KB
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
// TODO: Switch histogram calculation from mask/shift to union
#pragma once
inline size_t* HistogramByteComponents(unsigned inArray[], size_t l, size_t r)
{
const unsigned BitsPerDigit = 8;
const unsigned NumberOfBins = 1 << BitsPerDigit;
const unsigned NumberOfDigits = (sizeof(unsigned) * 8 + BitsPerDigit - 1) / BitsPerDigit;
size_t* count = new size_t[NumberOfDigits * NumberOfBins]{};
size_t* count0 = count + (0 * NumberOfBins);
size_t* count1 = count + (1 * NumberOfBins);
size_t* count2 = count + (2 * NumberOfBins);
size_t* count3 = count + (3 * NumberOfBins);
for (size_t current = l; current <= r; current++) // Scan the array and count the number of times each digit value appears - i.e. size of each bin
{
unsigned value = inArray[current];
count0[ value & 0xff]++;
count1[(value >> 8) & 0xff]++;
count2[(value >> 16) & 0xff]++;
count3[(value >> 24) & 0xff]++;
}
return count;
}
inline void HistogramByteSingleComponent(unsigned inArray[], size_t l, size_t r, unsigned shiftAmount, size_t* count)
{
const size_t NumberOfBins = 256;
for (size_t i = 0; i < NumberOfBins; i++)
count[i] = 0;
for (size_t current = l; current <= r; current++)
count[(inArray[current] >> shiftAmount) & 0xff]++;
}
inline size_t* HistogramNbitComponents(unsigned inArray[], size_t l, size_t r, unsigned bitsPerComponent)
{
if (inArray == NULL)
return NULL;
const int NumBitsInUInt = sizeof(unsigned) * 8;
if (bitsPerComponent > NumBitsInUInt || bitsPerComponent == 0)
return NULL;
size_t numberOfBins = (size_t)1 << bitsPerComponent;
unsigned numberOfDigits = (NumBitsInUInt + bitsPerComponent - 1) / bitsPerComponent; // ceiling division
size_t* count = new size_t[numberOfDigits * numberOfBins]{};
unsigned bitMask = (unsigned)(numberOfBins - 1);
for (size_t current = l; current <= r; current++) // Scan the array and count the number of times each digit value appears - i.e. size of each bin
{
unsigned value = inArray[current];
for (unsigned d = 0; d < numberOfDigits; d++)
count[d * numberOfBins + ((value >> (d * bitsPerComponent)) & bitMask)]++;
}
return count;
}
template< unsigned PowerOfTwoRadix, unsigned Log2ofPowerOfTwoRadix >
inline size_t** HistogramByteComponents(unsigned long long inArray[], int l, int r)
{
const unsigned numberOfDigits = Log2ofPowerOfTwoRadix;
const unsigned NumberOfBins = PowerOfTwoRadix;
size_t** count = new size_t * [numberOfDigits];
for (unsigned i = 0; i < numberOfDigits; i++)
count[i] = new size_t[NumberOfBins]{};
// Faster version, since it doesn't use a 2-D array, reducing one level of indirection
size_t* count0 = count[0];
size_t* count1 = count[1];
size_t* count2 = count[2];
size_t* count3 = count[3];
for (int current = l; current <= r; current++) // Scan the array and count the number of times each digit value appears - i.e. size of each bin
{
unsigned long value = inArray[current];
count0[value & 0xff]++;
count1[(value >> 8) & 0xff]++;
count2[(value >> 16) & 0xff]++;
count3[(value >> 24) & 0xff]++;
}
return count;
}