|
@@ -1,10 +1,10 @@
|
|
|
use std::ops::{Add, AddAssign, Div, DivAssign, Index, IndexMut, Mul, MulAssign, Neg, Sub, SubAssign};
|
|
|
use std::ptr::swap;
|
|
|
|
|
|
-use crate::{Float, Matrix, Numeric, Primitive, View};
|
|
|
+use crate::{Float, Matrix, Numeric, Primitive, View, ViewMut};
|
|
|
#[cfg(feature = "angular")]
|
|
|
use crate::Angular;
|
|
|
-use crate::types::matrix::matrices_are_equal;
|
|
|
+use crate::types::matrix::{compare, ComparisonResult, MatrixMut, multiply};
|
|
|
|
|
|
/// Struct representing a dense matrix.
|
|
|
#[repr(transparent)]
|
|
@@ -17,7 +17,9 @@ impl<T: Numeric, const ROWS: usize, const COLUMNS: usize> Matrix<T, ROWS, COLUMN
|
|
|
fn get(&self, row: usize, col: usize) -> T {
|
|
|
self.data[row][col]
|
|
|
}
|
|
|
+}
|
|
|
|
|
|
+impl<T: Numeric, const ROWS: usize, const COLUMNS: usize> MatrixMut<T, ROWS, COLUMNS> for GenericMatrix<T, ROWS, COLUMNS> {
|
|
|
fn set(&mut self, row: usize, col: usize, value: T) {
|
|
|
self.data[row][col] = value;
|
|
|
}
|
|
@@ -94,8 +96,68 @@ impl<T: Numeric, const ROWS: usize, const COLUMNS: usize> GenericMatrix<T, ROWS,
|
|
|
Self::default()
|
|
|
}
|
|
|
|
|
|
- pub fn view<const VIEW_ROWS: usize, const VIEW_COLUMNS: usize>(&self, origin: (usize, usize)) -> View<T, VIEW_ROWS, VIEW_COLUMNS, ROWS, COLUMNS, Self> {
|
|
|
- View::new(self, origin)
|
|
|
+ /// Create a view for a part of the matrix.
|
|
|
+ ///
|
|
|
+ /// # Example
|
|
|
+ ///
|
|
|
+ /// ```rust
|
|
|
+ /// # use lineal::GenericMatrix;
|
|
|
+ /// let mat = GenericMatrix::from([
|
|
|
+ /// [1, 2, 3, 4],
|
|
|
+ /// [5, 6, 7, 8],
|
|
|
+ /// [9, 10, 11, 12],
|
|
|
+ /// ]);
|
|
|
+ /// // 3 and 2 are the size of the view, 0 and 1 are the starting indices of the view.
|
|
|
+ /// let view = mat.view::<3, 2>(0, 1);
|
|
|
+ /// assert_eq!(
|
|
|
+ /// view,
|
|
|
+ /// GenericMatrix::from([
|
|
|
+ /// [2, 3],
|
|
|
+ /// [6, 7],
|
|
|
+ /// [10, 11],
|
|
|
+ /// ])
|
|
|
+ /// );
|
|
|
+ /// ```
|
|
|
+ pub fn view<const VIEW_ROWS: usize, const VIEW_COLUMNS: usize>(&self, base_row: usize, base_col: usize) -> View<T, VIEW_ROWS, VIEW_COLUMNS, ROWS, COLUMNS, Self> {
|
|
|
+ View::new(self, (base_row, base_col))
|
|
|
+ }
|
|
|
+
|
|
|
+ /// Create a mutable view for a part of the matrix.
|
|
|
+ ///
|
|
|
+ /// # Example
|
|
|
+ ///
|
|
|
+ /// ```rust
|
|
|
+ /// # use lineal::{GenericMatrix, MatrixMut};
|
|
|
+ /// let mut mat = GenericMatrix::from([
|
|
|
+ /// [1, 2, 3, 4],
|
|
|
+ /// [5, 6, 7, 8],
|
|
|
+ /// [9, 10, 11, 12],
|
|
|
+ /// ]);
|
|
|
+ /// {
|
|
|
+ /// // 3 and 2 are the size of the view, 0 and 1 are the starting indices of the view.
|
|
|
+ /// let mut view = mat.view_mut::<3, 2>(0, 1);
|
|
|
+ /// view.set(1, 0, 23);
|
|
|
+ /// view.set(1, 1, 42);
|
|
|
+ /// assert_eq!(
|
|
|
+ /// view,
|
|
|
+ /// GenericMatrix::from([
|
|
|
+ /// [2, 3],
|
|
|
+ /// [23, 42],
|
|
|
+ /// [10, 11],
|
|
|
+ /// ])
|
|
|
+ /// );
|
|
|
+ /// }
|
|
|
+ /// assert_eq!(
|
|
|
+ /// mat,
|
|
|
+ /// GenericMatrix::from([
|
|
|
+ /// [1, 2, 3, 4],
|
|
|
+ /// [5, 23, 42, 8],
|
|
|
+ /// [9, 10, 11, 12],
|
|
|
+ /// ])
|
|
|
+ /// );
|
|
|
+ /// ```
|
|
|
+ pub fn view_mut<const VIEW_ROWS: usize, const VIEW_COLUMNS: usize>(&mut self, base_row: usize, base_col: usize) -> ViewMut<T, VIEW_ROWS, VIEW_COLUMNS, ROWS, COLUMNS, Self> {
|
|
|
+ ViewMut::new(self, (base_row, base_col))
|
|
|
}
|
|
|
|
|
|
/// Create a transpose of the input matrix.
|
|
@@ -352,39 +414,39 @@ impl<T: Numeric + Neg<Output=T>, const ROWS: usize, const COLUMNS: usize> Neg fo
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-impl<T: Numeric, const ROWS: usize, const COLUMNS: usize> Add for GenericMatrix<T, ROWS, COLUMNS> {
|
|
|
+impl<T: Numeric, const ROWS: usize, const COLUMNS: usize, RHS: Matrix<T, ROWS, COLUMNS>> Add<RHS> for GenericMatrix<T, ROWS, COLUMNS> {
|
|
|
type Output = Self;
|
|
|
|
|
|
- fn add(mut self, rhs: Self) -> Self::Output {
|
|
|
+ fn add(mut self, rhs: RHS) -> Self::Output {
|
|
|
self += rhs;
|
|
|
self
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-impl<T: Numeric, const ROWS: usize, const COLUMNS: usize> AddAssign for GenericMatrix<T, ROWS, COLUMNS> {
|
|
|
- fn add_assign(&mut self, rhs: Self) {
|
|
|
+impl<T: Numeric, const ROWS: usize, const COLUMNS: usize, RHS: Matrix<T, ROWS, COLUMNS>> AddAssign<RHS> for GenericMatrix<T, ROWS, COLUMNS> {
|
|
|
+ fn add_assign(&mut self, rhs: RHS) {
|
|
|
for r in 0..ROWS {
|
|
|
for c in 0..COLUMNS {
|
|
|
- self.data[r][c] += rhs.data[r][c];
|
|
|
+ self.data[r][c] += rhs.get(r, c);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-impl<T: Numeric, const ROWS: usize, const COLUMNS: usize> Sub for GenericMatrix<T, ROWS, COLUMNS> {
|
|
|
+impl<T: Numeric, const ROWS: usize, const COLUMNS: usize, RHS: Matrix<T, ROWS, COLUMNS>> Sub<RHS> for GenericMatrix<T, ROWS, COLUMNS> {
|
|
|
type Output = Self;
|
|
|
|
|
|
- fn sub(mut self, rhs: Self) -> Self::Output {
|
|
|
+ fn sub(mut self, rhs: RHS) -> Self::Output {
|
|
|
self -= rhs;
|
|
|
self
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-impl<T: Numeric, const ROWS: usize, const COLUMNS: usize> SubAssign for GenericMatrix<T, ROWS, COLUMNS> {
|
|
|
- fn sub_assign(&mut self, rhs: Self) {
|
|
|
+impl<T: Numeric, const ROWS: usize, const COLUMNS: usize, RHS: Matrix<T, ROWS, COLUMNS>> SubAssign<RHS> for GenericMatrix<T, ROWS, COLUMNS> {
|
|
|
+ fn sub_assign(&mut self, rhs: RHS) {
|
|
|
for r in 0..ROWS {
|
|
|
for c in 0..COLUMNS {
|
|
|
- self.data[r][c] -= rhs.data[r][c];
|
|
|
+ self.data[r][c] -= rhs.get(r, c);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
@@ -441,13 +503,7 @@ impl<T: Numeric, const ROWS: usize, const COMMON: usize, const COLUMNS: usize> M
|
|
|
|
|
|
fn mul(self, rhs: GenericMatrix<T, COMMON, COLUMNS>) -> Self::Output {
|
|
|
let mut result = Self::Output::default();
|
|
|
- for i in 0..ROWS {
|
|
|
- for j in 0..COLUMNS {
|
|
|
- for k in 0..COMMON {
|
|
|
- result.data[i][j] += self.data[i][k] * rhs.data[k][j];
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
+ multiply(&mut result, &self, &rhs);
|
|
|
result
|
|
|
}
|
|
|
}
|
|
@@ -518,17 +574,17 @@ impl<T: Numeric + Float + Primitive> SquareMatrix<T, 4> {
|
|
|
|
|
|
impl<T: Numeric, const ROWS: usize, const COLUMNS: usize, RHS: Matrix<T, ROWS, COLUMNS>> PartialEq<RHS> for GenericMatrix<T, ROWS, COLUMNS> {
|
|
|
fn eq(&self, other: &RHS) -> bool {
|
|
|
- matrices_are_equal(self, other, T::epsilon())
|
|
|
+ compare(self, other, T::epsilon()) == ComparisonResult::Equal
|
|
|
}
|
|
|
|
|
|
fn ne(&self, other: &RHS) -> bool {
|
|
|
- !matrices_are_equal(self, other, T::epsilon())
|
|
|
+ compare(self, other, T::epsilon()) == ComparisonResult::NotEqual
|
|
|
}
|
|
|
}
|
|
|
|
|
|
#[cfg(test)]
|
|
|
mod tests {
|
|
|
- use crate::{ColumnVector, Complex, cplx, GenericMatrix, Matrix, RowVector, SquareMatrix};
|
|
|
+ use crate::{ColumnVector, Complex, cplx, GenericMatrix, Matrix, MatrixMut, RowVector, SquareMatrix};
|
|
|
|
|
|
#[test]
|
|
|
fn identity_matrix() {
|