array_matrix/matrix.rs
1use num_traits::One;
2use num_traits::Zero;
3
4pub mod det;
5pub mod submatrix;
6pub mod inv;
7pub mod transpose;
8pub mod add;
9pub mod sub;
10pub mod trace;
11pub mod adj;
12pub mod minor;
13pub mod cofactor;
14pub mod kronecker;
15pub mod mul;
16pub mod conj;
17pub mod herm;
18pub mod eig;
19pub mod diag;
20pub mod qr_householder;
21pub mod div;
22
23pub use self::det::*;
24pub use self::submatrix::*;
25pub use self::inv::*;
26pub use self::transpose::*;
27pub use self::add::*;
28pub use self::sub::*;
29pub use self::trace::*;
30pub use self::adj::*;
31pub use self::minor::*;
32pub use self::cofactor::*;
33pub use self::kronecker::*;
34pub use self::mul::*;
35pub use self::conj::*;
36pub use self::herm::*;
37pub use self::eig::*;
38pub use self::diag::*;
39pub use self::qr_householder::*;
40pub use self::div::*;
41
42pub trait Matrix: Sized
43{
44 /// Returns the height of the given matrix
45 ///
46 /// # Examples
47 ///
48 /// ```rust
49 /// # #![feature(generic_const_exprs)]
50 /// # #![allow(unused)]
51 /// # extern crate matrix;
52 /// # extern crate num_traits;
53 /// # extern crate array_init;
54 /// #
55 /// let a = [
56 /// [1.0, 2.0, 3.0],
57 /// [4.0, 5.0, 6.0]
58 /// ];
59 /// assert_eq!(a.height(), 2);
60 /// ```
61 fn height(&self) -> usize;
62
63 /// Returns the length of the given matrix
64 ///
65 /// # Examples
66 ///
67 /// ```rust
68 /// # #![feature(generic_const_exprs)]
69 /// # #![allow(unused)]
70 /// # extern crate matrix;
71 /// # extern crate num_traits;
72 /// # extern crate array_init;
73 /// #
74 /// let a = [
75 /// [1.0, 2.0, 3.0],
76 /// [4.0, 5.0, 6.0]
77 /// ];
78 /// assert_eq!(a.length(), 3);
79 /// ```
80 fn length(&self) -> usize;
81
82 /// Returns an empty matrix with the given dimensions
83 ///
84 /// # Examples
85 ///
86 /// ```rust
87 /// # #![feature(generic_const_exprs)]
88 /// # #![allow(unused)]
89 /// # extern crate matrix;
90 /// # extern crate num_traits;
91 /// # extern crate array_init;
92 /// #
93 /// let a = [
94 /// [0.0, 0.0],
95 /// [0.0, 0.0]
96 /// ]
97 /// assert_eq!(a, Matrix::empty())
98 /// ```
99 fn empty() -> Self;
100}
101
102/// Initialize a matrix given an initializer expression.
103/// The initializer is given the row- and collumn-indices of the cell.
104/// It is allowed to mutate external state; we will always initialize the cells in order.
105///
106/// # Examples
107///
108/// ```rust
109/// # #![feature(generic_const_exprs)]
110/// # #![allow(unused)]
111/// # extern crate matrix;
112/// # extern crate num_traits;
113/// # extern crate array_init;
114/// #
115/// let a: [[f64; 3]; 3] = matrix_init(|r, c| (r * c) as f64);
116///
117/// assert!(arr.iter().enumerate().all(|(r, ar)| ar.iter().enumerate().all(|(c, &arc)| arc == (r * c) as f64)));
118/// ```
119pub fn matrix_init<F, T, const L: usize, const H: usize>(mut initializer: F) -> [[T; L]; H]
120where
121 F: FnMut(usize, usize) -> T,
122{
123 use array_init::array_init;
124
125 array_init(|r| array_init(|c| initializer(r, c)))
126}
127
128impl<F: Zero, const L: usize, const H: usize> Matrix for [[F; L]; H]
129where [[F; L - 1 as usize]; H - 1]:
130{
131 fn height(&self) -> usize
132 {
133 H
134 }
135 fn length(&self) -> usize
136 {
137 L
138 }
139 fn empty() -> Self
140 {
141 matrix_init(|_, _| F::zero())
142 }
143}
144
145pub trait SquareMatrix: Matrix
146{
147 /// Returns the identity matrix with the given dimensions
148 ///
149 /// # Examples
150 ///
151 /// ```rust
152 /// # #![feature(generic_const_exprs)]
153 /// # #![allow(unused)]
154 /// # extern crate matrix;
155 /// # extern crate num_traits;
156 /// # extern crate array_init;
157 /// let a = [
158 /// [1.0, 0.0],
159 /// [0.0, 1.0]
160 /// ]
161 /// assert_eq!(a, SquareMatrix::identity())
162 /// ```
163 fn identity() -> Self;
164}
165
166impl<F: One + Zero, const N: usize> SquareMatrix for [[F; N]; N]
167where
168 Self: Matrix,
169 [[F; N - 1 as usize]; N - 1]:
170{
171 fn identity() -> Self
172 {
173 matrix_init(|r, c| if r == c {F::one()} else {F::zero()})
174 }
175}