Struct mini_matrix::Matrix
source · 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] ]
-
Eliminate Below Pivot in Column 2:
Add 6 times the second row to the third row:
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)
Methods from Deref<Target = [[T; N]; M]>§
sourcepub fn as_ascii(&self) -> Option<&[AsciiChar; N]>
🔬This is a nightly-only experimental API. (ascii_char
)
pub fn as_ascii(&self) -> Option<&[AsciiChar; N]>
ascii_char
)Converts this array of bytes into an array of ASCII characters,
or returns None
if any of the characters is non-ASCII.
§Examples
#![feature(ascii_char)]
#![feature(const_option)]
const HEX_DIGITS: [std::ascii::Char; 16] =
*b"0123456789abcdef".as_ascii().unwrap();
assert_eq!(HEX_DIGITS[1].as_str(), "1");
assert_eq!(HEX_DIGITS[10].as_str(), "a");
sourcepub unsafe fn as_ascii_unchecked(&self) -> &[AsciiChar; N]
🔬This is a nightly-only experimental API. (ascii_char
)
pub unsafe fn as_ascii_unchecked(&self) -> &[AsciiChar; N]
ascii_char
)Converts this array of bytes into an array of ASCII characters, without checking whether they’re valid.
§Safety
Every byte in the array must be in 0..=127
, or else this is UB.
1.57.0 · sourcepub fn as_slice(&self) -> &[T]
pub fn as_slice(&self) -> &[T]
Returns a slice containing the entire array. Equivalent to &s[..]
.
1.57.0 · sourcepub fn as_mut_slice(&mut self) -> &mut [T]
pub fn as_mut_slice(&mut self) -> &mut [T]
Returns a mutable slice containing the entire array. Equivalent to
&mut s[..]
.
1.77.0 · sourcepub fn each_ref(&self) -> [&T; N]
pub fn each_ref(&self) -> [&T; N]
Borrows each element and returns an array of references with the same
size as self
.
§Example
let floats = [3.1, 2.7, -1.0];
let float_refs: [&f64; 3] = floats.each_ref();
assert_eq!(float_refs, [&3.1, &2.7, &-1.0]);
This method is particularly useful if combined with other methods, like
map
. This way, you can avoid moving the original
array if its elements are not Copy
.
let strings = ["Ferris".to_string(), "♥".to_string(), "Rust".to_string()];
let is_ascii = strings.each_ref().map(|s| s.is_ascii());
assert_eq!(is_ascii, [true, false, true]);
// We can still access the original array: it has not been moved.
assert_eq!(strings.len(), 3);
1.77.0 · sourcepub fn each_mut(&mut self) -> [&mut T; N]
pub fn each_mut(&mut self) -> [&mut T; N]
Borrows each element mutably and returns an array of mutable references
with the same size as self
.
§Example
let mut floats = [3.1, 2.7, -1.0];
let float_refs: [&mut f64; 3] = floats.each_mut();
*float_refs[0] = 0.0;
assert_eq!(float_refs, [&mut 0.0, &mut 2.7, &mut -1.0]);
assert_eq!(floats, [0.0, 2.7, -1.0]);
sourcepub fn split_array_ref<const M: usize>(&self) -> (&[T; M], &[T])
🔬This is a nightly-only experimental API. (split_array
)
pub fn split_array_ref<const M: usize>(&self) -> (&[T; M], &[T])
split_array
)Divides one array reference into two at an index.
The first will contain all indices from [0, M)
(excluding
the index M
itself) and the second will contain all
indices from [M, N)
(excluding the index N
itself).
§Panics
Panics if M > N
.
§Examples
#![feature(split_array)]
let v = [1, 2, 3, 4, 5, 6];
{
let (left, right) = v.split_array_ref::<0>();
assert_eq!(left, &[]);
assert_eq!(right, &[1, 2, 3, 4, 5, 6]);
}
{
let (left, right) = v.split_array_ref::<2>();
assert_eq!(left, &[1, 2]);
assert_eq!(right, &[3, 4, 5, 6]);
}
{
let (left, right) = v.split_array_ref::<6>();
assert_eq!(left, &[1, 2, 3, 4, 5, 6]);
assert_eq!(right, &[]);
}
sourcepub fn split_array_mut<const M: usize>(&mut self) -> (&mut [T; M], &mut [T])
🔬This is a nightly-only experimental API. (split_array
)
pub fn split_array_mut<const M: usize>(&mut self) -> (&mut [T; M], &mut [T])
split_array
)Divides one mutable array reference into two at an index.
The first will contain all indices from [0, M)
(excluding
the index M
itself) and the second will contain all
indices from [M, N)
(excluding the index N
itself).
§Panics
Panics if M > N
.
§Examples
#![feature(split_array)]
let mut v = [1, 0, 3, 0, 5, 6];
let (left, right) = v.split_array_mut::<2>();
assert_eq!(left, &mut [1, 0][..]);
assert_eq!(right, &mut [3, 0, 5, 6]);
left[1] = 2;
right[1] = 4;
assert_eq!(v, [1, 2, 3, 4, 5, 6]);
sourcepub fn rsplit_array_ref<const M: usize>(&self) -> (&[T], &[T; M])
🔬This is a nightly-only experimental API. (split_array
)
pub fn rsplit_array_ref<const M: usize>(&self) -> (&[T], &[T; M])
split_array
)Divides one array reference into two at an index from the end.
The first will contain all indices from [0, N - M)
(excluding
the index N - M
itself) and the second will contain all
indices from [N - M, N)
(excluding the index N
itself).
§Panics
Panics if M > N
.
§Examples
#![feature(split_array)]
let v = [1, 2, 3, 4, 5, 6];
{
let (left, right) = v.rsplit_array_ref::<0>();
assert_eq!(left, &[1, 2, 3, 4, 5, 6]);
assert_eq!(right, &[]);
}
{
let (left, right) = v.rsplit_array_ref::<2>();
assert_eq!(left, &[1, 2, 3, 4]);
assert_eq!(right, &[5, 6]);
}
{
let (left, right) = v.rsplit_array_ref::<6>();
assert_eq!(left, &[]);
assert_eq!(right, &[1, 2, 3, 4, 5, 6]);
}
sourcepub fn rsplit_array_mut<const M: usize>(&mut self) -> (&mut [T], &mut [T; M])
🔬This is a nightly-only experimental API. (split_array
)
pub fn rsplit_array_mut<const M: usize>(&mut self) -> (&mut [T], &mut [T; M])
split_array
)Divides one mutable array reference into two at an index from the end.
The first will contain all indices from [0, N - M)
(excluding
the index N - M
itself) and the second will contain all
indices from [N - M, N)
(excluding the index N
itself).
§Panics
Panics if M > N
.
§Examples
#![feature(split_array)]
let mut v = [1, 0, 3, 0, 5, 6];
let (left, right) = v.rsplit_array_mut::<4>();
assert_eq!(left, &mut [1, 0]);
assert_eq!(right, &mut [3, 0, 5, 6][..]);
left[1] = 2;
right[1] = 4;
assert_eq!(v, [1, 2, 3, 4, 5, 6]);
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]]);
source§impl<T, const M: usize, const N: usize> Mul<Matrix<T, N, N>> for Matrix<T, M, N>
impl<T, const M: usize, const N: usize> Mul<Matrix<T, N, N>> for Matrix<T, M, N>
source§impl<T, const M: usize, const N: usize> Mul<T> for Matrix<T, M, N>
impl<T, const M: usize, const N: usize> Mul<T> for Matrix<T, M, N>
source§impl<T, const M: usize, const N: usize> Mul<Vector<T, N>> for Matrix<T, M, N>
impl<T, const M: usize, const N: usize> Mul<Vector<T, N>> for Matrix<T, M, N>
source§impl<T, const M: usize, const N: usize> Sub for Matrix<T, M, N>
impl<T, const M: usize, const N: usize> Sub for Matrix<T, M, N>
impl<T: Copy, const M: usize, const N: usize> Copy for Matrix<T, M, N>
impl<T, const M: usize, const N: usize> StructuralPartialEq for Matrix<T, M, N>
Auto Trait Implementations§
impl<T, const M: usize, const N: usize> Freeze for Matrix<T, M, N>where
T: Freeze,
impl<T, const M: usize, const N: usize> RefUnwindSafe for Matrix<T, M, N>where
T: RefUnwindSafe,
impl<T, const M: usize, const N: usize> Send for Matrix<T, M, N>where
T: Send,
impl<T, const M: usize, const N: usize> Sync for Matrix<T, M, N>where
T: Sync,
impl<T, const M: usize, const N: usize> Unpin for Matrix<T, M, N>where
T: Unpin,
impl<T, const M: usize, const N: usize> UnwindSafe for Matrix<T, M, N>where
T: UnwindSafe,
Blanket Implementations§
source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
source§default unsafe fn clone_to_uninit(&self, dst: *mut T)
default unsafe fn clone_to_uninit(&self, dst: *mut T)
clone_to_uninit
)source§impl<T> CloneToUninit for Twhere
T: Copy,
impl<T> CloneToUninit for Twhere
T: Copy,
source§unsafe fn clone_to_uninit(&self, dst: *mut T)
unsafe fn clone_to_uninit(&self, dst: *mut T)
clone_to_uninit
)