pub mod cholesky;
pub mod decomposition_tests;
pub mod lu;
pub mod qr;
pub mod svd;
use crate::core::Expression;
use crate::matrices::types::*;
use crate::matrices::unified::Matrix;
pub trait MatrixDecomposition {
fn lu_decomposition(&self) -> Option<LUDecomposition>;
fn qr_decomposition(&self) -> Option<QRDecomposition>;
fn cholesky_decomposition(&self) -> Option<CholeskyDecomposition>;
fn svd_decomposition(&self) -> Option<SVDDecomposition>;
fn rank(&self) -> usize;
fn is_positive_definite(&self) -> bool;
fn condition_number(&self) -> Expression;
}
impl MatrixDecomposition for Matrix {
fn lu_decomposition(&self) -> Option<LUDecomposition> {
self.lu_decomposition()
}
fn qr_decomposition(&self) -> Option<QRDecomposition> {
self.qr_decomposition()
}
fn cholesky_decomposition(&self) -> Option<CholeskyDecomposition> {
self.cholesky_decomposition()
}
fn svd_decomposition(&self) -> Option<SVDDecomposition> {
self.svd_decomposition()
}
fn rank(&self) -> usize {
self.rank_via_svd()
}
fn is_positive_definite(&self) -> bool {
self.is_positive_definite_cholesky()
}
fn condition_number(&self) -> Expression {
self.condition_number_via_svd()
}
}
impl Matrix {
pub(crate) fn to_dense_matrix(&self) -> Matrix {
let (rows, cols) = self.dimensions();
let mut dense_rows = Vec::with_capacity(rows);
for i in 0..rows {
let mut row = Vec::with_capacity(cols);
for j in 0..cols {
row.push(self.get_element(i, j));
}
dense_rows.push(row);
}
Matrix::dense(dense_rows)
}
pub(crate) fn swap_rows(&self, row1: usize, row2: usize) -> Matrix {
if row1 == row2 {
return self.clone();
}
let (rows, cols) = self.dimensions();
let mut new_rows = Vec::with_capacity(rows);
for i in 0..rows {
let mut row = Vec::with_capacity(cols);
let source_row = if i == row1 {
row2
} else if i == row2 {
row1
} else {
i
};
for j in 0..cols {
row.push(self.get_element(source_row, j));
}
new_rows.push(row);
}
Matrix::dense(new_rows)
}
pub(crate) fn set_element(&self, i: usize, j: usize, value: &Expression) -> Matrix {
let (rows, cols) = self.dimensions();
let mut new_rows = Vec::with_capacity(rows);
for row_idx in 0..rows {
let mut row = Vec::with_capacity(cols);
for col_idx in 0..cols {
if row_idx == i && col_idx == j {
row.push(value.clone());
} else {
row.push(self.get_element(row_idx, col_idx));
}
}
new_rows.push(row);
}
Matrix::dense(new_rows)
}
}