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
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
//! Integers as bit strings: the reflected binary Gray code and the conversions between
//! an index and its bits, most significant bit first.
//!
//! # Model
//!
//! The binary reflected Gray code of $i$ and its inverse are
//!
//! $$
//! g(i) = i \oplus \lfloor i / 2 \rfloor, \qquad
//! g^{-1}(g) = \bigoplus_{k \ge 0} \left\lfloor g / 2^{k} \right\rfloor,
//! $$
//!
//! so that $g(i)$ and $g(i + 1)$ differ in one bit. An index $i$ of $n$ bits is written
//! $b_{0} b_{1} \dots b_{n-1}$ with $i = \sum_{k=0}^{n-1} b_{k} 2^{n-1-k}$ (the most
//! significant bit first, the order of the labels of every constellation and of the
//! symbols of every code of comnum).
//!
//! # Examples
//! ```
//! use comnum_math::{bits_to_index, gray, gray_inverse, index_to_bits};
//! assert_eq!(gray(5), 7); // 101 → 111
//! assert_eq!(gray_inverse(7), 5);
//! assert_eq!(bits_to_index(&[1, 0, 1, 1]), 11);
//! assert_eq!(index_to_bits(11, 4).collect::<Vec<u8>>(), [1, 0, 1, 1]);
//! ```
use ;
/// The binary reflected Gray code $g(i) = i \oplus \lfloor i/2 \rfloor$.
///
/// # Examples
/// ```
/// use comnum_math::gray;
/// assert_eq!((0..8).map(gray).collect::<Vec<_>>(), [0, 1, 3, 2, 6, 7, 5, 4]);
/// ```
/// The inverse of [`gray`]: $g^{-1}(g) = \bigoplus_{k \ge 0} \lfloor g / 2^{k} \rfloor$.
///
/// # Examples
/// ```
/// use comnum_math::{gray, gray_inverse};
/// assert!((0..1024).all(|i| gray_inverse(gray(i)) == i));
/// ```
/// The index $i = \sum_{k} b_{k} 2^{n-1-k}$ of the bits $b_{0} \dots b_{n-1}$, the most
/// significant first (only the lowest bit of every value is read).
///
/// # Examples
/// ```
/// use comnum_math::bits_to_index;
/// assert_eq!(bits_to_index(&[1, 1, 0]), 6);
/// assert_eq!(bits_to_index(&[]), 0);
/// ```
/// The `n_bits` bits of `index`, the most significant first (the bits above $2^{n}$
/// are dropped).
///
/// # Examples
/// ```
/// use comnum_math::index_to_bits;
/// assert_eq!(index_to_bits(6, 3).collect::<Vec<u8>>(), [1, 1, 0]);
/// assert_eq!(index_to_bits(6, 2).collect::<Vec<u8>>(), [1, 0]);
/// ```
/// The indices of the blocks of `n_bits` bits of `bits`, each the [`bits_to_index`] of
/// its block (the labels of the symbols of a bit stream, the symbols of a code over
/// $\mathrm{GF}(2^{m})$).
///
/// # Errors
/// [`Error::Config`] for `n_bits = 0`, [`Error::Shape`] if the number of bits is not a
/// multiple of `n_bits`.
///
/// # Examples
/// ```
/// use comnum_math::bits::bits_to_indices;
/// assert_eq!(bits_to_indices(&[1, 0, 1, 1, 1, 0], 3)?, [5, 6]);
/// assert!(bits_to_indices(&[1, 0, 1], 2).is_err());
/// # Ok::<(), comnum_core::Error>(())
/// ```