rust_tensors/
matrix_address.rs1use std::cmp::Ordering;
2use std::fmt::{Display, Formatter};
3use crate::addressable::Addressable;
4
5#[derive(Eq, PartialEq, Ord, Copy, Clone, Debug, Hash)]
6pub struct MatrixAddress {
7    pub x: i64,
8    pub y: i64,
9}
10
11impl PartialOrd<Self> for MatrixAddress {
12    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
13        match self.y.cmp(&other.y) {
14            Ordering::Less => Some(Ordering::Less),
15            Ordering::Equal => match self.x.cmp(&other.x) {
16                Ordering::Less => Some(Ordering::Less),
17                Ordering::Equal => Some(Ordering::Equal),
18                Ordering::Greater => Some(Ordering::Greater),
19            },
20            Ordering::Greater => Some(Ordering::Greater),
21        }
22    }
23}
24
25impl Addressable for MatrixAddress {
26    fn get_dimension_count() -> u32 {
27        2
28    }
29
30    fn new_from_value_vec(values: Vec<i64>) -> MatrixAddress {
31        MatrixAddress {
32            x: values[0],
33            y: values[1],
34        }
35    }
36
37    fn get_item_at_dimension_index(&self, dimension_index: u32) -> &i64 {
38        match dimension_index {
39            0 => &self.x,
40            1 => &self.y,
41            _ => panic!("Unexpected Dimension Index Accessed"),
42        }
43    }
44}
45
46impl Display for MatrixAddress {
47    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
48        write!(f, "({}, {})", self.x, self.y)
49    }
50}
51
52#[allow(unused)]
53impl MatrixAddress {
54    fn new(x: i64, y: i64) -> MatrixAddress {
55        MatrixAddress { x, y }
56    }
57}
58
59#[cfg(test)]
60mod tests {
61    use proptest::{prop_assert_eq, proptest};
62    use crate::addressable::Addressable;
63    use crate::matrix_address::MatrixAddress;
64
65    proptest! {
66        #[test]
67        fn doesnt_crash(x1 in -1_000_000_000i64..1_000_000_000i64, y1 in -1_000_000_000i64..1_000_000_000i64, x2 in -1_000_000_000i64..1_000_000_000i64, y2 in -1_000_000_000i64..1_000_000_000i64) {
68            let a1 = MatrixAddress{x: x1, y: y1};
69            let a2 = MatrixAddress{x: x2,y: y2};
70            a1.add(&a2);
71            a2.add(&a1);
72            a1.subtract(&a2);
73            a2.subtract(&a1);
74            a1.difference(&a2);
75            a2.difference(&a1);
76            a1.distance(&a2);
77            a2.distance(&a1);
78            a1.scale(x2 as f64);
79        }
80
81        #[test]
82        fn operation_consistency(x1 in -1_000_000_000i64..1_000_000_000i64, y1 in -1_000_000_000i64..1_000_000_000i64, x2 in -1_000_000_000i64..1_000_000_000i64, y2 in -1_000_000_000i64..1_000_000_000i64) {
83            let a1 = MatrixAddress{x: x1, y: y1};
84            let a2 = MatrixAddress{x: x2,y: y2};
85            prop_assert_eq!(a1.add(&a2).subtract(&a2), a1);
86            prop_assert_eq!(a1.subtract(&a2).add(&a2), a1);
87        }
88
89        #[test]
90        fn operation_accuracy(x1 in -1_000_000i64..1_000_000i64, y1 in -1_000_000i64..1_000_000i64, x2 in -1_000_000i64..1_000_000i64, y2 in -1_000_000i64..1_000_000i64) {
91            let a1 = MatrixAddress{x: x1, y: y1};
92            let a2 = MatrixAddress{x: x2,y: y2};
93            prop_assert_eq!(a1.add(&a2), MatrixAddress{x: x1 + x2,y: y1 + y2});
94            prop_assert_eq!(a1.subtract(&a2), MatrixAddress{x: x1 - x2,y: y1 - y2});
95            prop_assert_eq!(a1.scale(x2 as f64), MatrixAddress{x: x1 * x2,y: y1 * x2});
96            prop_assert_eq!(a1.distance(&a2), (((x1 - x2).pow(2) as f64) + ((y1 - y2).pow(2) as f64)).sqrt());
97        }
98    }
99}