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::ops::{Index, IndexMut, Mul};
8use vector::Vector;
9
10/// A matrix.
11#[derive(Clone, Debug, PartialEq)]
12pub struct Matrix(Vec<Vector>);
13
14impl Matrix {
15    pub fn height(&self) -> usize {
16        self.0.len()
17    }
18    pub fn is_empty(&self) -> bool {
19        self.0.is_empty()
20    }
21    pub fn iter(&self) -> impl Iterator<Item = &Vector> {
22        self.0.iter()
23    }
24    pub fn iter_mut(&mut self) -> impl Iterator<Item = &mut Vector> {
25        self.0.iter_mut()
26    }
27    pub fn len(&self) -> usize {
28        self.0.len()
29    }
30    pub fn transpose(&self) -> Self {
31        (0..self.width())
32            .map(|i| (0..self.len()).map(|j| self[j][i]).collect())
33            .collect()
34        // let mut transpose = Self::zero(self.width(), self.len());
35        // self.iter().enumerate().for_each(|(i, self_i)|
36        //     self_i.iter().zip(transpose.iter_mut()).for_each(|(self_ij, transpose_j)|
37        //         transpose_j[i] = *self_ij
38        //     )
39        // );
40        // transpose
41    }
42    pub fn width(&self) -> usize {
43        self.0[0].len()
44    }
45    pub fn zero(height: usize, width: usize) -> Self {
46        (0..height).map(|_| Vector::zero(width)).collect()
47    }
48}
49
50impl TensorVec for Matrix {
51    type Item = Vector;
52    fn append(&mut self, other: &mut Self) {
53        self.0.append(&mut other.0)
54    }
55    fn capacity(&self) -> usize {
56        self.0.capacity()
57    }
58    fn is_empty(&self) -> bool {
59        self.0.is_empty()
60    }
61    fn new() -> Self {
62        Self(Vec::new())
63    }
64    fn push(&mut self, item: Self::Item) {
65        self.0.push(item)
66    }
67    fn remove(&mut self, index: usize) -> Self::Item {
68        self.0.remove(index)
69    }
70    fn retain<F>(&mut self, f: F)
71    where
72        F: FnMut(&Self::Item) -> bool,
73    {
74        self.0.retain(f)
75    }
76    fn swap_remove(&mut self, index: usize) -> Self::Item {
77        self.0.swap_remove(index)
78    }
79}
80
81impl From<Matrix> for Vec<Vec<Scalar>> {
82    fn from(matrix: Matrix) -> Self {
83        matrix.into_iter().map(|vector| vector.into()).collect()
84    }
85}
86
87impl FromIterator<Vector> for Matrix {
88    fn from_iter<Ii: IntoIterator<Item = Vector>>(into_iterator: Ii) -> Self {
89        Self(Vec::from_iter(into_iterator))
90    }
91}
92
93impl Index<usize> for Matrix {
94    type Output = Vector;
95    fn index(&self, index: usize) -> &Self::Output {
96        &self.0[index]
97    }
98}
99
100impl IndexMut<usize> for Matrix {
101    fn index_mut(&mut self, index: usize) -> &mut Self::Output {
102        &mut self.0[index]
103    }
104}
105
106impl IntoIterator for Matrix {
107    type Item = Vector;
108    type IntoIter = std::vec::IntoIter<Self::Item>;
109    fn into_iter(self) -> Self::IntoIter {
110        self.0.into_iter()
111    }
112}
113
114impl Mul<Vector> for &Matrix {
115    type Output = Vector;
116    fn mul(self, vector: Vector) -> Self::Output {
117        self.iter().map(|self_i| self_i * &vector).collect()
118    }
119}
120
121impl Mul<&Vector> for &Matrix {
122    type Output = Vector;
123    fn mul(self, vector: &Vector) -> Self::Output {
124        self.iter().map(|self_i| self_i * vector).collect()
125    }
126}
127
128impl Mul<&Scalar> for &Matrix {
129    type Output = Vector;
130    fn mul(self, _tensor_rank_0: &Scalar) -> Self::Output {
131        unimplemented!()
132    }
133}
134
135impl<const D: usize, const I: usize> Mul<&TensorRank1<D, I>> for &Matrix {
136    type Output = Vector;
137    fn mul(self, _tensor_rank_1: &TensorRank1<D, I>) -> Self::Output {
138        unimplemented!()
139    }
140}
141
142impl<const D: usize, const I: usize> Mul<&TensorRank1Vec<D, I>> for &Matrix {
143    type Output = Vector;
144    fn mul(self, tensor_rank_1_vec: &TensorRank1Vec<D, I>) -> Self::Output {
145        self.iter()
146            .map(|self_i| self_i * tensor_rank_1_vec)
147            .collect()
148    }
149}
150
151impl<const D: usize, const I: usize, const J: usize> Mul<&TensorRank2<D, I, J>> for &Matrix {
152    type Output = Vector;
153    fn mul(self, tensor_rank_2: &TensorRank2<D, I, J>) -> Self::Output {
154        self.iter().map(|self_i| self_i * tensor_rank_2).collect()
155    }
156}
157
158impl<const D: usize, const I: usize, const J: usize, const K: usize, const L: usize>
159    Mul<&TensorTuple<TensorRank2<D, I, J>, TensorRank2<D, K, L>>> for &Matrix
160{
161    type Output = Vector;
162    fn mul(
163        self,
164        tensor_tuple: &TensorTuple<TensorRank2<D, I, J>, TensorRank2<D, K, L>>,
165    ) -> Self::Output {
166        self.iter().map(|self_i| self_i * tensor_tuple).collect()
167    }
168}
169
170impl Mul for Matrix {
171    type Output = Self;
172    fn mul(self, matrix: Self) -> Self::Output {
173        let mut output = Self::zero(self.len(), matrix.width());
174        self.iter()
175            .zip(output.iter_mut())
176            .for_each(|(self_i, output_i)| {
177                self_i
178                    .iter()
179                    .zip(matrix.iter())
180                    .for_each(|(self_ij, matrix_j)| *output_i += matrix_j * self_ij)
181            });
182        output
183    }
184}