Use block comments for docs

Much more readable in the raw source
master
Andrew Cassidy 1 year ago
parent 9b14bebb2d
commit bd1bde1657

@ -2,77 +2,77 @@
use std::fmt::Debug; use std::fmt::Debug;
/// Trait implemented by types that can be used as a matrix index /** Trait implemented by types that can be used as a matrix index
///
/// There are currently two implementations: There are currently two implementations:
/// [`usize`](#impl-Index2D-for-usize) and [`(usize,usize)`](#impl-Index2D-for-(usize,+usize)) [`usize`](#impl-Index2D-for-usize) and [`(usize,usize)`](#impl-Index2D-for-(usize,+usize))
///
/// # Examples # Examples
/// Indexing by a `usize` indexes starting at the first element and Indexing by a `usize` indexes starting at the first element and
/// increments linearly in row-major order. This is especially useful for column vectors. increments linearly in row-major order. This is especially useful for column vectors.
///
/// ``` ```
/// # use vector_victor::{Matrix, Vector}; # use vector_victor::{Matrix, Vector};
/// let m = Matrix::mat([[1,2,3],[4,5,6],[7,8,9]]); let m = Matrix::mat([[1,2,3],[4,5,6],[7,8,9]]);
/// assert_eq!(m[0], 1); assert_eq!(m[0], 1);
/// assert_eq!(m[4], 5); assert_eq!(m[4], 5);
/// assert_eq!(m[7], 8); assert_eq!(m[7], 8);
///
/// let v = Vector::vec([4,8,15,16,23,42]); let v = Vector::vec([4,8,15,16,23,42]);
/// assert_eq!(v[2], 15); // just like a std::vec assert_eq!(v[2], 15); // just like a std::vec
/// ``` ```
///
/// Indexing by a `(usize,usize)` indexes by row and column Indexing by a `(usize,usize)` indexes by row and column
/// ``` ```
/// # use vector_victor::{Matrix, Vector}; # use vector_victor::{Matrix, Vector};
/// let m = Matrix::mat([[1,2,3],[4,5,6],[7,8,9]]); let m = Matrix::mat([[1,2,3],[4,5,6],[7,8,9]]);
/// assert_eq!(m[(0,0)], 1); assert_eq!(m[(0,0)], 1);
/// assert_eq!(m[(1,1)], 5); assert_eq!(m[(1,1)], 5);
/// assert_eq!(m[(2,1)], 8); assert_eq!(m[(2,1)], 8);
/// ``` ``` */
pub trait Index2D: Copy + Debug { pub trait Index2D: Copy + Debug {
/// Convert an index to its 1-D linear interpretation, given the `width` and `height` of the /** Convert an index to its 1-D linear interpretation, given the `width` and `height` of the
/// matrix being subscripted. matrix being subscripted.
///
/// If the index is out of bounds for the given dimensions, this returns `None`, If the index is out of bounds for the given dimensions, this returns `None`,
/// otherwise it returns `Some(usize)` otherwise it returns `Some(usize)`
///
/// # Examples # Examples
/// ``` ```
/// # use vector_victor::index::Index2D; # use vector_victor::index::Index2D;
/// assert_eq!( assert_eq!(
/// (1usize,2usize).to_1d(3,3), (1usize,2usize).to_1d(3,3),
/// Some(5), Some(5),
/// "(1,2) is index 5 in a 3×3 matrix"); "(1,2) is index 5 in a 3×3 matrix");
/// assert_eq!( assert_eq!(
/// (3usize, 2usize).to_1d(3,3), (3usize, 2usize).to_1d(3,3),
/// None, None,
/// "row 3, column 2 is out of bounds for a 3×3 matrix"); "row 3, column 2 is out of bounds for a 3×3 matrix");
/// ``` ``` */
#[inline(always)] #[inline(always)]
fn to_1d(self, height: usize, width: usize) -> Option<usize> { fn to_1d(self, height: usize, width: usize) -> Option<usize> {
let (r, c) = self.to_2d(height, width)?; let (r, c) = self.to_2d(height, width)?;
Some(r * width + c) Some(r * width + c)
} }
/// Convert an index to its 2-D interpretation, given the `width` and `height` of the /** Convert an index to its 2-D interpretation, given the `width` and `height` of the
/// matrix being subscripted. matrix being subscripted.
///
/// If the index is out of bounds for the given dimensions, this returns `None`, If the index is out of bounds for the given dimensions, this returns `None`,
/// otherwise it returns `Some((usize, usize))` otherwise it returns `Some((usize, usize))`
///
/// # Examples # Examples
/// ``` ```
/// # use vector_victor::index::Index2D; # use vector_victor::index::Index2D;
/// assert_eq!( assert_eq!(
/// 5usize.to_2d(3,3), 5usize.to_2d(3,3),
/// Some((1usize,2usize)), Some((1usize,2usize)),
/// "index 5 is at row 1 column 2 in a 3×3 matrix"); "index 5 is at row 1 column 2 in a 3×3 matrix");
/// assert_eq!( assert_eq!(
/// 10usize.to_2d(3,3), 10usize.to_2d(3,3),
/// None, None,
/// "a 3×3 matrix only has 9 elements, so index 10 is out of bounds."); "a 3×3 matrix only has 9 elements, so index 10 is out of bounds.");
/// ``` ``` */
fn to_2d(self, height: usize, width: usize) -> Option<(usize, usize)>; fn to_2d(self, height: usize, width: usize) -> Option<(usize, usize)>;
} }

