#[cfg(feature = "alloc")]
use alloc::vec::Vec;
mod dense_matrix;
mod dense_matrix2d;
mod matrix2d;
mod matrix_mut;
mod sparse_matrix2d;
mod square_matrix;
mod transposed_valued_matrix2d;
mod triangular_matrix;
mod valued_matrix2d;
pub use dense_matrix::*;
pub use dense_matrix2d::*;
pub use matrix_mut::*;
pub use matrix2d::*;
use num_traits::AsPrimitive;
pub use sparse_matrix2d::*;
pub use square_matrix::*;
pub use transposed_valued_matrix2d::*;
pub use triangular_matrix::*;
pub use valued_matrix2d::*;
use super::Coordinates;
use crate::{
impls::ImplicitValuedSparseIterator,
traits::{PositiveInteger, TotalOrd},
};
pub trait Matrix {
type Coordinates: Coordinates;
#[must_use]
#[inline]
fn dimensions() -> usize {
Self::Coordinates::dimensions()
}
#[must_use]
#[cfg(feature = "alloc")]
fn shape(&self) -> alloc::vec::Vec<usize>;
#[must_use]
#[cfg(feature = "alloc")]
#[inline]
fn total_values(&self) -> usize {
self.shape().iter().product()
}
}
impl<M: Matrix> Matrix for &M {
type Coordinates = M::Coordinates;
#[inline]
fn dimensions() -> usize {
M::dimensions()
}
#[cfg(feature = "alloc")]
#[inline]
fn shape(&self) -> Vec<usize> {
(*self).shape()
}
#[cfg(feature = "alloc")]
#[inline]
fn total_values(&self) -> usize {
(*self).total_values()
}
}
pub trait ValuedMatrix: Matrix {
type Value;
}
impl<M: ValuedMatrix> ValuedMatrix for &M {
type Value = M::Value;
}
pub trait ImplicitValuedMatrix: ValuedMatrix {
fn implicit_value(&self, coordinates: &Self::Coordinates) -> Self::Value;
}
pub trait SparseMatrix: Matrix {
type SparseIndex: PositiveInteger + AsPrimitive<usize>;
type SparseCoordinates<'a>: Iterator<Item = Self::Coordinates>
+ DoubleEndedIterator<Item = Self::Coordinates>
where
Self: 'a;
fn sparse_coordinates(&self) -> Self::SparseCoordinates<'_>;
fn last_sparse_coordinates(&self) -> Option<Self::Coordinates>;
fn is_empty(&self) -> bool;
}
impl<M: SparseMatrix> SparseMatrix for &M {
type SparseIndex = M::SparseIndex;
type SparseCoordinates<'a>
= M::SparseCoordinates<'a>
where
Self: 'a;
#[inline]
fn sparse_coordinates(&self) -> Self::SparseCoordinates<'_> {
(*self).sparse_coordinates()
}
#[inline]
fn last_sparse_coordinates(&self) -> Option<Self::Coordinates> {
(*self).last_sparse_coordinates()
}
#[inline]
fn is_empty(&self) -> bool {
(*self).is_empty()
}
}
pub trait SizedSparseMatrix: SparseMatrix {
#[allow(clippy::cast_precision_loss)]
#[cfg(feature = "alloc")]
#[inline]
fn density(&self) -> f64 {
let defined_values = self.number_of_defined_values().as_();
let total_values = self.total_values();
if total_values == 0 {
return 0.0;
}
defined_values as f64 / total_values as f64
}
fn number_of_defined_values(&self) -> Self::SparseIndex;
}
impl<M: SizedSparseMatrix> SizedSparseMatrix for &M {
#[inline]
fn number_of_defined_values(&self) -> Self::SparseIndex {
(*self).number_of_defined_values()
}
}
pub trait RankSelectSparseMatrix: SizedSparseMatrix {
fn rank(&self, coordinates: &Self::Coordinates) -> Self::SparseIndex;
fn select(&self, sparse_index: Self::SparseIndex) -> Self::Coordinates;
}
impl<M: RankSelectSparseMatrix> RankSelectSparseMatrix for &M {
#[inline]
fn rank(&self, coordinates: &Self::Coordinates) -> Self::SparseIndex {
(*self).rank(coordinates)
}
#[inline]
fn select(&self, sparse_index: Self::SparseIndex) -> Self::Coordinates {
(*self).select(sparse_index)
}
}
pub trait DenseValuedMatrix: DenseMatrix + ValuedMatrix {
type Values<'a>: Iterator<Item = Self::Value> + DoubleEndedIterator<Item = Self::Value>
where
Self: 'a;
#[inline]
fn max_value(&self) -> Option<Self::Value>
where
Self::Value: TotalOrd,
{
self.values().max_by(TotalOrd::total_cmp)
}
#[inline]
fn min_value(&self) -> Option<Self::Value>
where
Self::Value: TotalOrd,
{
self.values().min_by(TotalOrd::total_cmp)
}
fn value(&self, coordinates: Self::Coordinates) -> Self::Value;
fn values(&self) -> Self::Values<'_>;
}
impl<M: DenseValuedMatrix> DenseValuedMatrix for &M {
type Values<'a>
= M::Values<'a>
where
Self: 'a;
#[inline]
fn value(&self, coordinates: Self::Coordinates) -> Self::Value {
(*self).value(coordinates)
}
#[inline]
fn values(&self) -> Self::Values<'_> {
(*self).values()
}
}
pub trait SparseValuedMatrix: SparseMatrix + ValuedMatrix {
type SparseValues<'a>: Iterator<Item = Self::Value> + DoubleEndedIterator<Item = Self::Value>
where
Self: 'a;
#[inline]
fn max_sparse_value(&self) -> Option<Self::Value>
where
Self::Value: TotalOrd,
{
self.sparse_values().max_by(TotalOrd::total_cmp)
}
#[inline]
fn min_sparse_value(&self) -> Option<Self::Value>
where
Self::Value: TotalOrd,
{
self.sparse_values().min_by(TotalOrd::total_cmp)
}
fn sparse_values(&self) -> Self::SparseValues<'_>;
}
impl<M: SparseValuedMatrix> SparseValuedMatrix for &M {
type SparseValues<'a>
= M::SparseValues<'a>
where
Self: 'a;
#[inline]
fn sparse_values(&self) -> Self::SparseValues<'_> {
(*self).sparse_values()
}
}
pub trait SizedSparseValuedMatrix: SizedSparseMatrix + SparseValuedMatrix {
fn select_value(&self, sparse_index: Self::SparseIndex) -> Self::Value;
}
impl<M: SizedSparseValuedMatrix> SizedSparseValuedMatrix for &M {
#[inline]
fn select_value(&self, sparse_index: Self::SparseIndex) -> Self::Value {
(*self).select_value(sparse_index)
}
}
pub trait SparseValuedMatrixRef: SparseValuedMatrix {
type SparseValuesRef<'a>: Iterator<Item = &'a Self::Value>
+ DoubleEndedIterator<Item = &'a Self::Value>
where
Self: 'a,
Self::Value: 'a;
fn sparse_values_ref(&self) -> Self::SparseValuesRef<'_>;
#[inline]
fn sparse_entries(&self) -> impl Iterator<Item = (Self::Coordinates, &Self::Value)> {
self.sparse_coordinates().zip(self.sparse_values_ref())
}
}
impl<M: SparseValuedMatrixRef> SparseValuedMatrixRef for &M {
type SparseValuesRef<'a>
= M::SparseValuesRef<'a>
where
Self: 'a,
M::Value: 'a;
#[inline]
fn sparse_values_ref(&self) -> Self::SparseValuesRef<'_> {
(*self).sparse_values_ref()
}
}
pub trait SizedSparseValuedMatrixRef: SizedSparseValuedMatrix + SparseValuedMatrixRef {
fn select_value_ref(&self, sparse_index: Self::SparseIndex) -> &Self::Value;
#[inline]
fn try_select_value(&self, sparse_index: Self::SparseIndex) -> Option<&Self::Value> {
if sparse_index < self.number_of_defined_values() {
Some(self.select_value_ref(sparse_index))
} else {
None
}
}
}
impl<M: SizedSparseValuedMatrixRef> SizedSparseValuedMatrixRef for &M {
#[inline]
fn select_value_ref(&self, sparse_index: Self::SparseIndex) -> &Self::Value {
(*self).select_value_ref(sparse_index)
}
}
pub trait SparseValuedMatrixMut: SparseValuedMatrixRef {
type SparseValuesMut<'a>: Iterator<Item = &'a mut Self::Value>
+ DoubleEndedIterator<Item = &'a mut Self::Value>
where
Self: 'a,
Self::Value: 'a;
fn sparse_values_mut(&mut self) -> Self::SparseValuesMut<'_>;
fn sparse_entries_mut(&mut self)
-> impl Iterator<Item = (Self::Coordinates, &mut Self::Value)>;
}
pub trait SizedSparseValuedMatrixMut: SizedSparseValuedMatrixRef + SparseValuedMatrixMut {
fn select_value_mut(&mut self, sparse_index: Self::SparseIndex) -> &mut Self::Value;
#[inline]
fn try_select_value_mut(
&mut self,
sparse_index: Self::SparseIndex,
) -> Option<&mut Self::Value> {
if sparse_index < self.number_of_defined_values() {
Some(self.select_value_mut(sparse_index))
} else {
None
}
}
#[inline]
fn update_value_at(
&mut self,
sparse_index: Self::SparseIndex,
f: impl FnOnce(&mut Self::Value),
) {
f(self.select_value_mut(sparse_index));
}
}
pub trait ImplicitValuedSparseMatrix: SparseValuedMatrix + ImplicitValuedMatrix {
type SparseImplicitValues<'a>: Iterator<Item = Self::Value>
+ DoubleEndedIterator<Item = Self::Value>
where
Self: 'a;
fn sparse_implicit_values(&self) -> Self::SparseImplicitValues<'_>;
}
impl<M> ImplicitValuedSparseMatrix for M
where
M: SparseValuedMatrix + ImplicitValuedMatrix,
{
type SparseImplicitValues<'a>
= ImplicitValuedSparseIterator<'a, M>
where
M: 'a;
#[inline]
fn sparse_implicit_values(&self) -> Self::SparseImplicitValues<'_> {
self.into()
}
}