arr_rs/math/operations/
rational.rs1use crate::{
2 core::prelude::*,
3 errors::prelude::*,
4 numeric::prelude::*,
5};
6use crate::prelude::ArrayMathMisc;
7
8pub trait ArrayRational<N: Numeric> where Self: Sized + Clone {
10
11 fn lcm(&self, other: &Array<N>) -> Result<Array<N>, ArrayError>;
29
30 fn gcd(&self, other: &Array<N>) -> Result<Array<N>, ArrayError>;
48}
49
50fn _gcd(x: i32, y: i32) -> i32 {
51 if y == 0 { x }
52 else { _gcd(y, x % y) }
53}
54
55impl <N: Numeric> ArrayRational<N> for Array<N> {
56
57 fn lcm(&self, other: &Self) -> Result<Self, ArrayError> {
58 self.abs()?.zip(&other.abs()?)?
59 .map(|item| {
60 let (x, y) = (item.0.to_i32(), item.1.to_i32());
61 N::from(x * y / _gcd(x, y))
62 })
63 }
64
65 fn gcd(&self, other: &Self) -> Result<Self, ArrayError> {
66 self.abs()?.zip(&other.abs()?)?
67 .map(|item| N::from(_gcd(item.0.to_i32(), item.1.to_i32())))
68 }
69}
70
71impl <N: Numeric> ArrayRational<N> for Result<Array<N>, ArrayError> {
72
73 fn lcm(&self, other: &Array<N>) -> Self {
74 self.clone()?.lcm(other)
75 }
76
77 fn gcd(&self, other: &Array<N>) -> Self {
78 self.clone()?.gcd(other)
79 }
80}