numberlab/structure/matrix/matrix_functions.rs
1use crate::structure::matrix::matrix_trait::MatrixDataTrait;
2use crate::structure::matrix::Matrix;
3
4/// Creates an identity matrix of the given size.
5///
6/// An identity matrix is a square matrix with ones on the main diagonal and zeros elsewhere.
7///
8/// # Type Parameters
9///
10/// * `T` - The type of the elements in the matrix.
11/// * `SIZE` - The number of rows and columns in the matrix.
12///
13/// # Returns
14///
15/// An identity matrix of the given size.
16///
17/// # Example
18///
19/// ```
20/// use numberlab::structure::matrix::{Matrix, identity};
21///
22/// let matrix = identity::<i32, 3>();
23///
24/// assert_eq!(matrix[(0, 0)], 1);
25/// assert_eq!(matrix[(1, 1)], 1);
26/// assert_eq!(matrix[(2, 2)], 1);
27/// assert_eq!(matrix[(0, 1)], 0);
28/// assert_eq!(matrix[(0, 2)], 0);
29/// assert_eq!(matrix[(1, 0)], 0);
30/// assert_eq!(matrix[(1, 2)], 0);
31/// assert_eq!(matrix[(2, 0)], 0);
32/// assert_eq!(matrix[(2, 1)], 0);
33/// ```
34pub fn identity<T: MatrixDataTrait, const SIZE: usize>() -> Matrix<T, SIZE, SIZE> {
35 let mut result = Matrix::<T, SIZE, SIZE>::new();
36 (0..SIZE).for_each(|i| result[(i, i)] = T::one());
37 result
38}
39
40/// Transposes the given matrix.
41///
42/// # Type Parameters
43///
44/// * `T` - The type of the elements in the matrix.
45/// * `ROWS` - The number of rows in the matrix.
46/// * `COLS` - The number of columns in the matrix.
47///
48/// # Arguments
49///
50/// * `matrix` - The matrix to be transposed.
51///
52/// # Returns
53///
54/// A new matrix that is the transpose of the given matrix.
55///
56/// # Example
57///
58/// ```
59/// use numberlab::structure::matrix::{Matrix, transpose};
60///
61/// let matrix = Matrix::<i32, 2, 3>::from_array([[1, 2, 3], [4, 5, 6]]);
62/// let transposed = transpose(matrix);
63///
64/// assert_eq!(transposed[(0, 0)], 1);
65/// assert_eq!(transposed[(1, 0)], 2);
66/// assert_eq!(transposed[(2, 0)], 3);
67/// assert_eq!(transposed[(0, 1)], 4);
68/// assert_eq!(transposed[(1, 1)], 5);
69/// assert_eq!(transposed[(2, 1)], 6);
70/// ```
71pub fn transpose<T: MatrixDataTrait, const ROWS: usize, const COLS: usize>(
72 matrix: Matrix<T, ROWS, COLS>,
73) -> Matrix<T, COLS, ROWS> {
74 let mut result = Matrix::<T, COLS, ROWS>::new();
75 for i in 0..ROWS {
76 for j in 0..COLS {
77 result[(j, i)] = matrix[(i, j)];
78 }
79 }
80 result
81}
82
83/// Converts the given matrix to its upper triangular form and returns it.
84///
85/// # Type Parameters
86///
87/// * `T` - The type of the elements in the matrix.
88/// * `SIZE` - The number of rows and columns in the matrix.
89///
90/// # Arguments
91///
92/// * `matrix` - The matrix to be converted.
93///
94/// # Returns
95///
96/// A new matrix that is the upper triangular form of the given matrix.
97///
98/// # Example
99///
100/// ```
101/// use numberlab::structure::matrix::{Matrix, upper_triangular};
102///
103/// let matrix = Matrix::<i32, 3, 3>::from_array([[1, 2, 3], [4, 5, 6], [7, 8, 9]]);
104/// let upper = upper_triangular(matrix);
105///
106/// assert_eq!(upper, Matrix::<i32, 3, 3>::from_array([[1, 2, 3], [0, 5, 6], [0, 0, 9]]));
107/// ```
108pub fn upper_triangular<T: MatrixDataTrait, const SIZE: usize>(
109 matrix: Matrix<T, SIZE, SIZE>,
110) -> Matrix<T, SIZE, SIZE> {
111 let mut result = matrix.clone();
112 for j in 0..SIZE {
113 for i in (j + 1)..SIZE {
114 result[(i, j)] = T::zero();
115 }
116 }
117 result
118}
119
120/// Converts the given matrix to its lower triangular form and returns it.
121///
122/// # Type Parameters
123///
124/// * `T` - The type of the elements in the matrix.
125/// * `SIZE` - The number of rows and columns in the matrix.
126///
127/// # Arguments
128///
129/// * `matrix` - The matrix to be converted.
130///
131/// # Returns
132///
133/// A new matrix that is the lower triangular form of the given matrix.
134///
135/// # Example
136///
137/// ```
138/// use numberlab::structure::matrix::{Matrix, lower_triangular};
139///
140/// let matrix = Matrix::<i32, 3, 3>::from_array([[1, 2, 3], [4, 5, 6], [7, 8, 9]]);
141/// let lower = lower_triangular(matrix);
142///
143/// assert_eq!(lower, Matrix::<i32, 3, 3>::from_array([[1, 0, 0], [4, 5, 0], [7, 8, 9]]));
144/// ```
145pub fn lower_triangular<T: MatrixDataTrait, const SIZE: usize>(
146 matrix: Matrix<T, SIZE, SIZE>,
147) -> Matrix<T, SIZE, SIZE> {
148 let mut result = matrix.clone();
149 for i in 0..SIZE {
150 for j in i + 1..SIZE {
151 result[(i, j)] = T::zero();
152 }
153 }
154 result
155}