Skip to main content

conspire/math/matrix/
mod.rs

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