@@ -17,35 +17,37 @@ void aldr_free (struct aldr_s x) {
17
17
free (x .leaves_flat );
18
18
}
19
19
20
- struct aldr_s aldr_preprocess (int * a , int n ) {
21
- // assume k <= 31
22
- int m = 0 ;
23
- for (int i = 0 ; i < n ; ++ i ) {
20
+ struct aldr_s aldr_preprocess (uint32_t * a , uint32_t n ) {
21
+ // this algorithm requires that
22
+ // 0 < n < (1 << 32) - 1
23
+ // 0 < sum(a) < (1 << 31) - 1
24
+ uint32_t m = 0 ;
25
+ for (uint32_t i = 0 ; i < n ; ++ i ) {
24
26
m += a [i ];
25
27
}
26
- int k = 32 - __builtin_clz (m ) - ( 1 == __builtin_popcount ( m ) );
27
- int K = k << 1 ; // depth
28
- long long c = (1ll << K ) / m ; // amplification factor
29
- long long r = (1ll << K ) % m ; // reject weight
28
+ uint32_t k = 32 - __builtin_clz (m - 1 );
29
+ uint32_t K = k << 1 ; // depth
30
+ uint64_t c = (1ll << K ) / m ; // amplification factor
31
+ uint64_t r = (1ll << K ) % m ; // reject weight
30
32
31
- int num_leaves = __builtin_popcountll (r );
32
- for (int i = 0 ; i < n ; ++ i ) {
33
+ uint32_t num_leaves = __builtin_popcountll (r );
34
+ for (uint32_t i = 0 ; i < n ; ++ i ) {
33
35
num_leaves += __builtin_popcountll (c * a [i ]);
34
36
}
35
37
36
- int * breadths = calloc (K + 1 , sizeof (int ));
37
- int * leaves_flat = calloc (num_leaves , sizeof (int ));
38
+ uint32_t * breadths = calloc (K + 1 , sizeof (* breadths ));
39
+ uint32_t * leaves_flat = calloc (num_leaves , sizeof (* leaves_flat ));
38
40
39
- int location = 0 ;
40
- for (int j = 0 ; j <= K ; j ++ ) {
41
- long long bit = (1ll << (K - j ));
41
+ uint32_t location = 0 ;
42
+ for (uint32_t j = 0 ; j <= K ; j ++ ) {
43
+ uint64_t bit = (1ll << (K - j ));
42
44
if (r & bit ) {
43
45
leaves_flat [location ] = 0 ;
44
46
++ breadths [j ];
45
47
++ location ;
46
48
}
47
- for (int i = 0 ; i < n ; ++ i ) {
48
- long long Qi = c * a [i ];
49
+ for (uint32_t i = 0 ; i < n ; ++ i ) {
50
+ uint64_t Qi = c * a [i ];
49
51
if (Qi & bit ) {
50
52
leaves_flat [location ] = i + 1 ;
51
53
++ breadths [j ];
@@ -62,14 +64,14 @@ struct aldr_s aldr_preprocess(int* a, int n) {
62
64
};
63
65
}
64
66
65
- int aldr_sample (struct aldr_s * f ) {
67
+ uint32_t aldr_sample (struct aldr_s * f ) {
66
68
for (;;) {
67
- int depth = 0 ;
68
- int location = 0 ;
69
- int val = 0 ;
69
+ uint32_t depth = 0 ;
70
+ uint32_t location = 0 ;
71
+ uint32_t val = 0 ;
70
72
for (;;) {
71
73
if (val < f -> breadths [depth ]) {
72
- int ans = f -> leaves_flat [location + val ];
74
+ uint32_t ans = f -> leaves_flat [location + val ];
73
75
if (ans ) return ans - 1 ;
74
76
else break ;
75
77
}
0 commit comments