pub struct Matrix<D: EuclideanDomain> { /* private fields */ }Expand description
A dense matrix with elements from a EuclideanDomain.
Elements are stored in row-major order.
§Example
use ocas_domain::{EuclideanDomain, IntegerDomain, Integer};
use ocas_poly::matrix::Matrix;
let d = IntegerDomain;
let a = Matrix::from_rows(vec![
vec![Integer::from(1), Integer::from(1)],
vec![Integer::from(1), Integer::from(-1)],
], d);
let b = vec![Integer::from(3), Integer::from(-1)];
let x = a.solve(&b).unwrap();
assert_eq!(x, vec![Integer::from(1), Integer::from(2)]);Implementations§
Source§impl<D: EuclideanDomain> Matrix<D>
impl<D: EuclideanDomain> Matrix<D>
Sourcepub fn new(nrows: usize, ncols: usize, data: Vec<D::Element>, domain: D) -> Self
pub fn new(nrows: usize, ncols: usize, data: Vec<D::Element>, domain: D) -> Self
Create a matrix from row-major data.
Panics if data.len() != nrows * ncols.
Sourcepub fn zeros(nrows: usize, ncols: usize, domain: D) -> Self
pub fn zeros(nrows: usize, ncols: usize, domain: D) -> Self
Create a zero matrix of the given shape.
Sourcepub fn from_rows(rows: Vec<Vec<D::Element>>, domain: D) -> Self
pub fn from_rows(rows: Vec<Vec<D::Element>>, domain: D) -> Self
Create a matrix from nested row vectors.
Returns None if rows have inconsistent lengths.
Sourcepub fn swap_rows(&mut self, i: usize, j: usize, start_col: usize)
pub fn swap_rows(&mut self, i: usize, j: usize, start_col: usize)
Swap two rows, starting from column start_col.
Sourcepub fn augment(&self, other: &Matrix<D>) -> Result<Matrix<D>, MatrixError>
pub fn augment(&self, other: &Matrix<D>) -> Result<Matrix<D>, MatrixError>
Horizontally concatenate self with other.
Both must have the same number of rows.
Sourcepub fn row_echelon(&mut self, max_col: usize) -> usize
pub fn row_echelon(&mut self, max_col: usize) -> usize
Perform fraction-free Gaussian elimination on the first max_col
columns, putting the matrix in row echelon form. Returns the rank.
This mirrors Symbolica’s partial_row_reduce_fraction_free.
Sourcepub fn back_substitution(&mut self, max_col: usize)
pub fn back_substitution(&mut self, max_col: usize)
Perform fraction-free back substitution on a matrix already in
row echelon form (mutating the first max_col columns).
Sourcepub fn solve(&self, b: &[D::Element]) -> Result<Vec<D::Element>, MatrixError>
pub fn solve(&self, b: &[D::Element]) -> Result<Vec<D::Element>, MatrixError>
Solve the linear system Ax = b where A is self and b is a
column vector represented as a slice.
Returns the solution vector x on success.
Sourcepub fn into_rows(self) -> Vec<Vec<D::Element>>
pub fn into_rows(self) -> Vec<Vec<D::Element>>
Convert the matrix into a nested vector of rows.
Sourcepub fn column(&self, j: usize) -> Vec<D::Element>
pub fn column(&self, j: usize) -> Vec<D::Element>
Return a copy of a single column as a vector.
Sourcepub fn transpose(&self) -> Matrix<D>
pub fn transpose(&self) -> Matrix<D>
Return the transpose of the matrix.
§Example
use ocas_domain::{Integer, IntegerDomain};
use ocas_poly::matrix::Matrix;
let d = IntegerDomain;
let a = Matrix::from_rows(vec![vec![Integer::from(1), Integer::from(2)]], d);
let t = a.transpose();
assert_eq!(t.nrows(), 2);
assert_eq!(t.ncols(), 1);
assert_eq!(t[(0, 0)], Integer::from(1));
assert_eq!(t[(1, 0)], Integer::from(2));Sourcepub fn trace(&self) -> Result<D::Element, MatrixError>
pub fn trace(&self) -> Result<D::Element, MatrixError>
Return the trace (sum of the diagonal) of a square matrix.
Returns an error if the matrix is not square.
§Example
use ocas_domain::{Integer, IntegerDomain};
use ocas_poly::matrix::Matrix;
let d = IntegerDomain;
let a = Matrix::from_rows(
vec![vec![Integer::from(1), Integer::from(2)], vec![Integer::from(3), Integer::from(4)]],
d,
);
assert_eq!(a.trace().unwrap(), Integer::from(5));Sourcepub fn matmul(&self, other: &Matrix<D>) -> Result<Matrix<D>, MatrixError>
pub fn matmul(&self, other: &Matrix<D>) -> Result<Matrix<D>, MatrixError>
Compute the matrix product self * other.
Returns an error if self.ncols != other.nrows.
§Example
use ocas_domain::{Integer, IntegerDomain};
use ocas_poly::matrix::Matrix;
let d = IntegerDomain;
let a = Matrix::from_rows(vec![vec![Integer::from(1), Integer::from(2)]], d);
let b = Matrix::from_rows(vec![vec![Integer::from(3)], vec![Integer::from(4)]], d);
let c = a.matmul(&b).unwrap();
assert_eq!(c[(0, 0)], Integer::from(11));Sourcepub fn rank(&self) -> usize
pub fn rank(&self) -> usize
Compute the rank of the matrix via fraction-free Gaussian elimination.
§Example
use ocas_domain::{Integer, IntegerDomain};
use ocas_poly::matrix::Matrix;
let d = IntegerDomain;
let a = Matrix::from_rows(
vec![vec![Integer::from(1), Integer::from(2)], vec![Integer::from(2), Integer::from(4)]],
d,
);
assert_eq!(a.rank(), 1);Sourcepub fn determinant(&self) -> Result<D::Element, MatrixError>
pub fn determinant(&self) -> Result<D::Element, MatrixError>
Compute the determinant of a square matrix using the Bareiss fraction-free algorithm with partial pivoting.
Returns an error if the matrix is not square.
§Example
use ocas_domain::{Integer, IntegerDomain};
use ocas_poly::matrix::Matrix;
let d = IntegerDomain;
let a = Matrix::from_rows(
vec![vec![Integer::from(1), Integer::from(2)], vec![Integer::from(3), Integer::from(4)]],
d,
);
assert_eq!(a.determinant().unwrap(), Integer::from(-2));Sourcepub fn inverse(&self) -> Result<Matrix<D>, MatrixError>
pub fn inverse(&self) -> Result<Matrix<D>, MatrixError>
Compute the inverse of a square non-singular matrix.
Returns an error if the matrix is not square or is singular over the coefficient domain.
§Example
use ocas_domain::{Integer, IntegerDomain};
use ocas_poly::matrix::Matrix;
let d = IntegerDomain;
// Unimodular matrix: determinant 1, integer inverse exists.
let a = Matrix::from_rows(
vec![vec![Integer::from(1), Integer::from(2)], vec![Integer::from(0), Integer::from(1)]],
d,
);
let inv = a.inverse().unwrap();
assert_eq!(inv[(0, 0)], Integer::from(1));
assert_eq!(inv[(0, 1)], Integer::from(-2));
assert_eq!(inv[(1, 0)], Integer::from(0));
assert_eq!(inv[(1, 1)], Integer::from(1));