rust_tensors/
matrix_address.rs

1use crate::addressable::Addressable;
2use std::cmp::Ordering;
3use std::fmt::{Display, Formatter};
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    fn get_mut_item_at_dimension_index(&mut self, dimension_index: u32) -> &mut i64 {
46        match dimension_index {
47            0 => &mut self.x,
48            1 => &mut self.y,
49            _ => panic!("Unexpected Dimension Index Accessed"),
50        }
51    }
52}
53
54impl Display for MatrixAddress {
55    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
56        write!(f, "({}, {})", self.x, self.y)
57    }
58}
59
60#[allow(unused)]
61impl MatrixAddress {
62    fn new(x: i64, y: i64) -> MatrixAddress {
63        MatrixAddress { x, y }
64    }
65}
66
67#[cfg(test)]
68mod tests {
69    use crate::addressable::Addressable;
70    use crate::matrix_address::MatrixAddress;
71    use proptest::{prop_assert_eq, proptest};
72
73    proptest! {
74        #[test]
75        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) {
76            let a1 = MatrixAddress{x: x1, y: y1};
77            let a2 = MatrixAddress{x: x2,y: y2};
78            a1.add(&a2);
79            a2.add(&a1);
80            a1.subtract(&a2);
81            a2.subtract(&a1);
82            a1.difference(&a2);
83            a2.difference(&a1);
84            a1.distance(&a2);
85            a2.distance(&a1);
86            a1.scale(x2 as f64);
87        }
88
89        #[test]
90        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) {
91            let a1 = MatrixAddress{x: x1, y: y1};
92            let a2 = MatrixAddress{x: x2,y: y2};
93            prop_assert_eq!(a1.add(&a2).subtract(&a2), a1);
94            prop_assert_eq!(a1.subtract(&a2).add(&a2), a1);
95            let mut a1_copy = a1.clone();
96            a1_copy.add_in_place(&a2);
97            a1_copy.subtract_in_place(&a2);
98            prop_assert_eq!(a1_copy, a1);
99            let mut a2_copy = a2.clone();
100            a2_copy.add_in_place(&a1);
101            a2_copy.subtract_in_place(&a1);
102            prop_assert_eq!(a2_copy, a2)
103        }
104
105        #[test]
106        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) {
107            let a1 = MatrixAddress{x: x1, y: y1};
108            let a2 = MatrixAddress{x: x2,y: y2};
109            prop_assert_eq!(a1.add(&a2), MatrixAddress{x: x1 + x2,y: y1 + y2});
110            prop_assert_eq!(a1.subtract(&a2), MatrixAddress{x: x1 - x2,y: y1 - y2});
111            prop_assert_eq!(a1.scale(x2 as f64), MatrixAddress{x: x1 * x2,y: y1 * x2});
112            prop_assert_eq!(a1.distance(&a2), (((x1 - x2).pow(2) as f64) + ((y1 - y2).pow(2) as f64)).sqrt());
113            let mut a1 = MatrixAddress{x: x1, y: y1};
114            let a2 = MatrixAddress{x: x2,y: y2};
115            a1.add_in_place(&a2);
116            prop_assert_eq!(a1, MatrixAddress{x: x1 + x2,y: y1 + y2});
117            let mut a1 = MatrixAddress{x: x1, y: y1};
118            let a2 = MatrixAddress{x: x2,y: y2};
119            a1.subtract_in_place(&a2);
120            prop_assert_eq!(a1, MatrixAddress{x: x1 - x2,y: y1 - y2});
121            let mut a1 = MatrixAddress{x: x1, y: y1};
122            a1.scale_in_place(x2 as f64);
123            prop_assert_eq!(a1, MatrixAddress{x: x1 * x2,y: y1 * x2});
124            
125        }
126    }
127}