use nalgebra_sparse::pattern::{SparsityPattern, SparsityPatternFormatError}; #[test] fn sparsity_pattern_valid_data() { // Construct pattern from valid data and check that selected methods return results // that agree with expectations. { // A pattern with zero explicitly stored entries let pattern = SparsityPattern::try_from_offsets_and_indices(3, 2, vec![0, 0, 0, 0], Vec::new()) .unwrap(); assert_eq!(pattern.major_dim(), 3); assert_eq!(pattern.minor_dim(), 2); assert_eq!(pattern.nnz(), 0); assert_eq!(pattern.major_offsets(), &[0, 0, 0, 0]); assert_eq!(pattern.minor_indices(), &[]); assert_eq!(pattern.lane(0), &[]); assert_eq!(pattern.lane(1), &[]); assert_eq!(pattern.lane(2), &[]); assert!(pattern.entries().next().is_none()); assert_eq!(pattern, SparsityPattern::zeros(3, 2)); let (offsets, indices) = pattern.disassemble(); assert_eq!(offsets, vec![0, 0, 0, 0]); assert_eq!(indices, vec![]); } { // Arbitrary pattern let offsets = vec![0, 2, 2, 5]; let indices = vec![0, 5, 1, 2, 3]; let pattern = SparsityPattern::try_from_offsets_and_indices(3, 6, offsets.clone(), indices.clone()) .unwrap(); assert_eq!(pattern.major_dim(), 3); assert_eq!(pattern.minor_dim(), 6); assert_eq!(pattern.major_offsets(), offsets.as_slice()); assert_eq!(pattern.minor_indices(), indices.as_slice()); assert_eq!(pattern.nnz(), 5); assert_eq!(pattern.lane(0), &[0, 5]); assert_eq!(pattern.lane(1), &[]); assert_eq!(pattern.lane(2), &[1, 2, 3]); assert_eq!( pattern.entries().collect::>(), vec![(0, 0), (0, 5), (2, 1), (2, 2), (2, 3)] ); let (offsets2, indices2) = pattern.disassemble(); assert_eq!(offsets2, offsets); assert_eq!(indices2, indices); } } #[test] fn sparsity_pattern_try_from_invalid_data() { { // Empty offset array (invalid length) let pattern = SparsityPattern::try_from_offsets_and_indices(0, 0, Vec::new(), Vec::new()); assert_eq!( pattern, Err(SparsityPatternFormatError::InvalidOffsetArrayLength) ); } { // Offset array invalid length for arbitrary data let offsets = vec![0, 3, 5]; let indices = vec![0, 1, 2, 3, 5]; let pattern = SparsityPattern::try_from_offsets_and_indices(3, 6, offsets, indices); assert!(matches!( pattern, Err(SparsityPatternFormatError::InvalidOffsetArrayLength) )); } { // Invalid first entry in offsets array let offsets = vec![1, 2, 2, 5]; let indices = vec![0, 5, 1, 2, 3]; let pattern = SparsityPattern::try_from_offsets_and_indices(3, 6, offsets, indices); assert!(matches!( pattern, Err(SparsityPatternFormatError::InvalidOffsetFirstLast) )); } { // Invalid last entry in offsets array let offsets = vec![0, 2, 2, 4]; let indices = vec![0, 5, 1, 2, 3]; let pattern = SparsityPattern::try_from_offsets_and_indices(3, 6, offsets, indices); assert!(matches!( pattern, Err(SparsityPatternFormatError::InvalidOffsetFirstLast) )); } { // Invalid length of offsets array let offsets = vec![0, 2, 2]; let indices = vec![0, 5, 1, 2, 3]; let pattern = SparsityPattern::try_from_offsets_and_indices(3, 6, offsets, indices); assert!(matches!( pattern, Err(SparsityPatternFormatError::InvalidOffsetArrayLength) )); } { // Nonmonotonic offsets let offsets = vec![0, 3, 2, 5]; let indices = vec![0, 1, 2, 3, 4]; let pattern = SparsityPattern::try_from_offsets_and_indices(3, 6, offsets, indices); assert_eq!( pattern, Err(SparsityPatternFormatError::NonmonotonicOffsets) ); } { // Nonmonotonic minor indices let offsets = vec![0, 2, 2, 5]; let indices = vec![0, 2, 3, 1, 4]; let pattern = SparsityPattern::try_from_offsets_and_indices(3, 6, offsets, indices); assert_eq!( pattern, Err(SparsityPatternFormatError::NonmonotonicMinorIndices) ); } { // Minor index out of bounds let offsets = vec![0, 2, 2, 5]; let indices = vec![0, 6, 1, 2, 3]; let pattern = SparsityPattern::try_from_offsets_and_indices(3, 6, offsets, indices); assert_eq!( pattern, Err(SparsityPatternFormatError::MinorIndexOutOfBounds) ); } { // Duplicate entry let offsets = vec![0, 2, 2, 5]; let indices = vec![0, 5, 2, 2, 3]; let pattern = SparsityPattern::try_from_offsets_and_indices(3, 6, offsets, indices); assert_eq!(pattern, Err(SparsityPatternFormatError::DuplicateEntry)); } }