@ -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,

@ -6,24 +6,25 @@ use std::ops::{Add, Mul};
/// Operations for column vectors /// Operations for column vectors
impl<T: Copy, const N: usize> Vector<T, N> { impl<T: Copy, const N: usize> Vector<T, N> {
/// Compute the dot product of two vectors, otherwise known as the scalar product. /** Compute the dot product of two vectors, otherwise known as the scalar product.
/// This is the sum of the elementwise product, or in math terms
/// This is the sum of the elementwise product, or in math terms
/// $vec(a) * vec(b) = sum_(i=1)^n a_i b_i = a_1 b_1 + a_2 b_2 + ... + a_n b_n$
/// $vec(a) * vec(b) = sum_(i=1)^n a_i b_i = a_1 b_1 + a_2 b_2 + ... + a_n b_n$
/// for example, $[[1],[2],[3]] * [[4],[5],[6]] = (1 * 4) + (2 * 5) + (3 * 6) = 32$
/// for example, $\[\[1],\[2],\[3]] * \[\[4],\[5],\[6]] = (1 * 4) + (2 * 5) + (3 * 6) = 32$
/// For vectors in euclidean space, this has the property that it is equal to the magnitudes of
/// the vectors times the cosine of the angle between them. For vectors in euclidean space, this has the property that it is equal to the magnitudes of
/// the vectors times the cosine of the angle between them.
/// $vec(a) * vec(b) = |vec(a)| |vec(b)| cos(theta)$
/// $vec(a) * vec(b) = |vec(a)| |vec(b)| cos(theta)$
/// this also gives it the special property that the dot product of a vector and itself is the
/// square of its magnitude. You may recognize the 2D version as the this also gives it the special property that the dot product of a vector and itself is the
/// [pythagorean theorem](https://en.wikipedia.org/wiki/Pythagorean_theorem). square of its magnitude. You may recognize the 2D version as the
/// [pythagorean theorem](https://en.wikipedia.org/wiki/Pythagorean_theorem).
/// see [dot product](https://en.wikipedia.org/wiki/Dot_product) on Wikipedia for more
/// information. see [dot product](https://en.wikipedia.org/wiki/Dot_product) on Wikipedia for more
information. */
pub fn dot<R>(&self, rhs: &R) -> T pub fn dot<R>(&self, rhs: &R) -> T
where where
for<'s> &'s Self: Mul<&'s R, Output = Self>, for<'s> &'s Self: Mul<&'s R, Output = Self>,

Loading…
Cancel
Save