arr_rs/math/operations/arithmetic.rs
1use crate::{
2 core::prelude::*,
3 errors::prelude::*,
4 math::prelude::*,
5 numeric::prelude::*,
6};
7
8/// `ArrayTrait` - Array Arithmetic functions
9pub trait ArrayArithmetic<N: Numeric> where Self: Sized + Clone {
10
11 /// Add arguments element-wise
12 ///
13 /// # Arguments
14 ///
15 /// * `value` - other array to perform operations on
16 ///
17 /// # Examples
18 ///
19 /// ```
20 /// use arr_rs::prelude::*;
21 ///
22 /// let arr = Array::flat(vec![1, 2, 3, 4]);
23 /// assert_eq!(Array::flat(vec![3, 4, 5, 6]), arr.add(&Array::single(2).unwrap()));
24 /// ```
25 ///
26 /// # Errors
27 ///
28 /// may returns `ArrayError`
29 fn add(&self, value: &Array<N>) -> Result<Array<N>, ArrayError>;
30
31 /// Computes reciprocal of array elements
32 ///
33 /// # Examples
34 ///
35 /// ```
36 /// use arr_rs::prelude::*;
37 ///
38 /// let arr = Array::flat(vec![1., 2., 4., 10.]);
39 /// assert_eq!(Array::flat(vec![1., 0.5, 0.25, 0.1]), arr.reciprocal());
40 /// ```
41 ///
42 /// # Errors
43 ///
44 /// may returns `ArrayError`
45 fn reciprocal(&self) -> Result<Array<N>, ArrayError>;
46
47 /// Computes numerical positive of array elements
48 /// Equivalent to `self.clone()`
49 ///
50 /// # Examples
51 ///
52 /// ```
53 /// use arr_rs::prelude::*;
54 ///
55 /// let arr = Array::flat(vec![1., -1.]);
56 /// assert_eq!(Array::flat(vec![1., -1.]), arr.positive());
57 /// ```
58 ///
59 /// # Errors
60 ///
61 /// may returns `ArrayError`
62 fn positive(&self) -> Result<Array<N>, ArrayError>;
63
64 /// Computes numerical negative of array elements
65 ///
66 /// # Examples
67 ///
68 /// ```
69 /// use arr_rs::prelude::*;
70 ///
71 /// let arr = Array::flat(vec![1., -1.]);
72 /// assert_eq!(Array::flat(vec![-1., 1.]), arr.negative());
73 /// ```
74 ///
75 /// # Errors
76 ///
77 /// may returns `ArrayError`
78 fn negative(&self) -> Result<Array<N>, ArrayError>;
79
80 /// Multiply arguments element-wise
81 ///
82 /// # Arguments
83 ///
84 /// * `value` - other array to perform operations on
85 ///
86 /// # Examples
87 ///
88 /// ```
89 /// use arr_rs::prelude::*;
90 ///
91 /// let arr = Array::flat(vec![1, 2, 3, 4]);
92 /// assert_eq!(Array::flat(vec![2, 4, 6, 8]), arr.multiply(&Array::single(2).unwrap()));
93 /// ```
94 ///
95 /// # Errors
96 ///
97 /// may returns `ArrayError`
98 fn multiply(&self, value: &Array<N>) -> Result<Array<N>, ArrayError>;
99
100 /// Divide arguments element-wise
101 ///
102 /// # Arguments
103 ///
104 /// * `value` - other array to perform operations on
105 ///
106 /// # Examples
107 ///
108 /// ```
109 /// use arr_rs::prelude::*;
110 ///
111 /// let arr = Array::flat(vec![1., 2., 3., 4.]);
112 /// assert_eq!(Array::flat(vec![0.5, 1., 1.5, 2.]), arr.divide(&Array::single(2.).unwrap()));
113 /// ```
114 ///
115 /// # Errors
116 ///
117 /// may returns `ArrayError`
118 fn divide(&self, value: &Array<N>) -> Result<Array<N>, ArrayError>;
119
120 /// Divide arguments element-wise
121 /// alias on `divide`
122 ///
123 /// # Arguments
124 ///
125 /// * `value` - other array to perform operations on
126 ///
127 /// # Examples
128 ///
129 /// ```
130 /// use arr_rs::prelude::*;
131 ///
132 /// let arr = Array::flat(vec![1., 2., 3., 4.]);
133 /// assert_eq!(Array::flat(vec![0.5, 1., 1.5, 2.]), arr.true_divide(&Array::single(2.).unwrap()));
134 /// ```
135 ///
136 /// # Errors
137 ///
138 /// may returns `ArrayError`
139 fn true_divide(&self, value: &Array<N>) -> Result<Array<N>, ArrayError>;
140
141 /// Divide arguments element-wise, returning floor value
142 ///
143 /// # Arguments
144 ///
145 /// * `value` - other array to perform operations on
146 ///
147 /// # Examples
148 ///
149 /// ```
150 /// use arr_rs::prelude::*;
151 ///
152 /// let arr = Array::flat(vec![1., 2., 3., 4.]);
153 /// assert_eq!(Array::flat(vec![0., 1., 1., 2.]), arr.floor_divide(&Array::single(2.).unwrap()));
154 /// ```
155 ///
156 /// # Errors
157 ///
158 /// may returns `ArrayError`
159 fn floor_divide(&self, value: &Array<N>) -> Result<Array<N>, ArrayError>;
160
161 /// Computes integer power of array elements
162 ///
163 /// # Arguments
164 ///
165 /// * `value` - other array to perform operations on
166 ///
167 /// # Examples
168 ///
169 /// ```
170 /// use arr_rs::prelude::*;
171 ///
172 /// let arr = Array::flat(vec![1, 2, 3, 4]);
173 /// assert_eq!(Array::flat(vec![1, 4, 9, 16]), arr.power(&Array::single(2).unwrap()));
174 /// ```
175 ///
176 /// # Errors
177 ///
178 /// may returns `ArrayError`
179 fn power(&self, value: &Array<N>) -> Result<Array<N>, ArrayError>;
180
181 /// Computes float power of array elements
182 ///
183 /// # Arguments
184 ///
185 /// * `value` - other array to perform operations on
186 ///
187 /// # Examples
188 ///
189 /// ```
190 /// use arr_rs::prelude::*;
191 ///
192 /// let arr = Array::flat(vec![1, 2, 3, 4]);
193 /// assert_eq!(Array::flat(vec![1, 4, 9, 16]), arr.float_power(&Array::single(2).unwrap()));
194 /// ```
195 ///
196 /// # Errors
197 ///
198 /// may returns `ArrayError`
199 fn float_power(&self, value: &Array<N>) -> Result<Array<N>, ArrayError>;
200
201 /// Subtract arguments element-wise
202 ///
203 /// # Arguments
204 ///
205 /// * `value` - other array to perform operations on
206 ///
207 /// # Examples
208 ///
209 /// ```
210 /// use arr_rs::prelude::*;
211 ///
212 /// let arr = Array::flat(vec![1, 2, 3, 4]);
213 /// assert_eq!(Array::flat(vec![-1, 0, 1, 2]), arr.subtract(&Array::single(2).unwrap()));
214 /// ```
215 ///
216 /// # Errors
217 ///
218 /// may returns `ArrayError`
219 fn subtract(&self, value: &Array<N>) -> Result<Array<N>, ArrayError>;
220
221 /// Computes remainder of division element-wise
222 /// alias on `remainder`
223 ///
224 /// # Arguments
225 ///
226 /// * `value` - other array to perform operations on
227 ///
228 /// # Examples
229 ///
230 /// ```
231 /// use arr_rs::prelude::*;
232 ///
233 /// let arr = Array::flat(vec![1, 2, 3, 4]);
234 /// assert_eq!(Array::flat(vec![1, 0, 1, 0]), arr.r#mod(&Array::single(2).unwrap()));
235 /// ```
236 ///
237 /// # Errors
238 ///
239 /// may returns `ArrayError`
240 fn r#mod(&self, value: &Array<N>) -> Result<Array<N>, ArrayError>;
241
242 /// Computes remainder of division element-wise
243 ///
244 /// # Arguments
245 ///
246 /// * `value` - other array to perform operations on
247 ///
248 /// # Examples
249 ///
250 /// ```
251 /// use arr_rs::prelude::*;
252 ///
253 /// let arr = Array::flat(vec![1, 2, 3, 4]);
254 /// assert_eq!(Array::flat(vec![1, 0, 1, 0]), arr.fmod(&Array::single(2).unwrap()));
255 /// ```
256 ///
257 /// # Errors
258 ///
259 /// may returns `ArrayError`
260 fn fmod(&self, value: &Array<N>) -> Result<Array<N>, ArrayError>;
261
262 /// Computes fractional and integral parts of an array, element-wise
263 ///
264 /// # Examples
265 ///
266 /// ```
267 /// use arr_rs::prelude::*;
268 ///
269 /// let arr = Array::flat(vec![1.5, 2., 3.5]);
270 /// assert_eq!(Ok((Array::flat(vec![0.5, 0., 0.5]).unwrap(), Array::flat(vec![1., 2., 3.]).unwrap())), arr.modf());
271 /// ```
272 ///
273 /// # Errors
274 ///
275 /// may returns `ArrayError`
276 fn modf(&self) -> Result<(Array<N>, Array<N>), ArrayError>;
277
278 /// Computes remainder of division element-wise
279 ///
280 /// # Arguments
281 ///
282 /// * `value` - other array to perform operations on
283 ///
284 /// # Examples
285 ///
286 /// ```
287 /// use arr_rs::prelude::*;
288 ///
289 /// let arr = Array::flat(vec![1, 2, 3, 4]);
290 /// assert_eq!(Array::flat(vec![1, 0, 1, 0]), arr.remainder(&Array::single(2).unwrap()));
291 /// ```
292 ///
293 /// # Errors
294 ///
295 /// may returns `ArrayError`
296 fn remainder(&self, value: &Array<N>) -> Result<Array<N>, ArrayError>;
297
298 /// Computes integral and fractional parts of an array, element-wise
299 ///
300 /// # Examples
301 ///
302 /// ```
303 /// use arr_rs::prelude::*;
304 ///
305 /// let arr = Array::flat(vec![1.5, 2., 3.5]);
306 /// assert_eq!(Ok((Array::flat(vec![1., 2., 3.]).unwrap(), Array::flat(vec![0.5, 0., 0.5]).unwrap())), arr.divmod());
307 /// ```
308 ///
309 /// # Errors
310 ///
311 /// may returns `ArrayError`
312 fn divmod(&self) -> Result<(Array<N>, Array<N>), ArrayError>;
313}
314
315impl <N: Numeric> ArrayArithmetic<N> for Array<N> {
316
317 fn add(&self, value: &Self) -> Result<Self, ArrayError> {
318 let broadcasted = self.broadcast(value)?;
319 let elements = broadcasted.clone().into_iter()
320 .map(|tuple| N::from(tuple.0.to_f64() + tuple.1.to_f64()))
321 .collect();
322 Self::new(elements, broadcasted.get_shape()?)
323 }
324
325 fn reciprocal(&self) -> Result<Self, ArrayError> {
326 self.map(|i| N::from(i.to_f64().recip()))
327 }
328
329 fn positive(&self) -> Result<Self, ArrayError> {
330 Ok(self.clone())
331 }
332
333 fn negative(&self) -> Result<Self, ArrayError> {
334 self.map(|i| N::from(-i.to_f64()))
335 }
336
337 fn multiply(&self, value: &Self) -> Result<Self, ArrayError> {
338 let broadcasted = self.broadcast(value)?;
339 let elements = broadcasted.clone().into_iter()
340 .map(|tuple| N::from(tuple.0.to_f64() * tuple.1.to_f64()))
341 .collect();
342 Self::new(elements, broadcasted.get_shape()?)
343 }
344
345 fn divide(&self, value: &Self) -> Result<Self, ArrayError> {
346 if value.get_elements()?.contains(&N::zero()) {
347 return Err(ArrayError::ParameterError { param: "value", message: "cannot contain `0`", });
348 }
349 let broadcasted = self.broadcast(value)?;
350 let elements = broadcasted.clone().into_iter()
351 .map(|tuple| N::from(tuple.0.to_f64() / tuple.1.to_f64()))
352 .collect();
353 Self::new(elements, broadcasted.get_shape()?)
354 }
355
356 fn true_divide(&self, value: &Self) -> Result<Self, ArrayError> {
357 self.divide(value)
358 }
359
360 fn floor_divide(&self, value: &Self) -> Result<Self, ArrayError> {
361 self.divide(value).floor()
362 }
363
364 fn power(&self, value: &Self) -> Result<Self, ArrayError> {
365 let broadcasted = self.broadcast(value)?;
366 let elements = broadcasted.clone().into_iter()
367 .map(|tuple| N::from(tuple.0.to_f64().powi(tuple.1.to_i32())))
368 .collect();
369 Self::new(elements, broadcasted.get_shape()?)
370 }
371
372 fn float_power(&self, value: &Self) -> Result<Self, ArrayError> {
373 let broadcasted = self.broadcast(value)?;
374 let elements = broadcasted.clone().into_iter()
375 .map(|tuple| N::from(tuple.0.to_f64().powf(tuple.1.to_f64())))
376 .collect();
377 Self::new(elements, broadcasted.get_shape()?)
378 }
379
380 fn subtract(&self, value: &Self) -> Result<Self, ArrayError> {
381 let broadcasted = self.broadcast(value)?;
382 let elements = broadcasted.clone().into_iter()
383 .map(|tuple| N::from(tuple.0.to_f64() - tuple.1.to_f64()))
384 .collect();
385 Self::new(elements, broadcasted.get_shape()?)
386 }
387
388 fn r#mod(&self, value: &Self) -> Result<Self, ArrayError> {
389 self.remainder(value)
390 }
391
392 fn fmod(&self, value: &Self) -> Result<Self, ArrayError> {
393 if value.get_elements()?.contains(&N::zero()) {
394 return Err(ArrayError::ParameterError { param: "value", message: "cannot contain `0`", });
395 }
396 let broadcasted = self.broadcast(value)?;
397 let elements = broadcasted.clone().into_iter()
398 .map(|tuple| N::from((tuple.0.to_f64() / tuple.1.to_f64()).floor().mul_add(-tuple.1.to_f64(), tuple.0.to_f64())))
399 .collect();
400 Self::new(elements, broadcasted.get_shape()?)
401 }
402
403 fn modf(&self) -> Result<(Self, Self), ArrayError> {
404 let fractional = self.r#mod(&Self::single(N::one())?)?;
405 let integral = self.floor()?;
406 Ok((fractional, integral))
407 }
408
409 fn remainder(&self, value: &Self) -> Result<Self, ArrayError> {
410 if value.get_elements()?.contains(&N::zero()) {
411 return Err(ArrayError::ParameterError { param: "value", message: "cannot contain `0`", });
412 }
413 let broadcasted = self.broadcast(value)?;
414 let elements = broadcasted.clone().into_iter()
415 .map(|tuple| N::from(tuple.0.to_f64() % tuple.1.to_f64()))
416 .collect();
417 Self::new(elements, broadcasted.get_shape()?)
418 }
419
420 fn divmod(&self) -> Result<(Self, Self), ArrayError> {
421 let fractional = self.r#mod(&Self::single(N::one())?)?;
422 let integral = self.floor()?;
423 Ok((integral, fractional))
424 }
425}
426
427impl <N: Numeric> ArrayArithmetic<N> for Result<Array<N>, ArrayError> {
428
429 fn add(&self, value: &Array<N>) -> Self {
430 self.clone()?.add(value)
431 }
432
433 fn reciprocal(&self) -> Self {
434 self.clone()?.reciprocal()
435 }
436
437 fn positive(&self) -> Self {
438 self.clone()?.positive()
439 }
440
441 fn negative(&self) -> Self {
442 self.clone()?.negative()
443 }
444
445 fn multiply(&self, value: &Array<N>) -> Self {
446 self.clone()?.multiply(value)
447 }
448
449 fn divide(&self, value: &Array<N>) -> Self {
450 self.clone()?.divide(value)
451 }
452
453 fn true_divide(&self, value: &Array<N>) -> Self {
454 self.clone()?.true_divide(value)
455 }
456
457 fn floor_divide(&self, value: &Array<N>) -> Self {
458 self.clone()?.floor_divide(value)
459 }
460
461 fn power(&self, value: &Array<N>) -> Self {
462 self.clone()?.power(value)
463 }
464
465 fn float_power(&self, value: &Array<N>) -> Self {
466 self.clone()?.float_power(value)
467 }
468
469 fn subtract(&self, value: &Array<N>) -> Self {
470 self.clone()?.subtract(value)
471 }
472
473 fn r#mod(&self, value: &Array<N>) -> Self {
474 self.clone()?.r#mod(value)
475 }
476
477 fn fmod(&self, value: &Array<N>) -> Self {
478 self.clone()?.fmod(value)
479 }
480
481 fn modf(&self) -> Result<(Array<N>, Array<N>), ArrayError> {
482 self.clone()?.modf()
483 }
484
485 fn remainder(&self, value: &Array<N>) -> Self {
486 self.clone()?.remainder(value)
487 }
488
489 fn divmod(&self) -> Result<(Array<N>, Array<N>), ArrayError> {
490 self.clone()?.divmod()
491 }
492}