use std::mem::size_of;
#[derive(Debug)]
pub struct CooMat<T> {
pub(crate) rows: usize,
pub(crate) cols: usize,
pub(crate) entries: Vec<(usize, usize, T)>,
}
impl<T> CooMat<T> {
pub fn new(rows: usize, cols: usize) -> Self {
assert!(size_of::<T>() != 0);
assert!(rows > 0);
assert!(cols > 0);
Self {
rows,
cols,
entries: Vec::new(),
}
}
pub fn with_capacity(rows: usize, cols: usize, capacity: usize) -> Self {
assert!(size_of::<T>() != 0);
assert!(rows > 0);
assert!(cols > 0);
Self {
rows,
cols,
entries: Vec::with_capacity(capacity),
}
}
pub fn with_entries(
rows: usize,
cols: usize,
entries: impl IntoIterator<Item = (usize, usize, T)>,
) -> Self {
assert!(size_of::<T>() != 0);
assert!(rows > 0);
assert!(cols > 0);
let entries: Vec<_> = entries.into_iter().collect();
for (row, col, _) in entries.iter() {
assert!(*row < rows);
assert!(*col < cols);
}
Self {
rows,
cols,
entries,
}
}
pub fn with_capacity_and_entries(
rows: usize,
cols: usize,
capacity: usize,
entries: impl IntoIterator<Item = (usize, usize, T)>,
) -> Self {
assert!(size_of::<T>() != 0);
assert!(rows > 0);
assert!(cols > 0);
let iter = entries.into_iter();
let mut entries = Vec::with_capacity(capacity);
for entry @ (row, col, _) in iter {
assert!(row < rows);
assert!(col < cols);
entries.push(entry);
}
Self {
rows,
cols,
entries,
}
}
pub fn with_triplets(
rows: usize,
cols: usize,
rowind: impl IntoIterator<Item = usize>,
colind: impl IntoIterator<Item = usize>,
values: impl IntoIterator<Item = T>,
) -> Self {
assert!(size_of::<T>() != 0);
assert!(rows > 0);
assert!(cols > 0);
let mut rowind = rowind.into_iter();
let mut colind = colind.into_iter();
let values = values.into_iter();
let capacity = match values.size_hint() {
(_, Some(high)) => high,
(low, None) => low,
};
let mut entries = Vec::with_capacity(capacity);
for value in values {
let row = rowind.next().unwrap();
let col = colind.next().unwrap();
assert!(row < rows);
assert!(col < cols);
entries.push((row, col, value));
}
assert!(rowind.next().is_none());
assert!(colind.next().is_none());
entries.shrink_to_fit();
CooMat {
rows,
cols,
entries,
}
}
pub fn with_capacity_and_triplets(
rows: usize,
cols: usize,
capacity: usize,
rowind: impl IntoIterator<Item = usize>,
colind: impl IntoIterator<Item = usize>,
values: impl IntoIterator<Item = T>,
) -> Self {
assert!(size_of::<T>() != 0);
assert!(rows > 0);
assert!(cols > 0);
let mut rowind = rowind.into_iter();
let mut colind = colind.into_iter();
let values = values.into_iter();
let mut entries = Vec::with_capacity(capacity);
for value in values {
let row = rowind.next().expect("invalid matrix");
let col = colind.next().expect("invalid matrix");
assert!(row < rows);
assert!(col < cols);
entries.push((row, col, value));
}
assert!(rowind.next().is_none());
assert!(colind.next().is_none());
CooMat {
rows,
cols,
entries,
}
}
pub fn rows(&self) -> usize {
self.rows
}
pub fn cols(&self) -> usize {
self.cols
}
pub fn shape(&self) -> (usize, usize) {
(self.rows, self.cols)
}
pub fn len(&self) -> usize {
self.entries.len()
}
pub fn is_empty(&self) -> bool {
self.entries.is_empty()
}
pub fn capacity(&self) -> usize {
self.entries.capacity()
}
pub fn reserve(&mut self, additional: usize) {
self.entries.reserve(additional)
}
pub fn shrink(&mut self) {
self.entries.shrink_to_fit()
}
pub fn truncate(&mut self, len: usize) {
assert!(len <= self.len());
self.entries.truncate(len)
}
pub fn clear(&mut self) {
self.entries.clear()
}
pub fn get(&self, index: usize) -> Option<(&usize, &usize, &T)> {
self.entries.get(index).map(|(r, c, v)| (r, c, v))
}
pub fn get_mut(&mut self, index: usize) -> Option<(&usize, &usize, &mut T)> {
self.entries.get_mut(index).map(|(r, c, v)| (&*r, &*c, v))
}
pub fn push(&mut self, row: usize, col: usize, val: T) {
assert!(row < self.rows);
assert!(col < self.cols);
self.entries.push((row, col, val))
}
pub fn pop(&mut self) -> Option<(usize, usize, T)> {
self.entries.pop()
}
pub fn insert(&mut self, index: usize, row: usize, col: usize, val: T) {
assert!(row < self.rows);
assert!(col < self.cols);
assert!(index <= self.len());
self.entries.insert(index, (row, col, val))
}
pub fn extend<I: IntoIterator<Item = (usize, usize, T)>>(&mut self, iter: I) {
for (row, col, val) in iter {
assert!(row < self.rows);
assert!(col < self.cols);
self.entries.push((row, col, val));
}
}
pub fn remove(&mut self, index: usize) -> (usize, usize, T) {
self.entries.remove(index)
}
pub fn iter(&self) -> Iter<T> {
Iter {
inner: self.entries.iter(),
}
}
pub fn iter_mut(&mut self) -> IterMut<T> {
IterMut {
inner: self.entries.iter_mut(),
}
}
}
impl<T> IntoIterator for CooMat<T> {
type Item = (usize, usize, T);
type IntoIter = IntoIter<T>;
fn into_iter(self) -> Self::IntoIter {
IntoIter {
inner: self.entries.into_iter(),
}
}
}
#[derive(Clone, Debug)]
pub struct Iter<'iter, T: 'iter> {
inner: std::slice::Iter<'iter, (usize, usize, T)>,
}
impl<'iter, T: 'iter> Iterator for Iter<'iter, T> {
type Item = (&'iter usize, &'iter usize, &'iter T);
fn next(&mut self) -> Option<Self::Item> {
self.inner.next().map(|(r, c, v)| (r, c, v))
}
}
impl<T> DoubleEndedIterator for Iter<'_, T> {
fn next_back(&mut self) -> Option<Self::Item> {
self.inner.next_back().map(|(r, c, v)| (r, c, v))
}
}
impl<T> ExactSizeIterator for Iter<'_, T> {}
#[derive(Debug)]
pub struct IterMut<'iter, T: 'iter> {
inner: std::slice::IterMut<'iter, (usize, usize, T)>,
}
impl<'iter, T: 'iter> Iterator for IterMut<'iter, T> {
type Item = (&'iter usize, &'iter usize, &'iter mut T);
fn next(&mut self) -> Option<Self::Item> {
self.inner.next().map(|(r, c, v)| (&*r, &*c, v))
}
}
impl<T> DoubleEndedIterator for IterMut<'_, T> {
fn next_back(&mut self) -> Option<Self::Item> {
self.inner.next_back().map(|(r, c, v)| (&*r, &*c, v))
}
}
impl<T> ExactSizeIterator for IterMut<'_, T> {}
#[derive(Debug)]
pub struct IntoIter<T> {
inner: std::vec::IntoIter<(usize, usize, T)>,
}
impl<T> Iterator for IntoIter<T> {
type Item = (usize, usize, T);
fn next(&mut self) -> Option<Self::Item> {
self.inner.next()
}
}
impl<T> DoubleEndedIterator for IntoIter<T> {
fn next_back(&mut self) -> Option<Self::Item> {
self.inner.next_back()
}
}
#[cfg(test)]
mod tests {
use std::vec;
use super::*;
#[test]
#[should_panic]
fn new_zero_size() {
CooMat::<f64>::new(0, 0);
}
#[test]
#[should_panic]
fn new_zero_size_type() {
CooMat::<()>::new(1, 1);
}
#[test]
fn new_annotation() {
let _: CooMat<f64> = CooMat::new(1, 2);
}
#[test]
fn new_fish() {
CooMat::<f64>::new(2, 1);
}
#[test]
fn new_shape() {
let matrix = CooMat::<f64>::new(1, 2);
assert_eq!(matrix.shape(), (1, 2));
}
#[test]
fn new_length() {
let matrix = CooMat::<f64>::new(1, 1);
assert_eq!(matrix.entries.len(), 0)
}
#[test]
fn new_capacity() {
let matrix = CooMat::<f64>::new(1, 1);
assert_eq!(matrix.entries.capacity(), 0);
}
#[test]
#[should_panic]
fn with_capacity_zero_size() {
CooMat::<f64>::new(0, 0);
}
#[test]
#[should_panic]
fn with_capacity_zero_size_type() {
CooMat::<()>::new(1, 1);
}
#[test]
fn with_capacity_annotation() {
let _: CooMat<f64> = CooMat::with_capacity(1, 2, 3);
}
#[test]
fn with_capacity_fish() {
CooMat::<f64>::with_capacity(2, 1, 3);
}
#[test]
fn with_capacity_shape() {
let matrix = CooMat::<f64>::with_capacity(1, 2, 3);
assert_eq!(matrix.shape(), (1, 2));
}
#[test]
fn with_capacity_length() {
let matrix = CooMat::<f64>::with_capacity(1, 1, 1);
assert_eq!(matrix.entries.len(), 0)
}
#[test]
fn with_capacity_capacity() {
let matrix = CooMat::<f64>::with_capacity(1, 1, 1);
assert_eq!(matrix.entries.capacity(), 1);
}
#[test]
#[should_panic]
fn with_entries_zero_size() {
CooMat::<f64>::with_entries(0, 0, vec![]);
}
#[test]
#[should_panic]
fn with_entries_zero_size_type() {
CooMat::<()>::with_entries(1, 1, vec![]);
}
#[test]
fn with_entries() {
let entries = vec![(0, 0, 1.0)];
let matrix = CooMat::with_entries(1, 1, entries);
assert_eq!(matrix.get(0), Some((&0, &0, &1.0)));
assert_eq!(matrix.get(1), None);
}
#[test]
fn with_entries_order() {
let entries = vec![(0, 0, 1.0), (0, 1, 2.0), (1, 0, 3.0), (1, 1, 4.0)];
let matrix = CooMat::with_entries(2, 2, entries);
let mut iter = matrix.iter();
assert_eq!(iter.next(), Some((&0, &0, &1.0)));
assert_eq!(iter.next(), Some((&0, &1, &2.0)));
assert_eq!(iter.next(), Some((&1, &0, &3.0)));
assert_eq!(iter.next(), Some((&1, &1, &4.0)));
assert_eq!(iter.next(), None);
}
#[test]
fn with_entries_length() {
let entries = vec![(0, 0, 1.0)];
let matrix = CooMat::with_entries(1, 1, entries);
assert_eq!(matrix.entries.len(), 1)
}
#[test]
fn with_entries_capacity() {
let entries = vec![(0, 0, 1.0)];
let matrix = CooMat::with_entries(1, 1, entries);
assert_eq!(matrix.entries.capacity(), 1)
}
#[test]
#[should_panic]
fn with_entries_invalid_row() {
let entries = vec![(1, 0, 1.0)];
CooMat::with_entries(1, 1, entries);
}
#[test]
#[should_panic]
fn with_entries_invalid_col() {
let entries = vec![(0, 1, 1.0)];
CooMat::with_entries(1, 1, entries);
}
#[test]
#[should_panic]
fn with_capacity_and_entries_zero_size() {
let entries = vec![(0, 0, 1.0)];
CooMat::with_capacity_and_entries(0, 0, 1, entries);
}
#[test]
#[should_panic]
fn with_capacity_and_entries_zero_size_type() {
let entries = vec![(0, 0, ())];
CooMat::with_capacity_and_entries(1, 1, 1, entries);
}
#[test]
fn with_capacity_and_entries() {
let entries = vec![(0, 0, 1.0)];
let matrix = CooMat::with_capacity_and_entries(1, 1, 1, entries);
assert_eq!(matrix.get(0), Some((&0, &0, &1.0)));
assert_eq!(matrix.get(1), None);
}
#[test]
fn with_capacity_and_entries_order() {
let entries = vec![(0, 0, 1.0), (0, 1, 2.0), (1, 0, 3.0), (1, 1, 4.0)];
let matrix = CooMat::with_capacity_and_entries(2, 2, 4, entries);
let mut iter = matrix.iter();
assert_eq!(iter.next(), Some((&0, &0, &1.0)));
assert_eq!(iter.next(), Some((&0, &1, &2.0)));
assert_eq!(iter.next(), Some((&1, &0, &3.0)));
assert_eq!(iter.next(), Some((&1, &1, &4.0)));
assert_eq!(iter.next(), None);
}
#[test]
fn with_capacity_and_entries_length() {
let entries = vec![(0, 0, 1.0)];
let matrix = CooMat::with_capacity_and_entries(1, 1, 1, entries);
assert_eq!(matrix.entries.len(), 1)
}
#[test]
fn with_capacity_and_entries_capacity() {
let entries = vec![(0, 0, 1.0)];
let matrix = CooMat::with_capacity_and_entries(1, 1, 1, entries);
assert_eq!(matrix.entries.capacity(), 1)
}
#[test]
#[should_panic]
fn with_capacity_and_entries_invalid_row() {
let entries = vec![(1, 0, 1.0)];
CooMat::with_capacity_and_entries(1, 1, 1, entries);
}
#[test]
#[should_panic]
fn with_capacity_and_entries_invalid_col() {
let entries = vec![(0, 1, 1.0)];
CooMat::with_capacity_and_entries(1, 1, 1, entries);
}
#[test]
#[should_panic]
fn with_triplets_zero_size() {
let rowind = vec![0];
let colind = vec![0];
let values = vec![1.0];
CooMat::<f64>::with_triplets(0, 0, rowind, colind, values);
}
#[test]
#[should_panic]
fn with_triplets_zero_size_type() {
let rowind = vec![0];
let colind = vec![0];
let values = vec![()];
CooMat::<()>::with_triplets(1, 1, rowind, colind, values);
}
#[test]
fn with_triplets() {
let rowind = vec![0];
let colind = vec![0];
let values = vec![1.0];
let matrix = CooMat::with_triplets(1, 1, rowind, colind, values);
assert_eq!(matrix.get(0), Some((&0, &0, &1.0)));
assert_eq!(matrix.get(1), None);
}
#[test]
fn with_triplets_order() {
let rowind = vec![0, 0, 1, 1];
let colind = vec![0, 1, 0, 1];
let values = vec![1.0, 2.0, 3.0, 4.0];
let matrix = CooMat::with_triplets(2, 2, rowind, colind, values);
let mut iter = matrix.iter();
assert_eq!(iter.next(), Some((&0, &0, &1.0)));
assert_eq!(iter.next(), Some((&0, &1, &2.0)));
assert_eq!(iter.next(), Some((&1, &0, &3.0)));
assert_eq!(iter.next(), Some((&1, &1, &4.0)));
assert_eq!(iter.next(), None);
}
#[test]
fn with_triplets_length() {
let rowind = vec![0];
let colind = vec![0];
let values = vec![1.0];
let matrix = CooMat::with_triplets(1, 1, rowind, colind, values);
assert_eq!(matrix.entries.len(), 1);
}
#[test]
fn with_triplets_capacity() {
let rowind = vec![0];
let colind = vec![0];
let values = vec![1.0];
let matrix = CooMat::with_triplets(1, 1, rowind, colind, values);
assert_eq!(matrix.entries.capacity(), 1);
}
#[test]
#[should_panic]
fn with_triplets_invalid_row() {
let rowind = vec![1];
let colind = vec![0];
let values = vec![1.0];
CooMat::with_triplets(1, 1, rowind, colind, values);
}
#[test]
#[should_panic]
fn with_triplets_invalid_col() {
let rowind = vec![0];
let colind = vec![1];
let values = vec![1.0];
CooMat::with_triplets(1, 1, rowind, colind, values);
}
#[test]
#[should_panic]
fn with_triplets_invalid_length() {
let rowind = vec![0; 2];
let colind = vec![1; 1];
let values = vec![1.0; 3];
CooMat::with_triplets(1, 1, rowind, colind, values);
}
#[test]
#[should_panic]
fn with_capacity_and_triplets_zero_size() {
let rowind = vec![0];
let colind = vec![0];
let values = vec![1.0];
CooMat::with_capacity_and_triplets(0, 0, 1, rowind, colind, values);
}
#[test]
#[should_panic]
fn with_capacity_and_triplets_zero_size_type() {
let rowind = vec![0];
let colind = vec![0];
let values = vec![()];
CooMat::with_capacity_and_triplets(1, 1, 1, rowind, colind, values);
}
#[test]
fn with_capacity_and_triplets() {
let rowind = vec![0];
let colind = vec![0];
let values = vec![1.0];
let matrix = CooMat::with_capacity_and_triplets(1, 1, 1, rowind, colind, values);
assert_eq!(matrix.get(0), Some((&0, &0, &1.0)));
assert_eq!(matrix.get(1), None);
}
#[test]
fn with_capacity_and_triplets_order() {
let rowind = vec![0, 0, 1, 1];
let colind = vec![0, 1, 0, 1];
let values = vec![1.0, 2.0, 3.0, 4.0];
let matrix = CooMat::with_capacity_and_triplets(2, 2, 4, rowind, colind, values);
let mut iter = matrix.iter();
assert_eq!(iter.next(), Some((&0, &0, &1.0)));
assert_eq!(iter.next(), Some((&0, &1, &2.0)));
assert_eq!(iter.next(), Some((&1, &0, &3.0)));
assert_eq!(iter.next(), Some((&1, &1, &4.0)));
assert_eq!(iter.next(), None);
}
#[test]
fn with_capacity_and_triplets_length() {
let rowind = vec![0];
let colind = vec![0];
let values = vec![1.0];
let matrix = CooMat::with_capacity_and_triplets(1, 1, 1, rowind, colind, values);
assert_eq!(matrix.entries.len(), 1);
}
#[test]
fn with_capacity_and_triplets_capacity() {
let rowind = vec![0];
let colind = vec![0];
let values = vec![1.0];
let matrix = CooMat::with_capacity_and_triplets(1, 1, 1, rowind, colind, values);
assert_eq!(matrix.entries.capacity(), 1);
}
#[test]
#[should_panic]
fn with_capacity_and_triplets_invalid_row() {
let rowind = vec![1];
let colind = vec![0];
let values = vec![1.0];
CooMat::with_capacity_and_triplets(1, 1, 1, rowind, colind, values);
}
#[test]
#[should_panic]
fn with_capacity_and_triplets_invalid_col() {
let rowind = vec![0];
let colind = vec![1];
let values = vec![1.0];
CooMat::with_capacity_and_triplets(1, 1, 1, rowind, colind, values);
}
#[test]
#[should_panic]
fn with_capacity_and_triplets_invalid_length() {
let rowind = vec![0; 2];
let colind = vec![1; 1];
let values = vec![1.0; 3];
CooMat::with_capacity_and_triplets(1, 1, 1, rowind, colind, values);
}
#[test]
fn rows() {
let matrix: CooMat<f64> = CooMat::new(1, 1);
assert_eq!(matrix.rows(), 1);
let matrix: CooMat<f64> = CooMat::new(123, 1);
assert_eq!(matrix.rows(), 123);
}
#[test]
fn cols() {
let matrix: CooMat<f64> = CooMat::new(1, 1);
assert_eq!(matrix.cols(), 1);
let matrix: CooMat<f64> = CooMat::new(1, 123);
assert_eq!(matrix.cols(), 123);
}
#[test]
fn shape() {
let matrix: CooMat<f64> = CooMat::new(1, 1);
assert_eq!(matrix.shape(), (1, 1));
let matrix: CooMat<f64> = CooMat::new(123, 123);
assert_eq!(matrix.shape(), (123, 123));
}
#[test]
fn capacity_new() {
let matrix: CooMat<f64> = CooMat::new(1, 1);
assert_eq!(matrix.capacity(), 0);
}
#[test]
fn capacity_with_capacity() {
let matrix: CooMat<f64> = CooMat::with_capacity(1, 1, 0);
assert_eq!(matrix.capacity(), 0);
let matrix: CooMat<f64> = CooMat::with_capacity(1, 1, 1);
assert_eq!(matrix.capacity(), 1);
let matrix: CooMat<f64> = CooMat::with_capacity(1, 1, 123);
assert_eq!(matrix.capacity(), 123);
}
#[test]
fn capacity_with_entries() {
let entries = vec![];
let matrix: CooMat<f64> = CooMat::with_entries(1, 1, entries);
assert_eq!(matrix.capacity(), 0);
let entries = vec![(0, 0, 1.0)];
let matrix = CooMat::with_entries(1, 1, entries);
assert_eq!(matrix.capacity(), 1);
}
#[test]
fn capacity_with_capacity_and_entries() {
let entries = vec![];
let matrix: CooMat<f64> = CooMat::with_capacity_and_entries(1, 1, 1, entries);
assert_eq!(matrix.capacity(), 1);
}
#[test]
fn capacity_with_triplets() {
let rowind = vec![];
let colind = vec![];
let values: Vec<f64> = vec![];
let matrix = CooMat::with_triplets(1, 1, rowind, colind, values);
assert_eq!(matrix.capacity(), 0);
let rowind = vec![0];
let colind = vec![0];
let values = vec![1.0];
let matrix = CooMat::with_triplets(1, 1, rowind, colind, values);
assert_eq!(matrix.capacity(), 1);
}
#[test]
fn capacity_with_capacity_and_triplets() {
let rowind = vec![];
let colind = vec![];
let values: Vec<f64> = vec![];
let matrix = CooMat::with_capacity_and_triplets(1, 1, 1, rowind, colind, values);
assert_eq!(matrix.capacity(), 1);
}
#[test]
fn reserve() {
let mut matrix: CooMat<f64> = CooMat {
rows: 1,
cols: 1,
entries: Vec::new(),
};
assert_eq!(matrix.capacity(), 0);
matrix.reserve(10);
assert!(matrix.entries.capacity() >= 10);
}
#[test]
fn shrink() {
let mut matrix: CooMat<f64> = CooMat {
rows: 1,
cols: 1,
entries: Vec::with_capacity(10),
};
assert_eq!(matrix.capacity(), 10);
matrix.shrink();
assert_eq!(matrix.capacity(), 0);
}
#[test]
fn length_new() {
let matrix: CooMat<f64> = CooMat::new(1, 1);
assert_eq!(matrix.len(), 0);
}
#[test]
fn length_with_capacity() {
let matrix: CooMat<f64> = CooMat::with_capacity(1, 1, 1);
assert_eq!(matrix.len(), 0);
}
#[test]
fn length_with_entries() {
let entries = vec![];
let matrix: CooMat<f64> = CooMat::with_entries(1, 1, entries);
assert_eq!(matrix.len(), 0);
let entries = vec![(0, 0, 1.0)];
let matrix = CooMat::with_entries(1, 1, entries);
assert_eq!(matrix.len(), 1);
}
#[test]
fn length_with_capcity_and_entries() {
let entries = vec![];
let matrix: CooMat<f64> = CooMat::with_capacity_and_entries(1, 1, 1, entries);
assert_eq!(matrix.len(), 0);
}
#[test]
fn length_with_triplets() {
let rowind = vec![];
let colind = vec![];
let values: Vec<f64> = vec![];
let matrix = CooMat::with_triplets(1, 1, rowind, colind, values);
assert_eq!(matrix.len(), 0);
let rowind = vec![0];
let colind = vec![0];
let values = vec![1.0];
let matrix = CooMat::with_triplets(1, 1, rowind, colind, values);
assert_eq!(matrix.len(), 1);
}
#[test]
fn length_with_capacity_and_triplets() {
let rowind = vec![];
let colind = vec![];
let values: Vec<f64> = vec![];
let matrix = CooMat::with_capacity_and_triplets(1, 1, 1, rowind, colind, values);
assert_eq!(matrix.len(), 0);
}
#[test]
fn is_empty() {
let mut matrix: CooMat<f64> = CooMat {
rows: 2,
cols: 2,
entries: Vec::new(),
};
assert!(matrix.is_empty());
matrix.push(0, 0, 1.0);
assert!(!matrix.is_empty());
}
#[test]
fn truncate() {
let mut matrix: CooMat<f64> = CooMat {
rows: 2,
cols: 2,
entries: vec![(0, 0, 1.0), (0, 1, 2.0), (1, 0, 3.0), (1, 1, 4.0)],
};
assert_eq!(matrix.len(), 4);
matrix.truncate(2);
assert_eq!(matrix.len(), 2);
}
#[test]
fn truncate_clear() {
let mut matrix: CooMat<f64> = CooMat {
rows: 2,
cols: 2,
entries: vec![(0, 0, 1.0), (0, 1, 2.0), (1, 0, 3.0), (1, 1, 4.0)],
};
assert_eq!(matrix.len(), 4);
matrix.truncate(0);
assert!(matrix.is_empty());
}
#[test]
fn truncate_noop() {
let mut matrix: CooMat<f64> = CooMat {
rows: 2,
cols: 2,
entries: vec![(0, 0, 1.0), (0, 1, 2.0), (1, 0, 3.0), (1, 1, 4.0)],
};
assert_eq!(matrix.len(), 4);
matrix.truncate(4);
assert_eq!(matrix.len(), 4);
}
#[test]
#[should_panic]
fn truncate_outofbounds() {
let mut matrix: CooMat<f64> = CooMat {
rows: 2,
cols: 2,
entries: vec![(0, 0, 1.0), (0, 1, 2.0), (1, 0, 3.0), (1, 1, 4.0)],
};
matrix.truncate(5);
}
#[test]
fn get() {
let matrix: CooMat<f64> = CooMat {
rows: 1,
cols: 1,
entries: vec![(0, 0, 1.0)],
};
assert_eq!(matrix.get(0), Some((&0, &0, &1.0)));
assert_eq!(matrix.get(1), None);
}
#[test]
fn get_mut() {
let mut matrix: CooMat<f64> = CooMat {
rows: 1,
cols: 1,
entries: vec![(0, 0, 1.0)],
};
assert_eq!(matrix.get_mut(0), Some((&0, &0, &mut 1.0)));
assert_eq!(matrix.get_mut(1), None);
}
#[test]
fn insert() {
let mut matrix: CooMat<f64> = CooMat {
rows: 2,
cols: 2,
entries: vec![(0, 0, 1.0), (1, 1, 4.0)],
};
matrix.insert(1, 0, 1, 2.0);
matrix.insert(2, 1, 0, 3.0);
assert_eq!(matrix.entries.len(), 4);
assert_eq!(matrix.entries.get(0), Some(&(0, 0, 1.0)));
assert_eq!(matrix.entries.get(1), Some(&(0, 1, 2.0)));
assert_eq!(matrix.entries.get(2), Some(&(1, 0, 3.0)));
assert_eq!(matrix.entries.get(3), Some(&(1, 1, 4.0)));
}
#[test]
#[should_panic]
fn insert_invalid_row() {
let mut matrix = CooMat::new(1, 1);
matrix.insert(0, 1, 0, 1.0);
}
#[test]
#[should_panic]
fn insert_invalid_col() {
let mut matrix = CooMat::new(1, 1);
matrix.insert(0, 0, 1, 1.0);
}
#[test]
#[should_panic]
fn insert_outofbounds() {
let mut matrix = CooMat::new(1, 1);
matrix.insert(1, 0, 0, 1.0);
}
#[test]
fn extend() {
let mut matrix = CooMat::new(2, 2);
assert!(matrix.entries.is_empty());
matrix.extend(vec![(0, 0, 1.0), (0, 1, 2.0), (1, 0, 3.0), (1, 1, 4.0)]);
assert_eq!(matrix.entries.len(), 4);
assert_eq!(matrix.entries.get(0), Some(&(0, 0, 1.0)));
assert_eq!(matrix.entries.get(1), Some(&(0, 1, 2.0)));
assert_eq!(matrix.entries.get(2), Some(&(1, 0, 3.0)));
assert_eq!(matrix.entries.get(3), Some(&(1, 1, 4.0)));
}
#[test]
#[should_panic]
fn extend_invalid_row() {
let mut matrix = CooMat::new(1, 1);
matrix.extend(vec![(1, 0, 1.0)]);
}
#[test]
#[should_panic]
fn extend_invalid_col() {
let mut matrix = CooMat::new(1, 1);
matrix.extend(vec![(0, 1, 1.0)]);
}
#[test]
fn remove() {
let mut matrix: CooMat<f64> = CooMat {
rows: 1,
cols: 1,
entries: vec![(0, 0, 1.0)],
};
assert_eq!(matrix.entries.len(), 1);
assert_eq!(matrix.remove(0), (0, 0, 1.0));
assert!(matrix.entries.is_empty());
}
#[test]
#[should_panic]
fn remove_outofbounds() {
let mut matrix: CooMat<f64> = CooMat::new(1, 1);
matrix.remove(0);
}
#[test]
fn push() {
let mut matrix = CooMat::new(1, 1);
matrix.push(0, 0, 1.0);
assert_eq!(matrix.entries.len(), 1);
assert_eq!(matrix.entries.get(0), Some(&(0, 0, 1.0)));
}
#[test]
#[should_panic]
fn push_invalid_row() {
let mut matrix = CooMat::new(1, 1);
matrix.push(1, 0, 1.0);
}
#[test]
#[should_panic]
fn push_invalid_col() {
let mut matrix = CooMat::new(1, 1);
matrix.push(0, 1, 1.0);
}
#[test]
fn pop() {
let mut matrix: CooMat<f64> = CooMat {
rows: 1,
cols: 1,
entries: vec![(0, 0, 1.0)],
};
assert_eq!(matrix.pop(), Some((0, 0, 1.0)));
assert!(matrix.entries.is_empty())
}
#[test]
fn clear() {
let mut matrix: CooMat<f64> = CooMat {
rows: 1,
cols: 1,
entries: vec![(0, 0, 1.0)],
};
matrix.clear();
assert!(matrix.entries.is_empty())
}
#[test]
fn iter() {
let matrix: CooMat<f64> = CooMat {
rows: 2,
cols: 2,
entries: vec![(0, 0, 1.0), (0, 1, 2.0), (1, 0, 3.0), (1, 1, 4.0)],
};
let mut iter = matrix.iter();
assert_eq!(iter.next(), Some((&0, &0, &1.0)));
assert_eq!(iter.next(), Some((&0, &1, &2.0)));
assert_eq!(iter.next(), Some((&1, &0, &3.0)));
assert_eq!(iter.next(), Some((&1, &1, &4.0)));
assert!(iter.next().is_none());
}
#[test]
fn iter_mut() {
let mut matrix: CooMat<f64> = CooMat {
rows: 2,
cols: 2,
entries: vec![(0, 0, 1.0), (0, 1, 2.0), (1, 0, 3.0), (1, 1, 4.0)],
};
let mut iter = matrix.iter_mut();
assert_eq!(iter.next(), Some((&0, &0, &mut 1.0)));
assert_eq!(iter.next(), Some((&0, &1, &mut 2.0)));
assert_eq!(iter.next(), Some((&1, &0, &mut 3.0)));
assert_eq!(iter.next(), Some((&1, &1, &mut 4.0)));
assert!(iter.next().is_none());
}
#[test]
fn into_iter() {
let matrix: CooMat<f64> = CooMat {
rows: 2,
cols: 2,
entries: vec![(0, 0, 1.0), (0, 1, 2.0), (1, 0, 3.0), (1, 1, 4.0)],
};
let mut iter = matrix.into_iter();
assert_eq!(iter.next(), Some((0, 0, 1.0)));
assert_eq!(iter.next(), Some((0, 1, 2.0)));
assert_eq!(iter.next(), Some((1, 0, 3.0)));
assert_eq!(iter.next(), Some((1, 1, 4.0)));
assert!(iter.next().is_none());
}
}