use super::ValuedMatrix2D;
use crate::traits::{
ImplicitValuedMatrix, SparseMatrix2D, SparseValuedMatrix, TotalOrd, ValuedMatrix,
};
pub trait SparseValuedMatrix2D: SparseMatrix2D + ValuedMatrix2D + SparseValuedMatrix {
type SparseRowValues<'a>: Iterator<Item = <Self as ValuedMatrix>::Value>
+ DoubleEndedIterator<Item = <Self as ValuedMatrix>::Value>
+ Clone
where
Self: 'a;
#[inline]
fn sparse_row_max_value(&self, row: Self::RowIndex) -> Option<<Self as ValuedMatrix>::Value>
where
Self::Value: TotalOrd,
{
self.sparse_row_values(row).max_by(TotalOrd::total_cmp)
}
#[inline]
fn sparse_row_max_value_and_column(
&self,
row: Self::RowIndex,
) -> Option<(Self::Value, Self::ColumnIndex)>
where
Self::Value: TotalOrd,
{
self.sparse_row_values(row)
.zip(self.sparse_row(row))
.max_by(|(value1, _), (value2, _)| value1.total_cmp(value2))
}
#[inline]
fn sparse_row_min_value(&self, row: Self::RowIndex) -> Option<Self::Value>
where
Self::Value: TotalOrd,
{
self.sparse_row_values(row).min_by(TotalOrd::total_cmp)
}
#[inline]
fn sparse_row_min_value_and_column(
&self,
row: Self::RowIndex,
) -> Option<(Self::Value, Self::ColumnIndex)>
where
Self::Value: TotalOrd,
{
self.sparse_row_values(row)
.zip(self.sparse_row(row))
.min_by(|(value1, _), (value2, _)| value1.total_cmp(value2))
}
fn sparse_row_values(&self, row: Self::RowIndex) -> Self::SparseRowValues<'_>;
#[inline]
fn sparse_value_at(&self, row: Self::RowIndex, column: Self::ColumnIndex) -> Option<Self::Value>
where
Self::ColumnIndex: PartialEq,
{
self.sparse_row(row)
.zip(self.sparse_row_values(row))
.find(|&(col, _)| col == column)
.map(|(_, val)| val)
}
#[inline]
fn sparse_row_max_values(&self) -> impl Iterator<Item = Option<Self::Value>>
where
Self::Value: TotalOrd,
{
self.row_indices().map(move |row| self.sparse_row_max_value(row))
}
#[inline]
fn sparse_row_min_values(&self) -> impl Iterator<Item = Option<Self::Value>>
where
Self::Value: TotalOrd,
{
self.row_indices().map(move |row| self.sparse_row_min_value(row))
}
}
impl<M: SparseValuedMatrix2D> SparseValuedMatrix2D for &M {
type SparseRowValues<'a>
= M::SparseRowValues<'a>
where
Self: 'a;
#[inline]
fn sparse_row_values(&self, row: Self::RowIndex) -> Self::SparseRowValues<'_> {
(*self).sparse_row_values(row)
}
#[inline]
fn sparse_value_at(&self, row: Self::RowIndex, column: Self::ColumnIndex) -> Option<Self::Value>
where
Self::ColumnIndex: PartialEq,
{
(*self).sparse_value_at(row, column)
}
}
pub struct ImplicitValuedSparseRowIterator<'matrix, M: SparseMatrix2D> {
iter: M::SparseRow<'matrix>,
row: M::RowIndex,
matrix: &'matrix M,
}
impl<M: SparseMatrix2D> Clone for ImplicitValuedSparseRowIterator<'_, M> {
#[inline]
fn clone(&self) -> Self {
Self { iter: self.iter.clone(), row: self.row, matrix: self.matrix }
}
}
impl<'matrix, M: SparseMatrix2D> ImplicitValuedSparseRowIterator<'matrix, M> {
#[inline]
pub fn new(matrix: &'matrix M, row: M::RowIndex) -> Self {
Self { iter: matrix.sparse_row(row), row, matrix }
}
}
impl<M> Iterator for ImplicitValuedSparseRowIterator<'_, M>
where
M: SparseMatrix2D + ImplicitValuedMatrix,
{
type Item = M::Value;
#[inline]
fn next(&mut self) -> Option<Self::Item> {
self.iter.next().map(|column| self.matrix.implicit_value(&(self.row, column)))
}
}
impl<'matrix, M> ExactSizeIterator for ImplicitValuedSparseRowIterator<'matrix, M>
where
M: SparseMatrix2D + ImplicitValuedMatrix,
M::SparseRow<'matrix>: ExactSizeIterator,
{
#[inline]
fn len(&self) -> usize {
self.iter.len()
}
}
impl<M> DoubleEndedIterator for ImplicitValuedSparseRowIterator<'_, M>
where
M: SparseMatrix2D + ImplicitValuedMatrix,
{
#[inline]
fn next_back(&mut self) -> Option<Self::Item> {
self.iter.next_back().map(|column| self.matrix.implicit_value(&(self.row, column)))
}
}
pub trait ImplicitSparseValuedMatrix2D: SparseValuedMatrix2D + ImplicitValuedMatrix {
type SparseRowImplicitValues<'a>: Iterator<Item = Self::Value>
+ DoubleEndedIterator<Item = Self::Value>
where
Self: 'a;
fn sparse_row_implicit_values(&self, row: Self::RowIndex) -> Self::SparseRowImplicitValues<'_>;
}
impl<M> ImplicitSparseValuedMatrix2D for M
where
M: SparseValuedMatrix2D + ImplicitValuedMatrix,
{
type SparseRowImplicitValues<'a>
= ImplicitValuedSparseRowIterator<'a, M>
where
Self: 'a;
#[inline]
fn sparse_row_implicit_values(&self, row: Self::RowIndex) -> Self::SparseRowImplicitValues<'_> {
ImplicitValuedSparseRowIterator { iter: self.sparse_row(row), row, matrix: self }
}
}