|
|
@ -14,9 +14,9 @@ mod ops;
|
|
|
|
|
|
|
|
|
|
|
|
mod util;
|
|
|
|
mod util;
|
|
|
|
|
|
|
|
|
|
|
|
/// A 2D array of values which can be operated upon.
|
|
|
|
/** A 2D array of values which can be operated upon.
|
|
|
|
///
|
|
|
|
|
|
|
|
/// Matrices have a fixed size known at compile time
|
|
|
|
Matrices have a fixed size known at compile time */
|
|
|
|
#[derive(Debug, Copy, Clone, PartialEq)]
|
|
|
|
#[derive(Debug, Copy, Clone, PartialEq)]
|
|
|
|
pub struct Matrix<T, const M: usize, const N: usize>
|
|
|
|
pub struct Matrix<T, const M: usize, const N: usize>
|
|
|
|
where
|
|
|
|
where
|
|
|
@ -69,30 +69,31 @@ impl<T: Copy + Bounded, const N: usize, const M: usize> Bounded for Matrix<T, N,
|
|
|
|
|
|
|
|
|
|
|
|
// Identity
|
|
|
|
// Identity
|
|
|
|
impl<T: Copy + Zero + One, const N: usize> Matrix<T, N, N> {
|
|
|
|
impl<T: Copy + Zero + One, const N: usize> Matrix<T, N, N> {
|
|
|
|
/// Create an identity matrix, a square matrix where the diagonals are 1 and all other elements
|
|
|
|
/** Create an identity matrix, a square matrix where the diagonals are 1 and
|
|
|
|
/// are 0.
|
|
|
|
all other elements are 0.
|
|
|
|
/// for example,
|
|
|
|
|
|
|
|
///
|
|
|
|
for example,
|
|
|
|
/// $bbI = [[1,0,0],[0,1,0],[0,0,1]]$
|
|
|
|
|
|
|
|
///
|
|
|
|
$bbI = \[\[1,0,0],\[0,1,0],\[0,0,1]]$
|
|
|
|
/// Matrix multiplication between a matrix and the identity matrix always results in itself
|
|
|
|
|
|
|
|
///
|
|
|
|
Matrix multiplication between a matrix and the identity matrix always results in itself
|
|
|
|
/// $bbA xx bbI = bbA$
|
|
|
|
|
|
|
|
///
|
|
|
|
$bbA xx bbI = bbA$
|
|
|
|
/// # Examples
|
|
|
|
|
|
|
|
/// ```
|
|
|
|
# Examples
|
|
|
|
/// # use vector_victor::Matrix;
|
|
|
|
```
|
|
|
|
/// let i = Matrix::<i32,3,3>::identity();
|
|
|
|
# use vector_victor::Matrix;
|
|
|
|
/// assert_eq!(i, Matrix::mat([[1, 0, 0],
|
|
|
|
let i = Matrix::<i32,3,3>::identity();
|
|
|
|
/// [0, 1, 0],
|
|
|
|
assert_eq!(i, Matrix::mat([[1, 0, 0],
|
|
|
|
/// [0, 0, 1]]))
|
|
|
|
[0, 1, 0],
|
|
|
|
/// ```
|
|
|
|
[0, 0, 1]]))
|
|
|
|
///
|
|
|
|
```
|
|
|
|
/// Note that the identity only exists for matrices that are square, so this doesnt work:
|
|
|
|
|
|
|
|
/// ```compile_fail
|
|
|
|
Note that the identity only exists for matrices that are square, so this doesnt work:
|
|
|
|
/// # use vector_victor::Matrix;
|
|
|
|
```compile_fail
|
|
|
|
/// let i = Matrix::<i32,4,2>::identity();
|
|
|
|
# use vector_victor::Matrix;
|
|
|
|
/// ```
|
|
|
|
let i = Matrix::<i32,4,2>::identity();
|
|
|
|
|
|
|
|
``` */
|
|
|
|
#[must_use]
|
|
|
|
#[must_use]
|
|
|
|
pub fn identity() -> Self {
|
|
|
|
pub fn identity() -> Self {
|
|
|
|
let mut result = Self::zero();
|
|
|
|
let mut result = Self::zero();
|
|
|
@ -105,18 +106,18 @@ impl<T: Copy + Zero + One, const N: usize> Matrix<T, N, N> {
|
|
|
|
|
|
|
|
|
|
|
|
// Matrix constructors
|
|
|
|
// Matrix constructors
|
|
|
|
impl<T: Copy, const M: usize, const N: usize> Matrix<T, M, N> {
|
|
|
|
impl<T: Copy, const M: usize, const N: usize> Matrix<T, M, N> {
|
|
|
|
/// Generate a new matrix from a 2D Array
|
|
|
|
/** Generate a new matrix from a 2D Array
|
|
|
|
///
|
|
|
|
|
|
|
|
/// # Arguments
|
|
|
|
# Arguments
|
|
|
|
///
|
|
|
|
|
|
|
|
/// * `data`: A 2D array of elements to copy into the new matrix
|
|
|
|
* `data`: A 2D array of elements to copy into the new matrix
|
|
|
|
///
|
|
|
|
|
|
|
|
/// # Examples
|
|
|
|
# Examples
|
|
|
|
///
|
|
|
|
|
|
|
|
/// ```
|
|
|
|
```
|
|
|
|
/// # use vector_victor::Matrix;
|
|
|
|
# use vector_victor::Matrix;
|
|
|
|
/// let a = Matrix::mat([[1,2,3,4];4]);
|
|
|
|
let a = Matrix::mat([[1,2,3,4];4]);
|
|
|
|
/// ```
|
|
|
|
``` */
|
|
|
|
#[must_use]
|
|
|
|
#[must_use]
|
|
|
|
pub fn mat(data: [[T; N]; M]) -> Self {
|
|
|
|
pub fn mat(data: [[T; N]; M]) -> Self {
|
|
|
|
assert!(M > 0, "Matrix must have at least 1 row");
|
|
|
|
assert!(M > 0, "Matrix must have at least 1 row");
|
|
|
@ -124,19 +125,19 @@ impl<T: Copy, const M: usize, const N: usize> Matrix<T, M, N> {
|
|
|
|
Matrix::<T, M, N> { data }
|
|
|
|
Matrix::<T, M, N> { data }
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// Generate a new matrix from a single scalar
|
|
|
|
/** Generate a new matrix from a single scalar
|
|
|
|
///
|
|
|
|
|
|
|
|
/// # Arguments
|
|
|
|
# Arguments
|
|
|
|
///
|
|
|
|
|
|
|
|
/// * `scalar`: Scalar value to copy into the new matrix.
|
|
|
|
* `scalar`: Scalar value to copy into the new matrix.
|
|
|
|
///
|
|
|
|
|
|
|
|
/// # Examples
|
|
|
|
# Examples
|
|
|
|
///
|
|
|
|
|
|
|
|
/// ```
|
|
|
|
```
|
|
|
|
/// # use vector_victor::Matrix;
|
|
|
|
# use vector_victor::Matrix;
|
|
|
|
/// // these are equivalent
|
|
|
|
// these are equivalent
|
|
|
|
/// assert_eq!(Matrix::<i32,4,4>::fill(5), Matrix::mat([[5;4];4]))
|
|
|
|
assert_eq!(Matrix::<i32,4,4>::fill(5), Matrix::mat([[5;4];4]))
|
|
|
|
/// ```
|
|
|
|
``` */
|
|
|
|
#[must_use]
|
|
|
|
#[must_use]
|
|
|
|
pub fn fill(scalar: T) -> Matrix<T, M, N> {
|
|
|
|
pub fn fill(scalar: T) -> Matrix<T, M, N> {
|
|
|
|
assert!(M > 0, "Matrix must have at least 1 row");
|
|
|
|
assert!(M > 0, "Matrix must have at least 1 row");
|
|
|
@ -146,26 +147,26 @@ impl<T: Copy, const M: usize, const N: usize> Matrix<T, M, N> {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// Create a matrix from an iterator of vectors
|
|
|
|
/** Create a matrix from an iterator of vectors
|
|
|
|
///
|
|
|
|
|
|
|
|
/// # Arguments
|
|
|
|
# Arguments
|
|
|
|
///
|
|
|
|
|
|
|
|
/// * `iter`: iterator of vectors to copy into rows
|
|
|
|
* `iter`: iterator of vectors to copy into rows
|
|
|
|
///
|
|
|
|
|
|
|
|
/// # Examples
|
|
|
|
# Examples
|
|
|
|
///
|
|
|
|
|
|
|
|
/// The following is another way of performing [`Matrix::transpose()`]
|
|
|
|
The following is another way of performing [`Matrix::transpose()`]
|
|
|
|
/// ```
|
|
|
|
```
|
|
|
|
/// # use vector_victor::Matrix;
|
|
|
|
# use vector_victor::Matrix;
|
|
|
|
/// let my_matrix = Matrix::mat([[1, 2, 3],
|
|
|
|
let my_matrix = Matrix::mat([[1, 2, 3],
|
|
|
|
/// [4, 5, 6]]);
|
|
|
|
[4, 5, 6]]);
|
|
|
|
///
|
|
|
|
|
|
|
|
/// let transpose : Matrix<_,3,2>= Matrix::from_rows(my_matrix.cols());
|
|
|
|
let transpose : Matrix<_,3,2>= Matrix::from_rows(my_matrix.cols());
|
|
|
|
///
|
|
|
|
|
|
|
|
/// assert_eq!(transpose, Matrix::mat([[1, 4],
|
|
|
|
assert_eq!(transpose, Matrix::mat([[1, 4],
|
|
|
|
/// [2, 5],
|
|
|
|
[2, 5],
|
|
|
|
/// [3, 6]]))
|
|
|
|
[3, 6]]))
|
|
|
|
/// ```
|
|
|
|
``` */
|
|
|
|
#[must_use]
|
|
|
|
#[must_use]
|
|
|
|
pub fn from_rows<I>(iter: I) -> Self
|
|
|
|
pub fn from_rows<I>(iter: I) -> Self
|
|
|
|
where
|
|
|
|
where
|
|
|
@ -179,26 +180,26 @@ impl<T: Copy, const M: usize, const N: usize> Matrix<T, M, N> {
|
|
|
|
result
|
|
|
|
result
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// Create a matrix from an iterator of vectors
|
|
|
|
/** Create a matrix from an iterator of vectors
|
|
|
|
///
|
|
|
|
|
|
|
|
/// # Arguments
|
|
|
|
# Arguments
|
|
|
|
///
|
|
|
|
|
|
|
|
/// * `iter`: iterator of vectors to copy into columns
|
|
|
|
* `iter`: iterator of vectors to copy into columns
|
|
|
|
///
|
|
|
|
|
|
|
|
/// # Examples
|
|
|
|
# Examples
|
|
|
|
///
|
|
|
|
|
|
|
|
/// The following is another way of performing [`Matrix::transpose()`]
|
|
|
|
The following is another way of performing [`Matrix::transpose()`]
|
|
|
|
/// ```
|
|
|
|
```
|
|
|
|
/// # use vector_victor::Matrix;
|
|
|
|
# use vector_victor::Matrix;
|
|
|
|
/// let my_matrix = Matrix::mat([[1, 2, 3],
|
|
|
|
let my_matrix = Matrix::mat([[1, 2, 3],
|
|
|
|
/// [4, 5, 6]]);
|
|
|
|
[4, 5, 6]]);
|
|
|
|
///
|
|
|
|
|
|
|
|
/// let transpose : Matrix<_,3,2>= Matrix::from_cols(my_matrix.rows());
|
|
|
|
let transpose : Matrix<_,3,2>= Matrix::from_cols(my_matrix.rows());
|
|
|
|
///
|
|
|
|
|
|
|
|
/// assert_eq!(transpose, Matrix::mat([[1, 4],
|
|
|
|
assert_eq!(transpose, Matrix::mat([[1, 4],
|
|
|
|
/// [2, 5],
|
|
|
|
[2, 5],
|
|
|
|
/// [3, 6]]))
|
|
|
|
[3, 6]]))
|
|
|
|
/// ```
|
|
|
|
``` */
|
|
|
|
#[must_use]
|
|
|
|
#[must_use]
|
|
|
|
pub fn from_cols<I>(iter: I) -> Self
|
|
|
|
pub fn from_cols<I>(iter: I) -> Self
|
|
|
|
where
|
|
|
|
where
|
|
|
@ -215,15 +216,15 @@ impl<T: Copy, const M: usize, const N: usize> Matrix<T, M, N> {
|
|
|
|
|
|
|
|
|
|
|
|
// Vector constructor
|
|
|
|
// Vector constructor
|
|
|
|
impl<T: Copy, const N: usize> Vector<T, N> {
|
|
|
|
impl<T: Copy, const N: usize> Vector<T, N> {
|
|
|
|
/// Create a vector from a 1D array.
|
|
|
|
/** Create a vector from a 1D array.
|
|
|
|
/// Note that vectors are always column vectors unless explicitly instantiated as row vectors
|
|
|
|
Note that vectors are always column vectors unless explicitly instantiated as row vectors
|
|
|
|
///
|
|
|
|
|
|
|
|
/// # Examples
|
|
|
|
# Examples
|
|
|
|
/// ```
|
|
|
|
```
|
|
|
|
/// # use vector_victor::{Matrix, Vector};
|
|
|
|
# use vector_victor::{Matrix, Vector};
|
|
|
|
/// // these are equivalent
|
|
|
|
// these are equivalent
|
|
|
|
/// assert_eq!(Vector::vec([1,2,3,4]), Matrix::mat([[1],[2],[3],[4]]));
|
|
|
|
assert_eq!(Vector::vec([1,2,3,4]), Matrix::mat([[1],[2],[3],[4]]));
|
|
|
|
/// ```
|
|
|
|
``` */
|
|
|
|
pub fn vec(data: [T; N]) -> Self {
|
|
|
|
pub fn vec(data: [T; N]) -> Self {
|
|
|
|
assert!(N > 0, "Vector must have at least 1 element");
|
|
|
|
assert!(N > 0, "Vector must have at least 1 element");
|
|
|
|
return Vector::<T, N> {
|
|
|
|
return Vector::<T, N> {
|
|
|
@ -234,100 +235,99 @@ impl<T: Copy, const N: usize> Vector<T, N> {
|
|
|
|
|
|
|
|
|
|
|
|
// ACCESSORS AND MUTATORS
|
|
|
|
// ACCESSORS AND MUTATORS
|
|
|
|
impl<T: Copy, const M: usize, const N: usize> Matrix<T, M, N> {
|
|
|
|
impl<T: Copy, const M: usize, const N: usize> Matrix<T, M, N> {
|
|
|
|
/// Returns an iterator over the elements of the matrix in row-major order.
|
|
|
|
/** Returns an iterator over the elements of the matrix in row-major order.
|
|
|
|
///
|
|
|
|
|
|
|
|
/// This is identical to the behavior of [`IntoIterator`](#associatedtype.IntoIter)
|
|
|
|
This is identical to the behavior of [`IntoIterator`](#associatedtype.IntoIter)
|
|
|
|
///
|
|
|
|
|
|
|
|
/// # Examples
|
|
|
|
# Examples
|
|
|
|
/// ```
|
|
|
|
```
|
|
|
|
/// # use vector_victor::Matrix;
|
|
|
|
# use vector_victor::Matrix;
|
|
|
|
/// let my_matrix = Matrix::mat([[1, 2],
|
|
|
|
let my_matrix = Matrix::mat([[1, 2],
|
|
|
|
/// [3, 4]]);
|
|
|
|
[3, 4]]);
|
|
|
|
///
|
|
|
|
|
|
|
|
/// itertools::assert_equal(my_matrix.elements(), [1,2,3,4].iter())
|
|
|
|
itertools::assert_equal(my_matrix.elements(), [1,2,3,4].iter())
|
|
|
|
/// ```
|
|
|
|
``` */
|
|
|
|
#[must_use]
|
|
|
|
#[must_use]
|
|
|
|
pub fn elements<'s>(&'s self) -> impl Iterator<Item = &'s T> + 's {
|
|
|
|
pub fn elements<'s>(&'s self) -> impl Iterator<Item = &'s T> + 's {
|
|
|
|
self.data.iter().flatten()
|
|
|
|
self.data.iter().flatten()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// Returns a mutable iterator over the elements of the matrix in row-major order.
|
|
|
|
/** Returns a mutable iterator over the elements of the matrix in row-major order.
|
|
|
|
///
|
|
|
|
|
|
|
|
/// # Examples
|
|
|
|
# Examples
|
|
|
|
/// ```
|
|
|
|
```
|
|
|
|
/// # use vector_victor::Matrix;
|
|
|
|
# use vector_victor::Matrix;
|
|
|
|
/// let mut my_matrix = Matrix::mat([[1, 2],
|
|
|
|
let mut my_matrix = Matrix::mat([[1, 2],
|
|
|
|
/// [3, 4]]);
|
|
|
|
[3, 4]]);
|
|
|
|
///
|
|
|
|
|
|
|
|
/// for elem in my_matrix.elements_mut() {*elem += 2;}
|
|
|
|
for elem in my_matrix.elements_mut() {*elem += 2;}
|
|
|
|
/// itertools::assert_equal(my_matrix.elements(), [3,4,5,6].iter())
|
|
|
|
itertools::assert_equal(my_matrix.elements(), [3,4,5,6].iter())
|
|
|
|
/// ```
|
|
|
|
``` */
|
|
|
|
#[must_use]
|
|
|
|
#[must_use]
|
|
|
|
pub fn elements_mut<'s>(&'s mut self) -> impl Iterator<Item = &'s mut T> + 's {
|
|
|
|
pub fn elements_mut<'s>(&'s mut self) -> impl Iterator<Item = &'s mut T> + 's {
|
|
|
|
self.data.iter_mut().flatten()
|
|
|
|
self.data.iter_mut().flatten()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// returns an iterator over the elements along the diagonal of a matrix
|
|
|
|
/** returns an iterator over the elements along the diagonal of a matrix
|
|
|
|
///
|
|
|
|
|
|
|
|
/// # Examples
|
|
|
|
# Examples
|
|
|
|
/// ```
|
|
|
|
```
|
|
|
|
/// # use vector_victor::Matrix;
|
|
|
|
# use vector_victor::Matrix;
|
|
|
|
/// let my_matrix = Matrix::mat([[1, 2, 3],
|
|
|
|
let my_matrix = Matrix::mat([[1, 2, 3],
|
|
|
|
/// [4, 5, 6],
|
|
|
|
[4, 5, 6],
|
|
|
|
/// [7, 8, 9],
|
|
|
|
[7, 8, 9],
|
|
|
|
/// [10,11,12]]);
|
|
|
|
[10,11,12]]);
|
|
|
|
///
|
|
|
|
|
|
|
|
/// itertools::assert_equal(my_matrix.diagonals(), [1,5,9].iter())
|
|
|
|
itertools::assert_equal(my_matrix.diagonals(), [1,5,9].iter())
|
|
|
|
/// ```
|
|
|
|
``` */
|
|
|
|
#[must_use]
|
|
|
|
#[must_use]
|
|
|
|
pub fn diagonals<'s>(&'s self) -> impl Iterator<Item = &'s T> + 's {
|
|
|
|
pub fn diagonals<'s>(&'s self) -> impl Iterator<Item = &'s T> + 's {
|
|
|
|
(0..min(N, M)).map(|n| &self[(n, n)])
|
|
|
|
(0..min(N, M)).map(|n| &self[(n, n)])
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// Returns an iterator over the elements directly below the diagonal of a matrix
|
|
|
|
/** Returns an iterator over the elements directly below the diagonal of a matrix
|
|
|
|
/// returns an iterator over the elements along the diagonal of a matrix
|
|
|
|
|
|
|
|
///
|
|
|
|
# Examples
|
|
|
|
/// # Examples
|
|
|
|
```
|
|
|
|
/// ```
|
|
|
|
# use vector_victor::Matrix;
|
|
|
|
/// # use vector_victor::Matrix;
|
|
|
|
let my_matrix = Matrix::mat([[1, 2, 3],
|
|
|
|
/// let my_matrix = Matrix::mat([[1, 2, 3],
|
|
|
|
[4, 5, 6],
|
|
|
|
/// [4, 5, 6],
|
|
|
|
[7, 8, 9],
|
|
|
|
/// [7, 8, 9],
|
|
|
|
[10,11,12]]);
|
|
|
|
/// [10,11,12]]);
|
|
|
|
|
|
|
|
///
|
|
|
|
itertools::assert_equal(my_matrix.subdiagonals(), [4,8,12].iter());
|
|
|
|
/// itertools::assert_equal(my_matrix.subdiagonals(), [4,8,12].iter());
|
|
|
|
``` */
|
|
|
|
/// ```
|
|
|
|
|
|
|
|
#[must_use]
|
|
|
|
#[must_use]
|
|
|
|
pub fn subdiagonals<'s>(&'s self) -> impl Iterator<Item = &'s T> + 's {
|
|
|
|
pub fn subdiagonals<'s>(&'s self) -> impl Iterator<Item = &'s T> + 's {
|
|
|
|
(0..min(N, M - 1)).map(|n| &self[(n + 1, n)])
|
|
|
|
(0..min(N, M - 1)).map(|n| &self[(n + 1, n)])
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// Returns a reference to the element at that position in the matrix, or `None` if out of bounds.
|
|
|
|
/** Returns a reference to the element at that position in the matrix, or `None` if out of bounds.
|
|
|
|
///
|
|
|
|
|
|
|
|
/// [`Index`](#impl-Index%3CI%3E-for-Matrix%3CT,+M,+N%3E) behaves similarly,
|
|
|
|
[`Index`](#impl-Index%3CI%3E-for-Matrix%3CT,+M,+N%3E) behaves similarly,
|
|
|
|
/// but will panic if the index is out of bounds instead of returning an option
|
|
|
|
but will panic if the index is out of bounds instead of returning an option
|
|
|
|
///
|
|
|
|
|
|
|
|
/// # Arguments
|
|
|
|
# Arguments
|
|
|
|
///
|
|
|
|
|
|
|
|
/// * `index`: a 1D or 2D index into the matrix. See [Index2D] for more information on matrix indexing.
|
|
|
|
* `index`: a 1D or 2D index into the matrix. See [Index2D] for more information on matrix indexing.
|
|
|
|
///
|
|
|
|
|
|
|
|
/// # Examples
|
|
|
|
# Examples
|
|
|
|
///
|
|
|
|
|
|
|
|
/// ```
|
|
|
|
```
|
|
|
|
/// # use vector_victor::Matrix;
|
|
|
|
# use vector_victor::Matrix;
|
|
|
|
/// let my_matrix = Matrix::mat([[1, 2],
|
|
|
|
let my_matrix = Matrix::mat([[1, 2],
|
|
|
|
/// [3, 4]]);
|
|
|
|
[3, 4]]);
|
|
|
|
///
|
|
|
|
|
|
|
|
/// // element at index 2 is the same as the element at row 1, column 0.
|
|
|
|
// element at index 2 is the same as the element at row 1, column 0.
|
|
|
|
/// assert_eq!(my_matrix.get(2), my_matrix.get((1,0)));
|
|
|
|
assert_eq!(my_matrix.get(2), my_matrix.get((1,0)));
|
|
|
|
///
|
|
|
|
|
|
|
|
/// // my_matrix.get() is equivalent to my_matrix[],
|
|
|
|
// my_matrix.get() is equivalent to my_matrix[],
|
|
|
|
/// // but returns an Option instead of panicking
|
|
|
|
// but returns an Option instead of panicking
|
|
|
|
/// assert_eq!(my_matrix.get(2), Some(&my_matrix[2]));
|
|
|
|
assert_eq!(my_matrix.get(2), Some(&my_matrix[2]));
|
|
|
|
///
|
|
|
|
|
|
|
|
/// // index 4 is out of range, so get(4) returns None.
|
|
|
|
// index 4 is out of range, so get(4) returns None.
|
|
|
|
/// assert_eq!(my_matrix.get(4), None);
|
|
|
|
assert_eq!(my_matrix.get(4), None);
|
|
|
|
/// ```
|
|
|
|
``` */
|
|
|
|
#[inline]
|
|
|
|
#[inline]
|
|
|
|
#[must_use]
|
|
|
|
#[must_use]
|
|
|
|
pub fn get(&self, index: impl Index2D) -> Option<&T> {
|
|
|
|
pub fn get(&self, index: impl Index2D) -> Option<&T> {
|
|
|
@ -335,29 +335,29 @@ impl<T: Copy, const M: usize, const N: usize> Matrix<T, M, N> {
|
|
|
|
Some(&self.data[m][n])
|
|
|
|
Some(&self.data[m][n])
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// Returns a mutable reference to the element at that position in the matrix,
|
|
|
|
/** Returns a mutable reference to the element at that position in the matrix,
|
|
|
|
/// or `None` if out of bounds.
|
|
|
|
or `None` if out of bounds.
|
|
|
|
///
|
|
|
|
|
|
|
|
/// [`IndexMut`](#impl-IndexMut%3CI%3E-for-Matrix%3CT,+M,+N%3E) behaves similarly,
|
|
|
|
[`IndexMut`](#impl-IndexMut%3CI%3E-for-Matrix%3CT,+M,+N%3E) behaves similarly,
|
|
|
|
/// but will panic if the index is out of bounds instead of returning an option
|
|
|
|
but will panic if the index is out of bounds instead of returning an option
|
|
|
|
///
|
|
|
|
|
|
|
|
/// # Arguments
|
|
|
|
# Arguments
|
|
|
|
///
|
|
|
|
|
|
|
|
/// * `index`: a 1D or 2D index into the matrix. See [Index2D] for more information
|
|
|
|
* `index`: a 1D or 2D index into the matrix. See [Index2D] for more information
|
|
|
|
/// on matrix indexing.
|
|
|
|
on matrix indexing.
|
|
|
|
///
|
|
|
|
|
|
|
|
/// # Examples
|
|
|
|
# Examples
|
|
|
|
///
|
|
|
|
|
|
|
|
/// ```
|
|
|
|
```
|
|
|
|
/// # use vector_victor::Matrix;
|
|
|
|
# use vector_victor::Matrix;
|
|
|
|
/// let mut my_matrix = Matrix::mat([[1, 2],
|
|
|
|
let mut my_matrix = Matrix::mat([[1, 2],
|
|
|
|
/// [3, 4]]);
|
|
|
|
[3, 4]]);
|
|
|
|
///
|
|
|
|
|
|
|
|
/// match my_matrix.get_mut(2) {
|
|
|
|
match my_matrix.get_mut(2) {
|
|
|
|
/// Some(t) => *t = 5,
|
|
|
|
Some(t) => *t = 5,
|
|
|
|
/// None => panic!()};
|
|
|
|
None => panic!()};
|
|
|
|
/// assert_eq!(my_matrix, Matrix::mat([[1,2],[5,4]]))
|
|
|
|
assert_eq!(my_matrix, Matrix::mat([[1,2],[5,4]]))
|
|
|
|
/// ```
|
|
|
|
``` */
|
|
|
|
#[inline]
|
|
|
|
#[inline]
|
|
|
|
#[must_use]
|
|
|
|
#[must_use]
|
|
|
|
pub fn get_mut(&mut self, index: impl Index2D) -> Option<&mut T> {
|
|
|
|
pub fn get_mut(&mut self, index: impl Index2D) -> Option<&mut T> {
|
|
|
@ -365,22 +365,22 @@ impl<T: Copy, const M: usize, const N: usize> Matrix<T, M, N> {
|
|
|
|
Some(&mut self.data[m][n])
|
|
|
|
Some(&mut self.data[m][n])
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// Returns a row of the matrix.
|
|
|
|
/** Returns a row of the matrix.
|
|
|
|
///
|
|
|
|
|
|
|
|
/// # Panics
|
|
|
|
# Panics
|
|
|
|
///
|
|
|
|
|
|
|
|
/// Panics if row index `m` is out of bounds.
|
|
|
|
Panics if row index `m` is out of bounds.
|
|
|
|
///
|
|
|
|
|
|
|
|
/// # Examples
|
|
|
|
# Examples
|
|
|
|
///
|
|
|
|
|
|
|
|
/// ```
|
|
|
|
```
|
|
|
|
/// # use vector_victor::{Matrix, Vector};
|
|
|
|
# use vector_victor::{Matrix, Vector};
|
|
|
|
/// let my_matrix = Matrix::mat([[1, 2],
|
|
|
|
let my_matrix = Matrix::mat([[1, 2],
|
|
|
|
/// [3, 4]]);
|
|
|
|
[3, 4]]);
|
|
|
|
///
|
|
|
|
|
|
|
|
/// // row at index 1
|
|
|
|
// row at index 1
|
|
|
|
/// assert_eq!(my_matrix.row(1), Vector::vec([3,4]));
|
|
|
|
assert_eq!(my_matrix.row(1), Vector::vec([3,4]));
|
|
|
|
/// ```
|
|
|
|
``` */
|
|
|
|
#[inline]
|
|
|
|
#[inline]
|
|
|
|
#[must_use]
|
|
|
|
#[must_use]
|
|
|
|
pub fn row(&self, m: usize) -> Vector<T, N> {
|
|
|
|
pub fn row(&self, m: usize) -> Vector<T, N> {
|
|
|
@ -394,22 +394,22 @@ impl<T: Copy, const M: usize, const N: usize> Matrix<T, M, N> {
|
|
|
|
Vector::<T, N>::vec(self.data[m])
|
|
|
|
Vector::<T, N>::vec(self.data[m])
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// Sets a row of the matrix.
|
|
|
|
/** Sets a row of the matrix.
|
|
|
|
///
|
|
|
|
|
|
|
|
/// # Panics
|
|
|
|
# Panics
|
|
|
|
///
|
|
|
|
|
|
|
|
/// Panics if row index `m` is out of bounds.
|
|
|
|
Panics if row index `m` is out of bounds.
|
|
|
|
///
|
|
|
|
|
|
|
|
/// # Examples
|
|
|
|
# Examples
|
|
|
|
///
|
|
|
|
|
|
|
|
/// ```
|
|
|
|
```
|
|
|
|
/// # use vector_victor::{Matrix, Vector};
|
|
|
|
# use vector_victor::{Matrix, Vector};
|
|
|
|
/// let mut my_matrix = Matrix::mat([[1, 2],
|
|
|
|
let mut my_matrix = Matrix::mat([[1, 2],
|
|
|
|
/// [3, 4]]);
|
|
|
|
[3, 4]]);
|
|
|
|
/// // row at index 1
|
|
|
|
// row at index 1
|
|
|
|
/// my_matrix.set_row(1, &Vector::vec([5,6]));
|
|
|
|
my_matrix.set_row(1, &Vector::vec([5,6]));
|
|
|
|
/// assert_eq!(my_matrix, Matrix::mat([[1,2],[5,6]]));
|
|
|
|
assert_eq!(my_matrix, Matrix::mat([[1,2],[5,6]]));
|
|
|
|
/// ```
|
|
|
|
``` */
|
|
|
|
#[inline]
|
|
|
|
#[inline]
|
|
|
|
pub fn set_row(&mut self, m: usize, val: &Vector<T, N>) {
|
|
|
|
pub fn set_row(&mut self, m: usize, val: &Vector<T, N>) {
|
|
|
|
assert!(
|
|
|
|
assert!(
|
|
|
@ -424,22 +424,22 @@ impl<T: Copy, const M: usize, const N: usize> Matrix<T, M, N> {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// Returns a column of the matrix.
|
|
|
|
/** Returns a column of the matrix.
|
|
|
|
///
|
|
|
|
|
|
|
|
/// # Panics
|
|
|
|
# Panics
|
|
|
|
///
|
|
|
|
|
|
|
|
/// Panics if column index `n` is out of bounds.
|
|
|
|
Panics if column index `n` is out of bounds.
|
|
|
|
///
|
|
|
|
|
|
|
|
/// # Examples
|
|
|
|
# Examples
|
|
|
|
///
|
|
|
|
|
|
|
|
/// ```
|
|
|
|
```
|
|
|
|
/// # use vector_victor::{Matrix, Vector};
|
|
|
|
# use vector_victor::{Matrix, Vector};
|
|
|
|
/// let my_matrix = Matrix::mat([[1, 2],
|
|
|
|
let my_matrix = Matrix::mat([[1, 2],
|
|
|
|
/// [3, 4]]);
|
|
|
|
[3, 4]]);
|
|
|
|
///
|
|
|
|
|
|
|
|
/// // column at index 1
|
|
|
|
// column at index 1
|
|
|
|
/// assert_eq!(my_matrix.col(1), Vector::vec([2,4]));
|
|
|
|
assert_eq!(my_matrix.col(1), Vector::vec([2,4]));
|
|
|
|
/// ```
|
|
|
|
``` */
|
|
|
|
#[inline]
|
|
|
|
#[inline]
|
|
|
|
#[must_use]
|
|
|
|
#[must_use]
|
|
|
|
pub fn col(&self, n: usize) -> Vector<T, M> {
|
|
|
|
pub fn col(&self, n: usize) -> Vector<T, M> {
|
|
|
@ -453,22 +453,22 @@ impl<T: Copy, const M: usize, const N: usize> Matrix<T, M, N> {
|
|
|
|
Vector::<T, M>::vec(self.data.map(|r| r[n]))
|
|
|
|
Vector::<T, M>::vec(self.data.map(|r| r[n]))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// Sets a column of the matrix.
|
|
|
|
/** Sets a column of the matrix.
|
|
|
|
///
|
|
|
|
|
|
|
|
/// # Panics
|
|
|
|
# Panics
|
|
|
|
///
|
|
|
|
|
|
|
|
/// Panics if column index `n` is out of bounds.
|
|
|
|
Panics if column index `n` is out of bounds.
|
|
|
|
///
|
|
|
|
|
|
|
|
/// # Examples
|
|
|
|
# Examples
|
|
|
|
///
|
|
|
|
|
|
|
|
/// ```
|
|
|
|
```
|
|
|
|
/// # use vector_victor::{Matrix, Vector};
|
|
|
|
# use vector_victor::{Matrix, Vector};
|
|
|
|
/// let mut my_matrix = Matrix::mat([[1, 2],
|
|
|
|
let mut my_matrix = Matrix::mat([[1, 2],
|
|
|
|
/// [3, 4]]);
|
|
|
|
[3, 4]]);
|
|
|
|
/// // column at index 1
|
|
|
|
// column at index 1
|
|
|
|
/// my_matrix.set_col(1, &Vector::vec([5,6]));
|
|
|
|
my_matrix.set_col(1, &Vector::vec([5,6]));
|
|
|
|
/// assert_eq!(my_matrix, Matrix::mat([[1,5],[3,6]]));
|
|
|
|
assert_eq!(my_matrix, Matrix::mat([[1,5],[3,6]]));
|
|
|
|
/// ```
|
|
|
|
``` */
|
|
|
|
#[inline]
|
|
|
|
#[inline]
|
|
|
|
pub fn set_col(&mut self, n: usize, val: &Vector<T, M>) {
|
|
|
|
pub fn set_col(&mut self, n: usize, val: &Vector<T, M>) {
|
|
|
|
assert!(
|
|
|
|
assert!(
|
|
|
@ -496,52 +496,52 @@ impl<T: Copy, const M: usize, const N: usize> Matrix<T, M, N> {
|
|
|
|
(0..N).map(|n| self.col(n))
|
|
|
|
(0..N).map(|n| self.col(n))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// Interchange two rows
|
|
|
|
/** Interchange two rows
|
|
|
|
///
|
|
|
|
|
|
|
|
/// # Panics
|
|
|
|
# Panics
|
|
|
|
///
|
|
|
|
|
|
|
|
/// Panics if row index `m1` or `m2` are out of bounds
|
|
|
|
Panics if row index `m1` or `m2` are out of bounds */
|
|
|
|
pub fn pivot_row(&mut self, m1: usize, m2: usize) {
|
|
|
|
pub fn pivot_row(&mut self, m1: usize, m2: usize) {
|
|
|
|
let tmp = self.row(m2);
|
|
|
|
let tmp = self.row(m2);
|
|
|
|
self.set_row(m2, &self.row(m1));
|
|
|
|
self.set_row(m2, &self.row(m1));
|
|
|
|
self.set_row(m1, &tmp);
|
|
|
|
self.set_row(m1, &tmp);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// Interchange two columns
|
|
|
|
/** Interchange two columns
|
|
|
|
///
|
|
|
|
|
|
|
|
/// # Panics
|
|
|
|
# Panics
|
|
|
|
///
|
|
|
|
|
|
|
|
/// Panics if column index `n1` or `n2` are out of bounds
|
|
|
|
Panics if column index `n1` or `n2` are out of bounds */
|
|
|
|
pub fn pivot_col(&mut self, n1: usize, n2: usize) {
|
|
|
|
pub fn pivot_col(&mut self, n1: usize, n2: usize) {
|
|
|
|
let tmp = self.col(n2);
|
|
|
|
let tmp = self.col(n2);
|
|
|
|
self.set_col(n2, &self.col(n1));
|
|
|
|
self.set_col(n2, &self.col(n1));
|
|
|
|
self.set_col(n1, &tmp);
|
|
|
|
self.set_col(n1, &tmp);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// Apply a permutation matrix to the rows of a matrix
|
|
|
|
/** Apply a permutation matrix to the rows of a matrix
|
|
|
|
///
|
|
|
|
|
|
|
|
/// # Arguments
|
|
|
|
# Arguments
|
|
|
|
///
|
|
|
|
|
|
|
|
/// * `ms`: a [`Vector`] of [`usize`] of length M. Each entry is the index of the row that will
|
|
|
|
* `ms`: a [`Vector`] of [`usize`] of length M. Each entry is the index of the row that will
|
|
|
|
/// appear in the result
|
|
|
|
appear in the result
|
|
|
|
///
|
|
|
|
|
|
|
|
/// # Panics
|
|
|
|
# Panics
|
|
|
|
///
|
|
|
|
|
|
|
|
/// Panics if any of the row indices in `ms` is out of bounds
|
|
|
|
Panics if any of the row indices in `ms` is out of bounds
|
|
|
|
///
|
|
|
|
|
|
|
|
/// # Examples
|
|
|
|
# Examples
|
|
|
|
///
|
|
|
|
|
|
|
|
/// ```
|
|
|
|
```
|
|
|
|
/// # use vector_victor::{Matrix, Vector};
|
|
|
|
# use vector_victor::{Matrix, Vector};
|
|
|
|
/// let my_matrix = Matrix::mat([[1, 2, 3],
|
|
|
|
let my_matrix = Matrix::mat([[1, 2, 3],
|
|
|
|
/// [4, 5, 6],
|
|
|
|
[4, 5, 6],
|
|
|
|
/// [7, 8, 9]]);
|
|
|
|
[7, 8, 9]]);
|
|
|
|
///
|
|
|
|
|
|
|
|
/// let permuted = my_matrix.permute_rows(&Vector::vec([1, 0, 2]));
|
|
|
|
let permuted = my_matrix.permute_rows(&Vector::vec([1, 0, 2]));
|
|
|
|
/// assert_eq!(permuted, Matrix::mat([[4, 5, 6],
|
|
|
|
assert_eq!(permuted, Matrix::mat([[4, 5, 6],
|
|
|
|
/// [1, 2, 3],
|
|
|
|
[1, 2, 3],
|
|
|
|
/// [7, 8, 9]]))
|
|
|
|
[7, 8, 9]]))
|
|
|
|
/// ```
|
|
|
|
``` */
|
|
|
|
#[must_use]
|
|
|
|
#[must_use]
|
|
|
|
pub fn permute_rows(&self, ms: &Vector<usize, M>) -> Self
|
|
|
|
pub fn permute_rows(&self, ms: &Vector<usize, M>) -> Self
|
|
|
|
where
|
|
|
|
where
|
|
|
@ -550,16 +550,16 @@ impl<T: Copy, const M: usize, const N: usize> Matrix<T, M, N> {
|
|
|
|
Self::from_rows(ms.elements().map(|&m| self.row(m)))
|
|
|
|
Self::from_rows(ms.elements().map(|&m| self.row(m)))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// Apply a permutation matrix to the columns of a matrix
|
|
|
|
/** Apply a permutation matrix to the columns of a matrix
|
|
|
|
///
|
|
|
|
|
|
|
|
/// # Arguments
|
|
|
|
# Arguments
|
|
|
|
///
|
|
|
|
|
|
|
|
/// * `ns`: a [`Vector`] of [`usize`] of length N. Each entry is the index of the column that will
|
|
|
|
* `ns`: a [`Vector`] of [`usize`] of length N. Each entry is the index of the column that will
|
|
|
|
/// appear in the result
|
|
|
|
appear in the result
|
|
|
|
///
|
|
|
|
|
|
|
|
/// # Panics
|
|
|
|
# Panics
|
|
|
|
///
|
|
|
|
|
|
|
|
/// Panics if any of the column indices in `ns` is out of bounds
|
|
|
|
Panics if any of the column indices in `ns` is out of bounds */
|
|
|
|
#[must_use]
|
|
|
|
#[must_use]
|
|
|
|
pub fn permute_cols(&self, ns: &Vector<usize, N>) -> Self
|
|
|
|
pub fn permute_cols(&self, ns: &Vector<usize, N>) -> Self
|
|
|
|
where
|
|
|
|
where
|
|
|
@ -568,20 +568,20 @@ impl<T: Copy, const M: usize, const N: usize> Matrix<T, M, N> {
|
|
|
|
Self::from_cols(ns.elements().map(|&n| self.col(n)))
|
|
|
|
Self::from_cols(ns.elements().map(|&n| self.col(n)))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// Returns the transpose $M^T$ of the matrix, or the matrix flipped across its diagonal.
|
|
|
|
/** Returns the transpose $M^T$ of the matrix, or the matrix flipped across its diagonal.
|
|
|
|
///
|
|
|
|
|
|
|
|
/// # Examples
|
|
|
|
# Examples
|
|
|
|
/// ```
|
|
|
|
```
|
|
|
|
/// # use vector_victor::Matrix;
|
|
|
|
# use vector_victor::Matrix;
|
|
|
|
/// let my_matrix = Matrix::mat([[1, 2, 3],
|
|
|
|
let my_matrix = Matrix::mat([[1, 2, 3],
|
|
|
|
/// [4, 5, 6]]);
|
|
|
|
[4, 5, 6]]);
|
|
|
|
///
|
|
|
|
|
|
|
|
/// assert_eq!(
|
|
|
|
assert_eq!(
|
|
|
|
/// my_matrix.transpose(),
|
|
|
|
my_matrix.transpose(),
|
|
|
|
/// Matrix::mat([[1, 4],
|
|
|
|
Matrix::mat([[1, 4],
|
|
|
|
/// [2, 5],
|
|
|
|
[2, 5],
|
|
|
|
/// [3, 6]]))
|
|
|
|
[3, 6]]))
|
|
|
|
/// ```
|
|
|
|
``` */
|
|
|
|
pub fn transpose(&self) -> Matrix<T, N, M>
|
|
|
|
pub fn transpose(&self) -> Matrix<T, N, M>
|
|
|
|
where
|
|
|
|
where
|
|
|
|
Matrix<T, N, M>: Default,
|
|
|
|
Matrix<T, N, M>: Default,
|
|
|
|