conspire/math/matrix/
mod.rs

1pub mod square;
2pub mod vector;
3
4use crate::math::{Tensor, TensorRank0, TensorRank1Vec, TensorRank2, TensorVec};
5use std::ops::{Index, IndexMut, Mul};
6use vector::Vector;
7
8/// A matrix.
9#[derive(Clone, Debug, PartialEq)]
10pub struct Matrix(Vec<Vector>);
11
12impl Matrix {
13    pub fn height(&self) -> usize {
14        self.0.len()
15    }
16    pub fn is_empty(&self) -> bool {
17        self.0.is_empty()
18    }
19    pub fn iter(&self) -> impl Iterator<Item = &Vector> {
20        self.0.iter()
21    }
22    pub fn iter_mut(&mut self) -> impl Iterator<Item = &mut Vector> {
23        self.0.iter_mut()
24    }
25    pub fn len(&self) -> usize {
26        self.0.len()
27    }
28    pub fn transpose(&self) -> Self {
29        (0..self.width())
30            .map(|i| (0..self.len()).map(|j| self[j][i]).collect())
31            .collect()
32        // let mut transpose = Self::zero(self.width(), self.len());
33        // self.iter().enumerate().for_each(|(i, self_i)|
34        //     self_i.iter().zip(transpose.iter_mut()).for_each(|(self_ij, transpose_j)|
35        //         transpose_j[i] = *self_ij
36        //     )
37        // );
38        // transpose
39    }
40    pub fn width(&self) -> usize {
41        self.0[0].len()
42    }
43    pub fn zero(height: usize, width: usize) -> Self {
44        (0..height).map(|_| Vector::zero(width)).collect()
45    }
46}
47
48impl FromIterator<Vector> for Matrix {
49    fn from_iter<Ii: IntoIterator<Item = Vector>>(into_iterator: Ii) -> Self {
50        Self(Vec::from_iter(into_iterator))
51    }
52}
53
54impl Index<usize> for Matrix {
55    type Output = Vector;
56    fn index(&self, index: usize) -> &Self::Output {
57        &self.0[index]
58    }
59}
60
61impl IndexMut<usize> for Matrix {
62    fn index_mut(&mut self, index: usize) -> &mut Self::Output {
63        &mut self.0[index]
64    }
65}
66
67impl IntoIterator for Matrix {
68    type Item = Vector;
69    type IntoIter = std::vec::IntoIter<Self::Item>;
70    fn into_iter(self) -> Self::IntoIter {
71        self.0.into_iter()
72    }
73}
74
75impl Mul<Vector> for &Matrix {
76    type Output = Vector;
77    fn mul(self, vector: Vector) -> Self::Output {
78        self.iter().map(|self_i| self_i * &vector).collect()
79    }
80}
81
82impl Mul<&Vector> for &Matrix {
83    type Output = Vector;
84    fn mul(self, vector: &Vector) -> Self::Output {
85        self.iter().map(|self_i| self_i * vector).collect()
86    }
87}
88
89impl Mul<&TensorRank0> for &Matrix {
90    type Output = Vector;
91    fn mul(self, _tensor_rank_0: &TensorRank0) -> Self::Output {
92        panic!()
93    }
94}
95
96impl<const D: usize, const I: usize> Mul<&TensorRank1Vec<D, I>> for &Matrix {
97    type Output = Vector;
98    fn mul(self, tensor_rank_1_vec: &TensorRank1Vec<D, I>) -> Self::Output {
99        self.iter()
100            .map(|self_i| self_i * tensor_rank_1_vec)
101            .collect()
102    }
103}
104
105impl<const D: usize, const I: usize, const J: usize> Mul<&TensorRank2<D, I, J>> for &Matrix {
106    type Output = Vector;
107    fn mul(self, tensor_rank_2: &TensorRank2<D, I, J>) -> Self::Output {
108        self.iter().map(|self_i| self_i * tensor_rank_2).collect()
109    }
110}
111
112impl Mul for Matrix {
113    type Output = Self;
114    fn mul(self, matrix: Self) -> Self::Output {
115        let mut output = Self::zero(self.len(), matrix.width());
116        self.iter()
117            .zip(output.iter_mut())
118            .for_each(|(self_i, output_i)| {
119                self_i
120                    .iter()
121                    .zip(matrix.iter())
122                    .for_each(|(self_ij, matrix_j)| *output_i += matrix_j * self_ij)
123            });
124        output
125    }
126}