use alloc::vec::Vec;
use num_traits::Zero;
use super::MutabilityError;
use crate::traits::SquareMatrix;
mod matrix;
mod sparse_matrix;
#[cfg_attr(feature = "mem_size", derive(mem_dbg::MemSize))]
#[cfg_attr(feature = "mem_size", mem_size(rec))]
#[cfg_attr(feature = "mem_dbg", derive(mem_dbg::MemDbg))]
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub struct SubsetSquareMatrix<M: SquareMatrix, I> {
matrix: M,
indices: I,
}
impl<M: SquareMatrix + Default, I> Default for SubsetSquareMatrix<M, I>
where
I: Default,
{
#[inline]
fn default() -> Self {
Self { matrix: M::default(), indices: I::default() }
}
}
impl<M: SquareMatrix, I> SubsetSquareMatrix<M, I> {
#[inline]
pub fn with_unsorted_indices(
matrix: M,
unsorted_indices: I,
) -> Result<SubsetSquareMatrix<M, Vec<M::Index>>, MutabilityError<M>>
where
I: Iterator<Item = M::Index> + ExactSizeIterator,
{
let mut sorted_indices: Vec<M::Index> = vec![M::Index::zero(); unsorted_indices.len()];
for (unsorted_index, sorted_index) in unsorted_indices.zip(sorted_indices.iter_mut()) {
if unsorted_index >= matrix.order() {
return Err(MutabilityError::OutOfBounds(
(unsorted_index, unsorted_index),
(matrix.order(), matrix.order()),
"The provided index is larger than the number of rows/columns of the matrix.",
));
}
*sorted_index = unsorted_index;
}
sorted_indices.sort_unstable();
Ok(SubsetSquareMatrix { matrix, indices: sorted_indices })
}
#[inline]
pub fn with_sorted_indices(matrix: M, sorted_indices: I) -> SubsetSquareMatrix<M, I>
where
I: AsRef<[M::Index]>,
{
debug_assert!(
sorted_indices.as_ref().is_sorted(),
"The indices are not sorted. This is a bug in the code."
);
debug_assert!(
sorted_indices.as_ref().iter().all(|&index| index < matrix.order()),
"The indices are out of bounds. This is a bug in the code."
);
SubsetSquareMatrix { matrix, indices: sorted_indices }
}
}