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}