pub struct Matrix<T, const M: usize, const N: usize> {
pub store: [[T; N]; M],
}
Expand description
A generic matrix type with M
rows and N
columns.
§Examples
use mini_matrix::Matrix;
let matrix = Matrix::<f64, 2, 2>::from([[1.0, 2.0], [3.0, 4.0]]);
assert_eq!(matrix.size(), (2, 2));
Fields§
§store: [[T; N]; M]
The underlying storage for the matrix elements.
Implementations§
Source§impl<T, const M: usize, const N: usize> Matrix<T, M, N>
impl<T, const M: usize, const N: usize> Matrix<T, M, N>
Sourcepub fn from(data: [[T; N]; M]) -> Self
pub fn from(data: [[T; N]; M]) -> Self
Creates a new Matrix
from the given 2D array.
§Examples
use mini_matrix::Matrix;
let matrix = Matrix::<i32, 2, 3>::from([[1, 2, 3], [4, 5, 6]]);
Sourcepub const fn size(&self) -> (usize, usize)
pub const fn size(&self) -> (usize, usize)
Returns the dimensions of the matrix as a tuple (rows, columns)
.
§Examples
use mini_matrix::Matrix;
let matrix = Matrix::<f64, 3, 4>::zero();
assert_eq!(matrix.size(), (3, 4));
Sourcepub fn zero() -> Self
pub fn zero() -> Self
Creates a new Matrix
with all elements set to the default value of type T
.
§Examples
use mini_matrix::Matrix;
let matrix = Matrix::<f64, 2, 2>::zero();
assert_eq!(matrix.store, [[0.0, 0.0], [0.0, 0.0]]);
pub fn from_vecs(vecs: Vec<Vec<T>>) -> Self
Source§impl<T, const M: usize, const N: usize> Matrix<T, M, N>
impl<T, const M: usize, const N: usize> Matrix<T, M, N>
Sourcepub fn add(&mut self, other: &Self)
pub fn add(&mut self, other: &Self)
Adds another matrix to this matrix in-place.
§Examples
use mini_matrix::Matrix;
let mut a = Matrix::<i32, 2, 2>::from([[1, 2], [3, 4]]);
let b = Matrix::<i32, 2, 2>::from([[5, 6], [7, 8]]);
a.add(&b);
assert_eq!(a.store, [[6, 8], [10, 12]]);
Source§impl<T, const M: usize, const N: usize> Matrix<T, M, N>
impl<T, const M: usize, const N: usize> Matrix<T, M, N>
Source§impl<T, const M: usize, const N: usize> Matrix<T, M, N>
impl<T, const M: usize, const N: usize> Matrix<T, M, N>
Sourcepub fn trace(&self) -> T
pub fn trace(&self) -> T
Calculates the trace of the matrix.
The trace is defined as the sum of the elements on the main diagonal.
§Panics
Panics if the matrix is not square (i.e., if M != N).
§Examples
use mini_matrix::Matrix;
let mut a = Matrix::<i32, 3, 3>::from([[1, 2, 3], [4, 5, 6], [7, 8, 9]]);
assert_eq!(a.trace(), 15);
Source§impl<T, const M: usize, const N: usize> Matrix<T, M, N>
impl<T, const M: usize, const N: usize> Matrix<T, M, N>
Sourcepub fn row_echelon(&self) -> Matrix<T, M, N>
pub fn row_echelon(&self) -> Matrix<T, M, N>
Converts a given matrix to its Reduced Row-Echelon Form (RREF).
Row-echelon form is a specific form of a matrix that is particularly useful for solving systems of linear equations and for understanding the properties of the matrix. To explain it simply and in detail, let’s go through what row-echelon form is, how to achieve it, and an example to illustrate the process.
§Row-Echelon Form
A matrix is in row-echelon form if it satisfies the following conditions:
- Leading Entry: The leading entry (first non-zero number from the left) in each row is 1. This is called the pivot.
- Zeros Below: The pivot in each row is to the right of the pivot in the row above, and all entries below a pivot are zeros.
- Rows of Zeros: Any rows consisting entirely of zeros are at the bottom of the matrix.
§Reduced Row-Echelon Form
A matrix is in reduced row-echelon form (RREF) if it additionally satisfies:
- Leading Entries: Each leading 1 is the only non-zero entry in its column.
§Achieving Row-Echelon Form
To convert a matrix into row-echelon form, we use a process called Gaussian elimination. This involves performing row operations:
- Row swapping: Swapping the positions of two rows.
- Row multiplication: Multiplying all entries of a row by a non-zero scalar.
- Row addition: Adding or subtracting the multiples of one row to another row.
Let’s consider an example with a 3 x 3
matrix:
A = [ [1, 2, 3], [4, 5, 6], [7, 8, 9] ]
§Step-by-Step Process
-
Starting Matrix:
[ [1, 2, 3], [4, 5, 6], [7, 8, 9] ]
-
Make the Pivot of Row 1 (already 1):
The first leading entry is already 1.
-
Eliminate Below Pivot in Column 1:
Subtract 4 times the first row from the second row:
R2 = R2 - 4R1
[
[1, 2, 3],
[0, -3, -6],
[7, 8, 9]
]
Subtract 7 times the first row from the third row:
R3 = R3 - 7R1
[
[1, 2, 3],
[0, -3, -6],
[0, -6, -12]
]
-
Make the Pivot of Row 2:
Divide the second row by -3 to make the pivot 1:
R2 = (1 / -3) * R2
[
[1, 2, 3],
[0, 1, 2],
[0, -6, -12]
]
5. **Eliminate Below Pivot in Column 2**:
Add 6 times the second row to the third row:
```markdown
R3 = R3 + 6R2
[
[1, 2, 3],
[0, 1, 2],
[0, 0, 0]
]
Now, the matrix is in row-echelon form.
§Examples
use mini_matrix::Matrix;
let a = Matrix::<f64, 3, 4>::from([
[1.0, 2.0, 3.0, 4.0],
[5.0, 6.0, 7.0, 8.0],
[9.0, 10.0, 11.0, 12.0]
]);
let b = a.row_echelon();
// Check the result (approximate due to floating-point arithmetic)
Source§impl<T, const M: usize, const N: usize> Matrix<T, M, N>
impl<T, const M: usize, const N: usize> Matrix<T, M, N>
Sourcepub fn determinant(&self) -> T
pub fn determinant(&self) -> T
Computes the determinant of the matrix.
§Determinant in General
The determinant is a scalar value that can be computed from the elements of a square matrix. It provides important properties about the matrix and the linear transformation it represents. In general, the determinant represents the scaling factor of the volume when the matrix is used as a linear transformation. It can be positive, negative, or zero, each with different implications:
-
(\det(A) = 0):
- The matrix
A
is singular and does not have an inverse. - The columns (or rows) of
A
are linearly dependent. - The transformation collapses the space into a lower-dimensional subspace.
- Geometrically, it indicates that the volume of the transformed space is 0.
- The matrix
-
(\det(A) > 0):
- The matrix
A
is non-singular and has an inverse. - The transformation preserves the orientation of the space.
- Geometrically, it indicates a positive scaling factor of the volume.
- The matrix
-
(\det(A) < 0):
- The matrix
A
is non-singular and has an inverse. - The transformation reverses the orientation of the space.
- Geometrically, it indicates a negative scaling factor of the volume.
- The matrix
§Example
Consider a 2 x 2
matrix:
A = [
[1, 2],
[3, 4]
]
The determinant is:
det(A) = 1 * 4 - 2 * 3 = 4 - 6 = -2
This indicates that the transformation represented by A
scales areas by a factor of 2 and
reverses their orientation.
§Panics
Panics if the matrix size is larger than 4 x 4
.
§Returns
The determinant of the matrix.
§Examples
use mini_matrix::Matrix;
let a = Matrix::<i32, 3, 3>::from([[1, 2, 3], [4, 5, 6], [7, 8, 9]]);
assert_eq!(a.determinant(), 0);
Source§impl<T, const M: usize, const N: usize> Matrix<T, M, N>
impl<T, const M: usize, const N: usize> Matrix<T, M, N>
Sourcepub fn inverse(&self) -> Result<Self, &'static str>
pub fn inverse(&self) -> Result<Self, &'static str>
Calculates the inverse of the matrix.
This method supports matrices up to 3x3 in size.
§Returns
Returns Ok(Matrix)
if the inverse exists, or an Err
with a descriptive message if not.
§Examples
use mini_matrix::Matrix;
let a = Matrix::<f64, 2, 2>::from([[1.0, 2.0], [3.0, 4.0]]);
let inv = a.inverse().unwrap();
// Check the result (approximate due to floating-point arithmetic)
Trait Implementations§
Source§impl<T, const M: usize, const N: usize> Add for Matrix<T, M, N>
impl<T, const M: usize, const N: usize> Add for Matrix<T, M, N>
Source§impl<T, const M: usize, const N: usize> Deref for Matrix<T, M, N>
impl<T, const M: usize, const N: usize> Deref for Matrix<T, M, N>
Source§impl<T, const M: usize, const N: usize> DerefMut for Matrix<T, M, N>
impl<T, const M: usize, const N: usize> DerefMut for Matrix<T, M, N>
Source§impl<T, const M: usize, const N: usize> Display for Matrix<T, M, N>
impl<T, const M: usize, const N: usize> Display for Matrix<T, M, N>
Source§fn fmt(&self, f: &mut Formatter<'_>) -> Result
fn fmt(&self, f: &mut Formatter<'_>) -> Result
Formats the matrix for display.
Each row of the matrix is displayed on a new line, with elements separated by commas. Elements are formatted with one decimal place precision.
§Examples
use mini_matrix::Matrix;
let a = Matrix::<f32, 2, 2>::from([[1.0, 2.5], [3.7, 4.2]]);
println!("{}", a);
// Output:
// // [1.0, 2.5]
// // [3.7, 4.2]
Source§impl<T, const M: usize, const N: usize> Index<(usize, usize)> for Matrix<T, M, N>
impl<T, const M: usize, const N: usize> Index<(usize, usize)> for Matrix<T, M, N>
Source§impl<T, const M: usize, const N: usize> IndexMut<(usize, usize)> for Matrix<T, M, N>
impl<T, const M: usize, const N: usize> IndexMut<(usize, usize)> for Matrix<T, M, N>
Source§fn index_mut(&mut self, index: (usize, usize)) -> &mut T
fn index_mut(&mut self, index: (usize, usize)) -> &mut T
Mutably indexes into the matrix, allowing modification of its elements.
§Arguments
index
- A tuple(row, column)
specifying the element to access.
§Examples
use mini_matrix::Matrix;
let mut matrix = Matrix::<i32, 2, 2>::from([[1, 2], [3, 4]]);
matrix[(0, 1)] = 5;
assert_eq!(matrix.store, [[1, 5], [3, 4]]);