rust_tensors/
matrix_address.rs1use 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}