tropical_gemm/mat/
mut_.rs1use crate::types::TropicalSemiring;
4
5#[derive(Debug)]
10pub struct MatMut<'a, S: TropicalSemiring> {
11 data: &'a mut [S],
12 nrows: usize,
13 ncols: usize,
14}
15
16impl<'a, S: TropicalSemiring> MatMut<'a, S> {
17 pub fn from_slice(data: &'a mut [S], nrows: usize, ncols: usize) -> Self {
19 assert_eq!(
20 data.len(),
21 nrows
22 .checked_mul(ncols)
23 .expect("matrix dimensions overflow"),
24 "data length {} != nrows {} * ncols {}",
25 data.len(),
26 nrows,
27 ncols
28 );
29 Self { data, nrows, ncols }
30 }
31
32 #[inline]
34 pub fn nrows(&self) -> usize {
35 self.nrows
36 }
37
38 #[inline]
40 pub fn ncols(&self) -> usize {
41 self.ncols
42 }
43
44 #[inline]
46 pub fn as_mut_slice(&mut self) -> &mut [S] {
47 self.data
48 }
49
50 #[inline]
52 pub fn as_mut_ptr(&mut self) -> *mut S {
53 self.data.as_mut_ptr()
54 }
55
56 #[inline]
58 pub fn get(&self, i: usize, j: usize) -> &S {
59 debug_assert!(
60 i < self.nrows,
61 "row index {} out of bounds {}",
62 i,
63 self.nrows
64 );
65 debug_assert!(
66 j < self.ncols,
67 "col index {} out of bounds {}",
68 j,
69 self.ncols
70 );
71 &self.data[j * self.nrows + i]
73 }
74
75 #[inline]
77 pub fn get_mut(&mut self, i: usize, j: usize) -> &mut S {
78 debug_assert!(
79 i < self.nrows,
80 "row index {} out of bounds {}",
81 i,
82 self.nrows
83 );
84 debug_assert!(
85 j < self.ncols,
86 "col index {} out of bounds {}",
87 j,
88 self.ncols
89 );
90 &mut self.data[j * self.nrows + i]
92 }
93}
94
95#[cfg(test)]
96mod tests {
97 use super::*;
98 use crate::TropicalMaxPlus;
99
100 #[test]
101 fn test_matmut_from_slice() {
102 let mut data = vec![
103 TropicalMaxPlus(1.0f64),
104 TropicalMaxPlus(2.0),
105 TropicalMaxPlus(3.0),
106 TropicalMaxPlus(4.0),
107 ];
108 let m = MatMut::from_slice(&mut data, 2, 2);
109 assert_eq!(m.nrows(), 2);
110 assert_eq!(m.ncols(), 2);
111 }
112
113 #[test]
114 fn test_matmut_get() {
115 let mut data = vec![
118 TropicalMaxPlus(1.0f64),
119 TropicalMaxPlus(3.0),
120 TropicalMaxPlus(2.0),
121 TropicalMaxPlus(4.0),
122 ];
123 let m = MatMut::from_slice(&mut data, 2, 2);
124 assert_eq!(m.get(0, 0).0, 1.0);
125 assert_eq!(m.get(0, 1).0, 2.0);
126 assert_eq!(m.get(1, 0).0, 3.0);
127 assert_eq!(m.get(1, 1).0, 4.0);
128 }
129
130 #[test]
131 fn test_matmut_get_mut() {
132 let mut data = vec![
133 TropicalMaxPlus(1.0f64),
134 TropicalMaxPlus(2.0),
135 TropicalMaxPlus(3.0),
136 TropicalMaxPlus(4.0),
137 ];
138 let mut m = MatMut::from_slice(&mut data, 2, 2);
139 *m.get_mut(0, 0) = TropicalMaxPlus(10.0);
140 assert_eq!(m.get(0, 0).0, 10.0);
141 }
142
143 #[test]
144 fn test_matmut_as_mut_slice() {
145 let mut data = vec![
146 TropicalMaxPlus(1.0f64),
147 TropicalMaxPlus(2.0),
148 TropicalMaxPlus(3.0),
149 TropicalMaxPlus(4.0),
150 ];
151 let mut m = MatMut::from_slice(&mut data, 2, 2);
152 let slice = m.as_mut_slice();
153 slice[0] = TropicalMaxPlus(100.0);
154 assert_eq!(data[0].0, 100.0);
155 }
156
157 #[test]
158 fn test_matmut_as_mut_ptr() {
159 let mut data = vec![
160 TropicalMaxPlus(1.0f64),
161 TropicalMaxPlus(2.0),
162 TropicalMaxPlus(3.0),
163 TropicalMaxPlus(4.0),
164 ];
165 let mut m = MatMut::from_slice(&mut data, 2, 2);
166 let ptr = m.as_mut_ptr();
167 assert!(!ptr.is_null());
168 }
169
170 #[test]
171 fn test_matmut_debug() {
172 let mut data = vec![TropicalMaxPlus(1.0f64), TropicalMaxPlus(2.0)];
173 let m = MatMut::from_slice(&mut data, 1, 2);
174 let debug_str = format!("{:?}", m);
175 assert!(debug_str.contains("MatMut"));
176 }
177
178 #[test]
179 #[should_panic(expected = "data length")]
180 fn test_matmut_size_mismatch() {
181 let mut data = vec![TropicalMaxPlus(1.0f64), TropicalMaxPlus(2.0)];
182 let _ = MatMut::from_slice(&mut data, 2, 2); }
184}