use std::ops::Mul;
use general::{Field, MultiplicativeMonoid, MultiplicativeGroup};
use linear::FiniteDimVectorSpace;
pub trait Matrix: Sized + Clone +
Mul<<Self as Matrix>::Row, Output = <Self as Matrix>::Column> {
type Field: Field;
type Row: FiniteDimVectorSpace<Field = Self::Field>;
type Column: FiniteDimVectorSpace<Field = Self::Field>;
type Transpose: Matrix<Field = Self::Field, Row = Self::Column, Column = Self::Row>;
fn nrows(&self) -> usize;
fn ncolumns(&self) -> usize;
fn row(&self, i: usize) -> Self::Row;
fn column(&self, i: usize) -> Self::Column;
unsafe fn get_unchecked(&self, i: usize, j: usize) -> Self::Field;
fn get(&self, i: usize, j: usize) -> Self::Field {
assert!(i < self.nrows() && j < self.ncolumns(), "Matrix indexing: index out of bounds.");
unsafe { self.get_unchecked(i, j) }
}
fn transpose(&self) -> Self::Transpose;
}
pub trait MatrixMut: Matrix {
#[inline]
fn set_row(&self, i: usize, row: &Self::Row) -> Self {
let mut res = self.clone();
res.set_row_mut(i, row);
res
}
fn set_row_mut(&mut self, i: usize, row: &Self::Row);
#[inline]
fn set_column(&self, i: usize, col: &Self::Column) -> Self {
let mut res = self.clone();
res.set_column_mut(i, col);
res
}
fn set_column_mut(&mut self, i: usize, col: &Self::Column);
unsafe fn set_unchecked(&mut self, i: usize, j: usize, val: Self::Field);
fn set(&mut self, i: usize, j: usize, val: Self::Field) {
assert!(i < self.nrows() && j < self.ncolumns(), "Matrix indexing: index out of bounds.");
unsafe { self.set_unchecked(i, j, val) }
}
}
pub trait SquareMatrix
: Matrix<Row = <Self as SquareMatrix>::Vector,
Column = <Self as SquareMatrix>::Vector,
Transpose = Self> +
MultiplicativeMonoid {
type Vector: FiniteDimVectorSpace<Field = Self::Field>;
fn diagonal(&self) -> Self::Vector;
fn determinant(&self) -> Self::Field;
#[inline]
fn try_inverse(&self) -> Option<Self>;
#[inline]
fn dimension(&self) -> usize {
self.nrows()
}
#[inline]
fn transpose_mut(&mut self) {
*self = self.transpose()
}
}
pub trait SquareMatrixMut: SquareMatrix +
MatrixMut<Row = <Self as SquareMatrix>::Vector,
Column = <Self as SquareMatrix>::Vector,
Transpose = Self> {
fn from_diagonal(diag: &Self::Vector) -> Self;
#[inline]
fn set_diagonal(&self, diag: &Self::Vector) -> Self {
let mut res = self.clone();
res.set_diagonal_mut(diag);
res
}
fn set_diagonal_mut(&mut self, diag: &Self::Vector);
}
pub trait InversibleSquareMatrix: SquareMatrix + MultiplicativeGroup {
}