Skip to main content

Matrix

Struct Matrix 

Source
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>

Source

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.

Source

pub fn zeros(nrows: usize, ncols: usize, domain: D) -> Self

Create a zero matrix of the given shape.

Source

pub fn identity(n: usize, domain: D) -> Self

Create an identity matrix of size n.

Source

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.

Source

pub fn nrows(&self) -> usize

Return the number of rows.

Source

pub fn ncols(&self) -> usize

Return the number of columns.

Source

pub fn domain(&self) -> &D

Return a reference to the domain.

Source

pub fn swap_rows(&mut self, i: usize, j: usize, start_col: usize)

Swap two rows, starting from column start_col.

Source

pub fn augment(&self, other: &Matrix<D>) -> Result<Matrix<D>, MatrixError>

Horizontally concatenate self with other.

Both must have the same number of rows.

Source

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.

Source

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).

Source

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.

Source

pub fn into_rows(self) -> Vec<Vec<D::Element>>

Convert the matrix into a nested vector of rows.

Source

pub fn data(&self) -> &[D::Element]

Return a reference to the underlying row-major data.

Source

pub fn row(&self, i: usize) -> Vec<D::Element>

Return a copy of a single row as a vector.

Source

pub fn column(&self, j: usize) -> Vec<D::Element>

Return a copy of a single column as a vector.

Source

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));
Source

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));
Source

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));
Source

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);
Source

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));
Source

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));

Trait Implementations§

Source§

impl<D: Clone + EuclideanDomain> Clone for Matrix<D>
where D::Element: Clone,

Source§

fn clone(&self) -> Matrix<D>

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl<D: Debug + EuclideanDomain> Debug for Matrix<D>
where D::Element: Debug,

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl<D: EuclideanDomain + Display> Display for Matrix<D>
where D::Element: Display,

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl<D: Eq + EuclideanDomain> Eq for Matrix<D>
where D::Element: Eq,

Source§

impl<D: EuclideanDomain> Index<(usize, usize)> for Matrix<D>

Source§

type Output = <D as Domain>::Element

The returned type after indexing.
Source§

fn index(&self, (row, col): (usize, usize)) -> &Self::Output

Performs the indexing (container[index]) operation. Read more
Source§

impl<D: EuclideanDomain> IndexMut<(usize, usize)> for Matrix<D>

Source§

fn index_mut(&mut self, (row, col): (usize, usize)) -> &mut Self::Output

Performs the mutable indexing (container[index]) operation. Read more
Source§

impl<D: PartialEq + EuclideanDomain> PartialEq for Matrix<D>
where D::Element: PartialEq,

Source§

fn eq(&self, other: &Matrix<D>) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 (const: unstable) · Source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
Source§

impl<D: PartialEq + EuclideanDomain> StructuralPartialEq for Matrix<D>
where D::Element: PartialEq,

Auto Trait Implementations§

§

impl<D> Freeze for Matrix<D>
where D: Freeze,

§

impl<D> RefUnwindSafe for Matrix<D>

§

impl<D> Send for Matrix<D>
where D: Send, <D as Domain>::Element: Send,

§

impl<D> Sync for Matrix<D>
where D: Sync, <D as Domain>::Element: Sync,

§

impl<D> Unpin for Matrix<D>
where D: Unpin, <D as Domain>::Element: Unpin,

§

impl<D> UnsafeUnpin for Matrix<D>
where D: UnsafeUnpin,

§

impl<D> UnwindSafe for Matrix<D>
where D: UnwindSafe, <D as Domain>::Element: UnwindSafe,

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T> ToString for T
where T: Display + ?Sized,

Source§

fn to_string(&self) -> String

Converts the given value to a String. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.