arr_rs/numeric/operations/
binary.rs

1use crate::{
2    core::prelude::*,
3    errors::prelude::*,
4    numeric::prelude::*,
5    validators::prelude::*,
6};
7
8/// `ArrayTrait` - Binary Array operations
9pub trait ArrayBinary<N: Numeric> where Self: Sized + Clone {
10
11    /// Compute the bit-wise AND of two arrays element-wise
12    ///
13    /// # Arguments
14    ///
15    /// * `other` - array to perform the operation with
16    ///
17    /// # Examples
18    ///
19    /// ```
20    /// use arr_rs::prelude::*;
21    ///
22    /// assert_eq!(Array::<i32>::flat(vec![1]), array!(i32, [13]).bitwise_and(&array!(i32, [17]).unwrap()));
23    /// assert_eq!(Array::<i32>::flat(vec![0, 1]), array!(i32, [11, 7]).bitwise_and(&array!(i32, [4, 25]).unwrap()));
24    /// assert_eq!(Array::<i32>::flat(vec![2, 4, 16]), array!(i32, [2, 5, 255]).bitwise_and(&array!(i32, [3, 14, 16]).unwrap()));
25    /// ```
26    ///
27    /// # Errors
28    ///
29    /// may returns `ArrayError`
30    fn bitwise_and(&self, other: &Array<N>) -> Result<Array<N>, ArrayError>;
31
32    /// Compute the bit-wise OR of two arrays element-wise
33    ///
34    /// # Arguments
35    ///
36    /// * `other` - array to perform the operation with
37    ///
38    /// # Examples
39    ///
40    /// ```
41    /// use arr_rs::prelude::*;
42    ///
43    /// assert_eq!(Array::<i32>::flat(vec![29]), array!(i32, [13]).bitwise_or(&array!(i32, [16]).unwrap()));
44    /// assert_eq!(Array::<i32>::flat(vec![33, 6]), array!(i32, [33, 4]).bitwise_or(&array!(i32, [1, 2]).unwrap()));
45    /// assert_eq!(Array::<i32>::flat(vec![6, 5, 255]), array!(i32, [2, 5, 255]).bitwise_or(&array!(i32, [4, 4, 4]).unwrap()));
46    /// ```
47    ///
48    /// # Errors
49    ///
50    /// may returns `ArrayError`
51    fn bitwise_or(&self, other: &Array<N>) -> Result<Array<N>, ArrayError>;
52
53    /// Compute the bit-wise XOR of two arrays element-wise
54    ///
55    /// # Arguments
56    ///
57    /// * `other` - array to perform the operation with
58    ///
59    /// # Examples
60    ///
61    /// ```
62    /// use arr_rs::prelude::*;
63    ///
64    /// assert_eq!(Array::<i32>::flat(vec![28]), array!(i32, [13]).bitwise_xor(&array!(i32, [17]).unwrap()));
65    /// assert_eq!(Array::<i32>::flat(vec![26]), array!(i32, [31]).bitwise_xor(&array!(i32, [5]).unwrap()));
66    /// assert_eq!(Array::<i32>::flat(vec![26, 5]), array!(i32, [31, 3]).bitwise_xor(&array!(i32, [5, 6]).unwrap()));
67    /// ```
68    ///
69    /// # Errors
70    ///
71    /// may returns `ArrayError`
72    fn bitwise_xor(&self, other: &Array<N>) -> Result<Array<N>, ArrayError>;
73
74    /// Compute bit-wise inversion, or bit-wise NOT, element-wise
75    ///
76    /// # Arguments
77    ///
78    /// * `other` - array to perform the operation with
79    ///
80    /// # Examples
81    ///
82    /// ```
83    /// use arr_rs::prelude::*;
84    ///
85    /// assert_eq!(Array::<u8>::flat(vec![242]), array!(u8, [13]).bitwise_not());
86    /// assert_eq!(Array::<u16>::flat(vec![65522]), array!(u16, [13]).bitwise_not());
87    /// assert_eq!(Array::<i32>::flat(vec![-14]), array!(i32, [13]).bitwise_not());
88    /// ```
89    ///
90    /// # Errors
91    ///
92    /// may returns `ArrayError`
93    fn bitwise_not(&self) -> Result<Array<N>, ArrayError>;
94
95    /// Compute bit-wise inversion, or bit-wise NOT, element-wise. Alias on `bitwise_not`
96    ///
97    /// # Arguments
98    ///
99    /// * `other` - array to perform the operation with
100    ///
101    /// # Examples
102    ///
103    /// ```
104    /// use arr_rs::prelude::*;
105    ///
106    /// assert_eq!(Array::<u8>::flat(vec![242]), array!(u8, [13]).invert());
107    /// assert_eq!(Array::<u16>::flat(vec![65522]), array!(u16, [13]).invert());
108    /// assert_eq!(Array::<i32>::flat(vec![-14]), array!(i32, [13]).invert());
109    /// ```
110    ///
111    /// # Errors
112    ///
113    /// may returns `ArrayError`
114    fn invert(&self) -> Result<Array<N>, ArrayError>;
115
116    /// Shift the bits of an integer to the left
117    ///
118    /// # Arguments
119    ///
120    /// * `other` - array to perform the operation with
121    ///
122    /// # Examples
123    ///
124    /// ```
125    /// use arr_rs::prelude::*;
126    ///
127    /// assert_eq!(Array::<u8>::flat(vec![20]), array!(u8, [5]).left_shift(&array!(u8, [2]).unwrap()));
128    /// assert_eq!(Array::<u8>::flat(vec![10, 20, 40]), array!(u8, [5]).left_shift(&array!(u8, [1, 2, 3]).unwrap()));
129    /// ```
130    ///
131    /// # Errors
132    ///
133    /// may returns `ArrayError`
134    fn left_shift(&self, other: &Array<N>) -> Result<Array<N>, ArrayError>;
135
136    /// Shift the bits of an integer to the right
137    ///
138    /// # Arguments
139    ///
140    /// * `other` - array to perform the operation with
141    ///
142    /// # Examples
143    ///
144    /// ```
145    /// use arr_rs::prelude::*;
146    ///
147    /// assert_eq!(Array::<u8>::flat(vec![5]), array!(u8, [10]).right_shift(&array!(u8, [1]).unwrap()));
148    /// assert_eq!(Array::<u8>::flat(vec![5, 2, 1]), array!(u8, [10]).right_shift(&array!(u8, [1, 2, 3]).unwrap()));
149    /// ```
150    ///
151    /// # Errors
152    ///
153    /// may returns `ArrayError`
154    fn right_shift(&self, other: &Array<N>) -> Result<Array<N>, ArrayError>;
155
156    /// Return the binary representation of the input number as a string
157    ///
158    /// # Arguments
159    ///
160    /// * `num` - integer decimal number
161    ///
162    /// # Examples
163    ///
164    /// ```
165    /// use arr_rs::prelude::*;
166    ///
167    /// assert_eq!("10".to_string(), 2u8.binary_repr());
168    /// assert_eq!("11".to_string(), 3u8.binary_repr());
169    /// assert_eq!("11111101".to_string(), (-3i8).binary_repr());
170    /// assert_eq!("11111111".to_string(), 255u8.binary_repr());
171    ///
172    /// assert_eq!("10".to_string(), Array::<u8>::binary_repr(2));
173    /// assert_eq!("11".to_string(), Array::<u8>::binary_repr(3));
174    /// assert_eq!("11111101".to_string(), Array::<i8>::binary_repr(-3));
175    /// assert_eq!("11111111".to_string(), Array::<u8>::binary_repr(255));
176    /// ```
177    ///
178    /// # Errors
179    ///
180    /// may returns `ArrayError`
181    fn binary_repr(num: N) -> String;
182}
183
184impl <N: Numeric> ArrayBinary<N> for Array<N> {
185
186    fn bitwise_and(&self, other: &Self) -> Result<Self, ArrayError> {
187        self.get_shape()?.is_broadcastable(&other.get_shape()?)?;
188        let broadcasted = self.broadcast(other)?;
189        let elements = broadcasted.clone().into_iter()
190            .map(|tuple| tuple.0.bitwise_and(&tuple.1))
191            .collect();
192        Self::new(elements, broadcasted.get_shape()?)
193    }
194
195    fn bitwise_or(&self, other: &Self) -> Result<Self, ArrayError> {
196        self.get_shape()?.is_broadcastable(&other.get_shape()?)?;
197        let broadcasted = self.broadcast(other)?;
198        let elements = broadcasted.clone().into_iter()
199            .map(|tuple| tuple.0.bitwise_or(&tuple.1))
200            .collect();
201        Self::new(elements, broadcasted.get_shape()?)
202    }
203
204    fn bitwise_xor(&self, other: &Self) -> Result<Self, ArrayError> {
205        self.get_shape()?.is_broadcastable(&other.get_shape()?)?;
206        let elements = self.broadcast(other)?.into_iter()
207            .map(|tuple| tuple.0.bitwise_xor(&tuple.1))
208            .collect();
209        Self::new(elements, self.get_shape()?)
210    }
211
212    fn bitwise_not(&self) -> Result<Self, ArrayError> {
213        self.map(|&a| a.bitwise_not())
214    }
215
216    fn invert(&self) -> Result<Self, ArrayError> {
217        self.bitwise_not()
218    }
219
220    fn left_shift(&self, other: &Self) -> Result<Self, ArrayError> {
221        self.get_shape()?.is_broadcastable(&other.get_shape()?)?;
222        let broadcasted = self.broadcast(other)?;
223        let elements = broadcasted.clone().into_iter()
224            .map(|tuple| tuple.0.left_shift(&tuple.1))
225            .collect();
226        Self::new(elements, broadcasted.get_shape()?)
227    }
228
229    fn right_shift(&self, other: &Self) -> Result<Self, ArrayError> {
230        self.get_shape()?.is_broadcastable(&other.get_shape()?)?;
231        let broadcasted = self.broadcast(other)?;
232        let elements = broadcasted.clone().into_iter()
233            .map(|tuple| tuple.0.right_shift(&tuple.1))
234            .collect();
235        Self::new(elements, broadcasted.get_shape()?)
236    }
237
238    fn binary_repr(num: N) -> String {
239        num.binary_repr()
240    }
241}
242
243impl <N: Numeric> ArrayBinary<N> for Result<Array<N>, ArrayError> {
244
245    fn bitwise_and(&self, other: &Array<N>) -> Self {
246        self.clone()?.bitwise_and(other)
247    }
248
249    fn bitwise_or(&self, other: &Array<N>) -> Self {
250        self.clone()?.bitwise_or(other)
251    }
252
253    fn bitwise_xor(&self, other: &Array<N>) -> Self {
254        self.clone()?.bitwise_xor(other)
255    }
256
257    fn bitwise_not(&self) -> Self {
258        self.clone()?.bitwise_not()
259    }
260
261    fn invert(&self) -> Self {
262        self.clone()?.invert()
263    }
264
265    fn left_shift(&self, other: &Array<N>) -> Self {
266        self.clone()?.left_shift(other)
267    }
268
269    fn right_shift(&self, other: &Array<N>) -> Self {
270        self.clone()?.right_shift(other)
271    }
272
273    fn binary_repr(num: N) -> String {
274        num.binary_repr()
275    }
276}