m4ri_rust/friendly/
binary_vector.rs1use std::ops;
5use vob::Vob;
6
7use rand;
8use rand::Rng;
9
10use friendly::binary_matrix::BinMatrix;
11
12#[derive(Clone, Debug, Default, PartialEq, Eq, Hash)]
14#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
15pub struct BinVector {
16 vec: Vob,
17}
18
19impl ops::Deref for BinVector {
20 type Target = Vob;
21
22 #[inline]
23 fn deref(&self) -> &Self::Target {
24 &self.vec
25 }
26}
27
28impl From<Vob> for BinVector {
29 fn from(v: Vob) -> BinVector {
30 BinVector::from(v)
31 }
32}
33
34impl ops::DerefMut for BinVector {
35 #[inline]
36 fn deref_mut(&mut self) -> &mut Self::Target {
37 &mut self.vec
38 }
39}
40
41impl BinVector {
42 #[inline]
44 pub fn new() -> Self {
45 BinVector::from(Vob::new())
46 }
47
48 #[inline]
50 pub fn from(vec: Vob) -> Self {
51 BinVector { vec }
52 }
53
54 #[inline]
56 pub fn from_elem(len: usize, elem: bool) -> Self {
57 BinVector::from(Vob::from_elem(len, elem))
58 }
59
60 #[inline]
62 pub fn from_bools(bools: &[bool]) -> BinVector {
63 let vec = bools.iter().cloned().collect::<Vob>();
64 BinVector { vec }
65 }
66
67 #[inline]
77 pub fn from_function(len: usize, f: fn(usize) -> bool) -> BinVector {
78 let mut vob = Vob::with_capacity(len);
79 for i in 0..len {
80 vob.push(f(i));
81 }
82 BinVector::from(vob)
83 }
84
85 #[inline]
87 pub fn random(len: usize) -> BinVector {
88 let mut rng = rand::thread_rng();
89 let mut vob = Vob::with_capacity(len);
90 for _ in 0..len {
91 vob.push(rng.gen());
92 }
93 BinVector::from(vob)
94 }
95
96 #[inline]
98 pub fn with_capacity(len: usize) -> Self {
99 BinVector::from(Vob::with_capacity(len))
100 }
101
102 #[inline]
104 pub fn from_bytes(bytes: &[u8]) -> BinVector {
105 let vec: Vob = Vob::from_bytes(bytes);
106
107 BinVector { vec }
108 }
109
110 #[inline]
112 pub fn count_ones(&self) -> u32 {
113 self.iter_storage()
114 .fold(0u32, |acc, block| acc + block.count_ones())
115 }
116
117 #[inline]
119 pub fn extend_from_binvec(&mut self, other: &BinVector) {
120 self.vec.extend_from_vob(&other.vec);
121 }
122
123 #[inline]
125 pub fn into_vob(self) -> Vob {
126 self.vec
127 }
128
129 pub fn as_matrix(&self) -> BinMatrix {
131 BinMatrix::new(vec![self.clone()] )
132 }
133
134 pub fn as_column_matrix(&self) -> BinMatrix {
136 self.as_matrix().transposed()
137 }
138
139 pub fn as_u32(&self) -> u32 {
141 assert!(self.len() < 32, "Can't convert this to a >32 bit number");
142 self.iter_storage()
143 .next()
144 .expect("Can't convert None to a number") as u32
145 }
146
147 pub fn as_u64(&self) -> u64 {
149 assert!(self.len() < 64, "Can't convert this to a >32 bit number");
150 self.iter_storage()
151 .next()
152 .expect("Can't convert None to a number") as u64
153 }
154}
155
156impl<'a> ops::Add<&'a BinVector> for &'a BinVector {
157 type Output = BinVector;
158 #[inline]
159 fn add(self, other: &BinVector) -> Self::Output {
160 let mut new = self.clone();
161 new += other;
162 new
163 }
164}
165
166impl ops::Add<BinVector> for BinVector {
167 type Output = BinVector;
168
169 #[inline]
170 fn add(self, other: BinVector) -> Self::Output {
171 assert_eq!(self.len(), other.len(), "unequal length vectors");
172 let mut new = self.clone();
173 new += other;
174 new
175 }
176}
177
178impl<'a> ops::AddAssign<&'a BinVector> for BinVector {
179 #[inline]
180 fn add_assign(&mut self, other: &BinVector) {
181 assert_eq!(self.len(), other.len(), "unequal length vectors");
182 self.xor(&*other);
183 }
184}
185
186impl ops::AddAssign<BinVector> for BinVector {
187 #[inline]
188 fn add_assign(&mut self, other: BinVector) {
189 assert_eq!(self.len(), other.len(), "unequal length vectors");
190 self.xor(&*other);
191 }
192}
193
194impl<'a> ops::Mul<&'a BinVector> for &'a BinVector {
195 type Output = bool;
196
197 #[inline]
198 fn mul(self, other: &BinVector) -> Self::Output {
199 let mut vec = self.clone();
200 vec.and(&other);
201 vec.count_ones() % 2 == 1
202 }
203}
204
205impl ops::Mul<BinVector> for BinVector {
206 type Output = bool;
207
208 #[inline]
209 fn mul(self, other: BinVector) -> Self::Output {
211 let mut vec = self.clone();
212 vec.and(&other);
213 vec.count_ones() % 2 == 1
214 }
215}
216
217#[cfg(test)]
218mod test {
219 use super::*;
220 use vob::Vob;
221
222 #[test]
223 fn init() {
224 let b = Vob::from_elem(10, false);
225 let b = BinVector::from(b);
226 assert_eq!(b.len(), 10);
227 }
228
229 #[test]
230 fn from_bytes() {
231 let b = BinVector::from_bytes(&[0b1111_1111]);
232 assert_eq!(b.len(), 8);
233
234 let b = BinVector::from_bytes(&[0b1000_0000]);
235 assert_eq!(b.get(0), Some(true));
236 assert_eq!(b.get(1), Some(false));
237 }
238
239 #[test]
240 fn add() {
241 let a = BinVector::from(Vob::from_elem(10, false));
242 let b = BinVector::from(Vob::from_elem(10, false));
243
244 let c = &a + &b;
245
246 assert_eq!(c.len(), 10, "length incorrect");
247 assert_eq!(Vob::from_elem(10, false), *c);
248 assert_eq!(c, a + b);
249 }
250
251 #[test]
252 fn mul() {
253 let a = BinVector::from(Vob::from_elem(10, true));
254 let b = BinVector::from(Vob::from_elem(10, false));
255
256 let c = &a * &b;
257
258 assert_eq!(false, c);
259 assert_eq!(c, a * b);
260 }
261
262 #[test]
263 fn as_matrix() {
264 let a = BinVector::random(10);
265 let amat = a.as_matrix();
266 assert_eq!(amat.ncols(), 10);
267 assert_eq!(amat.nrows(), 1);
268 assert_eq!(amat.as_vector(), a);
269 }
270
271 #[test]
272 fn as_column_matrix() {
273 let a = BinVector::random(10);
274 let amat = a.as_column_matrix();
275 assert_eq!(amat.ncols(), 1);
276 assert_eq!(amat.nrows(), 10);
277 assert_eq!(amat.as_vector(), a);
278 }
279
280 #[test]
281 fn count_ones() {
282 let a = BinVector::from_elem(10, true);
283 let b = BinVector::from_elem(10, false);
284 assert_eq!(a.count_ones(), 10);
285 assert_eq!(b.count_ones(), 0);
286 assert_eq!(BinVector::from_bytes(&[0b1010_1000]).count_ones(), 3);
287 }
288}