1pub(super) mod square;
2pub(super) mod vector;
3
4use crate::math::{
5 Quantity, QuantityVector, Scalar, Tensor, TensorRank1, TensorRank1Vec, TensorRank2,
6 TensorTuple, TensorVec,
7};
8use std::{
9 iter::Sum,
10 ops::{Add, AddAssign, Div, DivAssign, Index, IndexMut, Mul, MulAssign, Sub, SubAssign},
11};
12use vector::Vector;
13
14#[derive(Clone, Debug, PartialEq)]
16pub struct Matrix(Vec<Vector>);
17
18impl Default for Matrix {
19 fn default() -> Self {
20 Self::zero(0, 0)
21 }
22}
23
24impl Matrix {
25 pub fn height(&self) -> usize {
26 self.0.len()
27 }
28 pub fn is_empty(&self) -> bool {
29 self.0.is_empty()
30 }
31 pub fn iter(&self) -> impl Iterator<Item = &Vector> {
32 self.0.iter()
33 }
34 pub fn iter_mut(&mut self) -> impl Iterator<Item = &mut Vector> {
35 self.0.iter_mut()
36 }
37 pub fn len(&self) -> usize {
38 self.0.len()
39 }
40 pub fn transpose(&self) -> Self {
41 (0..self.width())
42 .map(|i| (0..self.len()).map(|j| self[j][i]).collect())
43 .collect()
44 }
45 pub fn width(&self) -> usize {
46 self.0[0].len()
47 }
48 pub fn zero(height: usize, width: usize) -> Self {
49 (0..height).map(|_| Vector::zero(width)).collect()
50 }
51}
52
53impl TensorVec for Matrix {
54 type Item = Vector;
55 fn append(&mut self, other: &mut Self) {
56 self.0.append(&mut other.0)
57 }
58 fn capacity(&self) -> usize {
59 self.0.capacity()
60 }
61 fn is_empty(&self) -> bool {
62 self.0.is_empty()
63 }
64 fn new() -> Self {
65 Self(Vec::new())
66 }
67 fn push(&mut self, item: Self::Item) {
68 self.0.push(item)
69 }
70 fn remove(&mut self, index: usize) -> Self::Item {
71 self.0.remove(index)
72 }
73 fn reserve(&mut self, additional: usize) {
74 self.0.reserve(additional)
75 }
76 fn retain<F>(&mut self, f: F)
77 where
78 F: FnMut(&Self::Item) -> bool,
79 {
80 self.0.retain(f)
81 }
82 fn swap_remove(&mut self, index: usize) -> Self::Item {
83 self.0.swap_remove(index)
84 }
85 fn with_capacity(capacity: usize) -> Self {
86 Self(Vec::with_capacity(capacity))
87 }
88}
89
90impl From<Matrix> for Vec<Vec<Scalar>> {
91 fn from(matrix: Matrix) -> Self {
92 matrix.into_iter().map(|vector| vector.into()).collect()
93 }
94}
95
96impl FromIterator<Vector> for Matrix {
97 fn from_iter<Ii: IntoIterator<Item = Vector>>(into_iterator: Ii) -> Self {
98 Self(Vec::from_iter(into_iterator))
99 }
100}
101
102impl Index<usize> for Matrix {
103 type Output = Vector;
104 fn index(&self, index: usize) -> &Self::Output {
105 &self.0[index]
106 }
107}
108
109impl IndexMut<usize> for Matrix {
110 fn index_mut(&mut self, index: usize) -> &mut Self::Output {
111 &mut self.0[index]
112 }
113}
114
115impl IntoIterator for Matrix {
116 type Item = Vector;
117 type IntoIter = std::vec::IntoIter<Self::Item>;
118 fn into_iter(self) -> Self::IntoIter {
119 self.0.into_iter()
120 }
121}
122
123impl Sum for Matrix {
124 fn sum<Ii>(iter: Ii) -> Self
125 where
126 Ii: Iterator<Item = Self>,
127 {
128 iter.reduce(|mut acc, item| {
129 acc += item;
130 acc
131 })
132 .unwrap_or_else(Self::default)
133 }
134}
135
136impl Div<Scalar> for Matrix {
137 type Output = Self;
138 fn div(mut self, scalar: Scalar) -> Self::Output {
139 self /= scalar;
140 self
141 }
142}
143
144impl DivAssign<Scalar> for Matrix {
145 fn div_assign(&mut self, scalar: Scalar) {
146 self.iter_mut().for_each(|entry| *entry /= &scalar);
147 }
148}
149
150impl Mul<Vector> for &Matrix {
151 type Output = Vector;
152 fn mul(self, vector: Vector) -> Self::Output {
153 self.iter().map(|self_i| self_i * &vector).collect()
154 }
155}
156
157impl Mul<&Vector> for &Matrix {
158 type Output = Vector;
159 fn mul(self, vector: &Vector) -> Self::Output {
160 self.iter().map(|self_i| self_i * vector).collect()
161 }
162}
163
164impl Mul<Scalar> for Matrix {
165 type Output = Matrix;
166 fn mul(mut self, scalar: Scalar) -> Self::Output {
167 self *= scalar;
168 self
169 }
170}
171
172impl Mul<&Scalar> for &Matrix {
173 type Output = Vector;
174 fn mul(self, _scalar: &Scalar) -> Self::Output {
175 unimplemented!()
176 }
177}
178
179impl<U> Mul<&Quantity<U>> for &Matrix {
180 type Output = Vector;
181 fn mul(self, _quantity: &Quantity<U>) -> Self::Output {
182 unimplemented!()
183 }
184}
185
186impl MulAssign<Scalar> for Matrix {
187 fn mul_assign(&mut self, scalar: Scalar) {
188 self.iter_mut().for_each(|entry| *entry *= &scalar);
189 }
190}
191
192impl Add for Matrix {
193 type Output = Self;
194 fn add(mut self, matrix: Self) -> Self::Output {
195 self += matrix;
196 self
197 }
198}
199
200impl Add<&Self> for Matrix {
201 type Output = Self;
202 fn add(mut self, matrix: &Self) -> Self::Output {
203 self += matrix;
204 self
205 }
206}
207
208impl AddAssign for Matrix {
209 fn add_assign(&mut self, matrix: Self) {
210 self.iter_mut()
211 .zip(matrix)
212 .for_each(|(self_i, matrix_i)| *self_i += matrix_i);
213 }
214}
215
216impl AddAssign<&Self> for Matrix {
217 fn add_assign(&mut self, matrix: &Self) {
218 self.iter_mut()
219 .zip(matrix.iter())
220 .for_each(|(self_entry, scalar)| *self_entry += scalar);
221 }
222}
223
224impl Sub for Matrix {
225 type Output = Self;
226 fn sub(mut self, matrix: Self) -> Self::Output {
227 self -= matrix;
228 self
229 }
230}
231
232impl Sub<&Self> for Matrix {
233 type Output = Self;
234 fn sub(mut self, matrix: &Self) -> Self::Output {
235 self -= matrix;
236 self
237 }
238}
239
240impl SubAssign for Matrix {
241 fn sub_assign(&mut self, matrix: Self) {
242 self.iter_mut()
243 .zip(matrix)
244 .for_each(|(self_i, matrix_i)| *self_i -= matrix_i);
245 }
246}
247
248impl SubAssign<&Self> for Matrix {
249 fn sub_assign(&mut self, matrix: &Self) {
250 self.iter_mut()
251 .zip(matrix.iter())
252 .for_each(|(self_entry, scalar)| *self_entry -= scalar);
253 }
254}
255
256impl<const D: usize, I, U> Mul<&TensorRank1<D, I, U>> for &Matrix {
257 type Output = Vector;
258 fn mul(self, _tensor_rank_1: &TensorRank1<D, I, U>) -> Self::Output {
259 unimplemented!()
260 }
261}
262
263impl<const D: usize, I, U> Mul<&TensorRank1Vec<D, I, U>> for &Matrix {
264 type Output = Vector;
265 fn mul(self, tensor_rank_1_vec: &TensorRank1Vec<D, I, U>) -> Self::Output {
266 self.iter()
267 .map(|self_i| self_i * tensor_rank_1_vec)
268 .collect()
269 }
270}
271
272impl<U> Mul<&QuantityVector<U>> for &Matrix {
273 type Output = Vector;
274 fn mul(self, quantity_vector: &QuantityVector<U>) -> Self::Output {
275 self.iter().map(|self_i| self_i * quantity_vector).collect()
276 }
277}
278
279impl<const D: usize, I, J, U> Mul<&TensorRank2<D, I, J, U>> for &Matrix {
280 type Output = Vector;
281 fn mul(self, tensor_rank_2: &TensorRank2<D, I, J, U>) -> Self::Output {
282 self.iter().map(|self_i| self_i * tensor_rank_2).collect()
283 }
284}
285
286impl<const D: usize, I, J, K, L, U, V>
287 Mul<&TensorTuple<TensorRank2<D, I, J, U>, TensorRank2<D, K, L, V>>> for &Matrix
288{
289 type Output = Vector;
290 fn mul(
291 self,
292 tensor_tuple: &TensorTuple<TensorRank2<D, I, J, U>, TensorRank2<D, K, L, V>>,
293 ) -> Self::Output {
294 self.iter().map(|self_i| self_i * tensor_tuple).collect()
295 }
296}
297
298impl Mul for Matrix {
299 type Output = Self;
300 fn mul(self, matrix: Self) -> Self::Output {
301 let mut output = Self::zero(self.len(), matrix.width());
302 self.iter()
303 .zip(output.iter_mut())
304 .for_each(|(self_i, output_i)| {
305 self_i
306 .iter()
307 .zip(matrix.iter())
308 .for_each(|(self_ij, matrix_j)| *output_i += matrix_j * self_ij)
309 });
310 output
311 }
312}