use super::{
BiMatrix2D, Matrix2D, RankSelectSparseMatrix, SizedSparseMatrix, SparseMatrix,
SymmetricMatrix2D,
};
pub trait SparseMatrix2D: Matrix2D + SparseMatrix {
type SparseRow<'a>: Iterator<Item = <Self as Matrix2D>::ColumnIndex>
+ DoubleEndedIterator<Item = <Self as Matrix2D>::ColumnIndex>
+ Clone
where
Self: 'a;
type SparseColumns<'a>: Iterator<Item = Self::ColumnIndex>
+ DoubleEndedIterator<Item = Self::ColumnIndex>
where
Self: 'a;
type SparseRows<'a>: Iterator<Item = Self::RowIndex>
+ DoubleEndedIterator<Item = Self::RowIndex>
where
Self: 'a;
fn sparse_row(&self, row: Self::RowIndex) -> Self::SparseRow<'_>;
#[inline]
fn has_entry(&self, row: Self::RowIndex, column: Self::ColumnIndex) -> bool {
self.sparse_row(row).any(|sparse_column| sparse_column == column)
}
fn sparse_columns(&self) -> Self::SparseColumns<'_>;
fn sparse_rows(&self) -> Self::SparseRows<'_>;
}
impl<M: SparseMatrix2D> SparseMatrix2D for &M {
type SparseRow<'a>
= M::SparseRow<'a>
where
Self: 'a;
type SparseColumns<'a>
= M::SparseColumns<'a>
where
Self: 'a;
type SparseRows<'a>
= M::SparseRows<'a>
where
Self: 'a;
#[inline]
fn sparse_row(&self, row: Self::RowIndex) -> Self::SparseRow<'_> {
(*self).sparse_row(row)
}
#[inline]
fn has_entry(&self, row: Self::RowIndex, column: Self::ColumnIndex) -> bool {
(*self).has_entry(row, column)
}
#[inline]
fn sparse_columns(&self) -> Self::SparseColumns<'_> {
(*self).sparse_columns()
}
#[inline]
fn sparse_rows(&self) -> Self::SparseRows<'_> {
(*self).sparse_rows()
}
}
pub trait EmptyRows: SparseMatrix2D {
type EmptyRowIndices<'a>: Iterator<Item = Self::RowIndex>
+ DoubleEndedIterator<Item = Self::RowIndex>
where
Self: 'a;
type NonEmptyRowIndices<'a>: Iterator<Item = Self::RowIndex>
+ DoubleEndedIterator<Item = Self::RowIndex>
where
Self: 'a;
fn number_of_empty_rows(&self) -> Self::RowIndex;
fn number_of_non_empty_rows(&self) -> Self::RowIndex;
fn empty_row_indices(&self) -> Self::EmptyRowIndices<'_>;
fn non_empty_row_indices(&self) -> Self::NonEmptyRowIndices<'_>;
}
impl<M: EmptyRows> EmptyRows for &M {
type EmptyRowIndices<'a>
= M::EmptyRowIndices<'a>
where
Self: 'a;
type NonEmptyRowIndices<'a>
= M::NonEmptyRowIndices<'a>
where
Self: 'a;
#[inline]
fn number_of_empty_rows(&self) -> Self::RowIndex {
(*self).number_of_empty_rows()
}
#[inline]
fn number_of_non_empty_rows(&self) -> Self::RowIndex {
(*self).number_of_non_empty_rows()
}
#[inline]
fn empty_row_indices(&self) -> Self::EmptyRowIndices<'_> {
(*self).empty_row_indices()
}
#[inline]
fn non_empty_row_indices(&self) -> Self::NonEmptyRowIndices<'_> {
(*self).non_empty_row_indices()
}
}
pub trait SizedRowsSparseMatrix2D: SparseMatrix2D + SizedSparseMatrix {
type SparseRowSizes<'a>: Iterator<Item = Self::ColumnIndex>
+ DoubleEndedIterator<Item = Self::ColumnIndex>
where
Self: 'a;
fn sparse_row_sizes(&self) -> Self::SparseRowSizes<'_>;
fn number_of_defined_values_in_row(&self, row: Self::RowIndex) -> Self::ColumnIndex;
}
pub trait SizedSparseMatrix2D: SizedRowsSparseMatrix2D + RankSelectSparseMatrix {
fn rank_row(&self, row: Self::RowIndex) -> Self::SparseIndex;
fn select_row(&self, sparse_index: Self::SparseIndex) -> Self::RowIndex;
fn select_column(&self, sparse_index: Self::SparseIndex) -> Self::ColumnIndex;
#[inline]
fn try_rank(&self, row: Self::RowIndex, column: Self::ColumnIndex) -> Option<Self::SparseIndex>
where
Self::ColumnIndex: PartialEq,
{
if self.has_entry(row, column) { Some(self.rank(&(row, column))) } else { None }
}
#[inline]
fn sparse_index(
&self,
row: Self::RowIndex,
column: Self::ColumnIndex,
) -> Option<Self::SparseIndex>
where
Self::ColumnIndex: PartialEq,
{
self.try_rank(row, column)
}
}
pub trait SparseBiMatrix2D:
BiMatrix2D<
Matrix = <Self as SparseBiMatrix2D>::SparseMatrix,
TransposedMatrix = <Self as SparseBiMatrix2D>::SparseTransposedMatrix,
> + SparseMatrix2D
{
type SparseMatrix: SparseMatrix2D<RowIndex = Self::RowIndex, ColumnIndex = Self::ColumnIndex>;
type SparseTransposedMatrix: SparseMatrix2D<RowIndex = Self::ColumnIndex, ColumnIndex = Self::RowIndex>;
#[inline]
fn sparse_column(
&self,
column: Self::ColumnIndex,
) -> <Self::SparseTransposedMatrix as SparseMatrix2D>::SparseRow<'_> {
self.transposed().sparse_row(column)
}
}
impl<M> SparseBiMatrix2D for M
where
M: BiMatrix2D + SparseMatrix2D,
M::Matrix: SparseMatrix2D<RowIndex = Self::RowIndex, ColumnIndex = Self::ColumnIndex>,
M::TransposedMatrix: SparseMatrix2D<RowIndex = Self::ColumnIndex, ColumnIndex = Self::RowIndex>,
{
type SparseMatrix = M::Matrix;
type SparseTransposedMatrix = M::TransposedMatrix;
}
pub trait SizedSparseBiMatrix2D:
SparseBiMatrix2D<
SparseMatrix = <Self as SizedSparseBiMatrix2D>::SizedSparseMatrix,
SparseTransposedMatrix = <Self as SizedSparseBiMatrix2D>::SizedSparseTransposedMatrix,
> + SizedSparseMatrix2D
{
type SizedSparseMatrix: SizedSparseMatrix2D<RowIndex = Self::RowIndex, ColumnIndex = Self::ColumnIndex>;
type SizedSparseTransposedMatrix: SizedSparseMatrix2D<RowIndex = Self::ColumnIndex, ColumnIndex = Self::RowIndex>;
#[inline]
fn number_of_defined_values_in_column(&self, column: Self::ColumnIndex) -> Self::RowIndex {
self.transposed().number_of_defined_values_in_row(column)
}
#[inline]
fn sparse_column_sizes(
&self,
) -> <Self::SizedSparseTransposedMatrix as SizedRowsSparseMatrix2D>::SparseRowSizes<'_> {
self.transposed().sparse_row_sizes()
}
}
impl<M> SizedSparseBiMatrix2D for M
where
M: SparseBiMatrix2D + SizedSparseMatrix2D,
M::Matrix: SizedSparseMatrix2D<RowIndex = Self::RowIndex, ColumnIndex = Self::ColumnIndex>,
M::TransposedMatrix:
SizedSparseMatrix2D<RowIndex = Self::ColumnIndex, ColumnIndex = Self::RowIndex>,
{
type SizedSparseMatrix = M::Matrix;
type SizedSparseTransposedMatrix = M::TransposedMatrix;
}
pub trait SparseSymmetricMatrix2D:
SymmetricMatrix2D<SymmetricMatrix = <Self as SparseSymmetricMatrix2D>::SymmetricSparseMatrix>
+ SparseMatrix2D
{
type SymmetricSparseMatrix: SparseMatrix2D<RowIndex = Self::RowIndex, ColumnIndex = Self::ColumnIndex>;
}
impl<M> SparseSymmetricMatrix2D for M
where
M: SymmetricMatrix2D + SparseMatrix2D,
M::Matrix: SparseMatrix2D<RowIndex = Self::RowIndex, ColumnIndex = Self::ColumnIndex>,
{
type SymmetricSparseMatrix = M::Matrix;
}