arr_rs/numeric/operations/
binary_bits.rs1use crate::{
2 core::prelude::*,
3 errors::prelude::*,
4 extensions::prelude::*,
5 numeric::prelude::*,
6};
7
8pub trait ArrayBinaryBits where Self: Sized + Clone {
10
11 fn unpack_bits(&self, axis: Option<isize>, count: Option<isize>, bit_order: Option<impl BitOrderType>) -> Result<Array<u8>, ArrayError>;
33
34 fn pack_bits(&self, axis: Option<isize>, bit_order: Option<impl BitOrderType>) -> Result<Array<u8>, ArrayError>;
55}
56
57impl ArrayBinaryBits for Array<u8> {
58
59 fn unpack_bits(&self, axis: Option<isize>, count: Option<isize>, bit_order: Option<impl BitOrderType>) -> Result<Array<u8>, ArrayError> {
60 if self.is_empty()? { return Self::empty() }
61 let bit_order = match bit_order {
62 Some(bo) => bo.to_bit_order()?,
63 None => BitOrder::Big,
64 };
65 match axis {
66 None => {
67 let result = self.ravel()?
68 .into_iter()
69 .flat_map(|a| {
70 let mut elems = (0..8).rev().map(move |idx| (a >> idx) & 1).collect::<Vec<u8>>();
71 if bit_order == BitOrder::Little { elems.reverse_ext() } else { elems }
72 })
73 .collect::<Self>();
74 let count = count.unwrap_or(self.len()?.to_isize() * 8);
75 if count >= 0 { result.slice(0..count.to_usize()) }
76 else { result.slice(0..self.len()? - count.to_usize()) }
77 },
78 Some(axis) => {
79 let axis = self.normalize_axis(axis);
80 self.apply_along_axis(axis, |arr| arr.unpack_bits(None, count, Some(bit_order)))
81 }
82 }
83 }
84
85 fn pack_bits(&self, axis: Option<isize>, bit_order: Option<impl BitOrderType>) -> Result<Array<u8>, ArrayError> {
86 if self.is_empty()? { return Self::empty() }
87 let bit_order = match bit_order {
88 Some(bo) => bo.to_bit_order()?,
89 None => BitOrder::Big,
90 };
91 match axis {
92 None => {
93 let mut elements = self.get_elements()?;
94 if elements.len() % 8 != 0 { elements.extend_from_slice(&vec![0; 8 - elements.len() % 8]) }
95
96 let parts = elements.len() / 8;
97 let result = (0..parts).map(|p| {
98 let subarray = elements[p * 8..(p + 1) * 8].iter()
99 .map(|i| if i > &0 { "1" } else { "0" })
100 .collect::<Vec<&str>>()
101 .join("");
102 let subarray = if bit_order == BitOrder::Little { subarray.chars().rev().collect() } else { subarray };
103 u8::from_str_radix(&subarray, 2).unwrap()
104 }).collect();
105 Ok(result)
106 },
107 Some(axis) => {
108 let axis = self.normalize_axis(axis);
109 self.apply_along_axis(axis, |arr| arr.pack_bits(None, Some(bit_order)))
110 },
111 }
112 }
113}
114
115impl ArrayBinaryBits for Result<Array<u8>, ArrayError> {
116
117 fn unpack_bits(&self, axis: Option<isize>, count: Option<isize>, bit_order: Option<impl BitOrderType>) -> Result<Array<u8>, ArrayError> {
118 self.clone()?.unpack_bits(axis, count, bit_order)
119 }
120
121 fn pack_bits(&self, axis: Option<isize>, bit_order: Option<impl BitOrderType>) -> Result<Array<u8>, ArrayError> {
122 self.clone()?.pack_bits(axis, bit_order)
123 }
124}