rust_tensors/
matrix_address.rs1use crate::adressable::Addressable;
2use std::ops::{Add, Neg, Sub};
3
4#[derive(Copy, Clone, Debug, Eq, PartialEq)]
5pub struct MatrixAddress {
6 pub x: i32,
7 pub y: i32,
8}
9
10impl MatrixAddress {
11 pub fn scale(self, scalar: f64) -> Self {
27 let (mut x, mut y) = (self.x as f64 * scalar, self.y as f64 * scalar);
28 if x > 0.0 {
29 x += f64::EPSILON;
30 }
31 if y > 0.0 {
32 y += f64::EPSILON;
33 }
34 MatrixAddress {
35 x: x as i32,
36 y: y as i32,
37 }
38 }
39}
40
41impl Addressable<i32, 2usize> for MatrixAddress {
42 fn get_value_at_dimension_index(&self, index: usize) -> i32 {
43 match index {
44 0 => self.x,
45 1 => self.y,
46 _ => panic!("Invalid Dimension Index"),
47 }
48 }
49}
50
51impl From<[i32; 2]> for MatrixAddress {
52 fn from(value: [i32; 2]) -> Self {
53 Self {
54 x: value[0],
55 y: value[1],
56 }
57 }
58}
59
60impl Into<[i32; 2]> for MatrixAddress {
61 fn into(self) -> [i32; 2] {
62 [self.x, self.y]
63 }
64}
65
66impl Add for MatrixAddress {
67 type Output = MatrixAddress;
68
69 fn add(self, rhs: Self) -> Self::Output {
70 MatrixAddress {
71 x: self.x + rhs.x,
72 y: self.y + rhs.y,
73 }
74 }
75}
76
77impl Sub for MatrixAddress {
78 type Output = MatrixAddress;
79
80 fn sub(self, rhs: Self) -> Self::Output {
81 MatrixAddress {
82 x: self.x - rhs.x,
83 y: self.y - rhs.y,
84 }
85 }
86}
87
88impl Neg for MatrixAddress {
89 type Output = Self;
90
91 fn neg(self) -> Self::Output {
92 MatrixAddress {
93 x: -self.x,
94 y: -self.y,
95 }
96 }
97}
98
99#[cfg(test)]
100mod tests {
101 use crate::adressable::Addressable;
102 use crate::matrix_address::MatrixAddress;
103 use proptest::proptest;
104
105 proptest! {
106 #[test]
107 fn arithmetic_test(x1 in -100000i32..100000i32, x2 in -100000i32..100000i32, y1 in -100000i32..100000i32, y2 in -100000i32..100000i32, s in -10000i32..10000i32) {
108 let a1 = MatrixAddress{x: x1, y: y1};
109 let a2 = MatrixAddress{x: x2, y: y2};
110
111 assert_eq!(a1.get_value_at_dimension_index(0), x1);
112 assert_eq!(a1.get_value_at_dimension_index(1), y1);
113 assert_eq!(a2.get_value_at_dimension_index(0), x2);
114 assert_eq!(a2.get_value_at_dimension_index(1), y2);
115
116 assert_eq!(a1 - a2, a1 + (-a2));
117 assert_eq!(a2 - a1, a2 + (-a1));
118 assert_eq!(-(-a1), a1);
119 assert_eq!(a1 + a2 - a2, a1);
120 assert_eq!(-a1 + a2 + a1, a2);
121 assert_eq!(a1.scale(2.0), MatrixAddress{x: a1.x * 2, y: a1.y * 2});
122
123 let a1 = MatrixAddress{x: x1, y: y1};
124 assert_eq!(a1.scale(s as f64), MatrixAddress{x: a1.x * s, y: a1.y * s});
125 }
126 }
127}