bitpacking_plus/
convert.rs

1//! Helper functions to convert between vanilla array and variants.
2//! 
3//! This is the module-level documentation. 
4
5use core::iter::zip;
6
7/// Substract 1 from each value.
8pub fn vanilla_to_m1(from: &[u32], to: &mut [u32]) {
9    for (i, j) in zip(from.iter(), to.iter_mut()) {
10        assert_ne!(*i, 0_u32, "`m1` must be used on only positive u32");
11        *j = *i - 1;
12    }
13}
14
15/// Same as `vanilla_to_m1()` but modify the original array.
16pub fn vanilla_to_m1_self(data: &mut [u32]) {
17    for i in data.iter_mut() {
18        assert_ne!(*i, 0_u32, "`m1` must be used on only positive u32");
19        *i = *i - 1;
20    }
21}
22
23/// Add 1 to each value.
24pub fn m1_to_vanilla(from: &[u32], to: &mut [u32]) {
25    for (i, j) in zip(from.iter(), to.iter_mut()) {
26        *j = *i + 1;
27    }
28}
29
30/// Same as `m1_to_vanilla()` but modify the original array.
31pub fn m1_to_vanilla_self(data: &mut [u32]) {
32    for i in data.iter_mut() {
33        *i = *i + 1;
34    }
35}
36
37/// Transforms the original input into the difference between consecutive values, then zigzag it. If $x > 0$, $zigzag(x) = 2x$, while $x < 0$, $zigzag(x) = -2x - 1$.
38pub fn vanilla_to_d1z(from: &[u32], to: &mut [u32]) {
39    let mut pre_val = from[0];
40    for (i, j) in zip(from.iter(), to.iter_mut()) {
41        if *i < pre_val {
42            *j = 2 * (pre_val - *i) - 1;
43        } else {
44            *j = 2 * (*i - pre_val);
45        }
46        pre_val = *i;
47    }
48}
49
50/// Same as `vanilla_to_d1z()` but modify the original array.
51pub fn vanilla_to_d1z_self(data: &mut [u32]) {
52    let mut pre_val = data[0];
53    for i in data.iter_mut() {
54        let curr_val = *i;
55        if curr_val < pre_val {
56            *i = 2 * (pre_val - curr_val) - 1;
57        } else {
58            *i = 2 * (curr_val - pre_val);
59        }
60        pre_val = curr_val;
61    }
62}
63
64/// Reverse the delta and zigzag transformation (`vanilla_to_d1z`).
65pub fn d1z_to_vanilla(from: &[u32], to: &mut [u32], initial: u32) {
66    let mut pre_val = initial;
67    for (i, j) in zip(from.iter(), to.iter_mut()) {
68        let m = *i % 2;
69        let x = *i / 2;
70        if m > 0 {
71            *j = pre_val - x - 1;
72        } else {
73            *j = pre_val + x;
74        }
75        pre_val = *j;
76    }
77}
78
79/// Same as `d1z_to_vanilla()` but modify the original array.
80pub fn d1z_to_vanilla_self(data: &mut [u32], initial: u32) {
81    let mut pre_val = initial;
82    for i in data.iter_mut() {
83        let m = *i % 2;
84        let x = *i / 2;
85        if m > 0 {
86            *i = pre_val - x - 1;
87        } else {
88            *i = pre_val + x;
89        }
90        pre_val = *i;
91    }
92}