Skip to main content

conspire/math/matrix/
mod.rs

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/// A matrix.
15#[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}