From 9e85c9e2b69fa443da8f12bb51e9d63c0d319517 Mon Sep 17 00:00:00 2001 From: Anton Date: Sun, 3 Oct 2021 00:56:13 +0200 Subject: [PATCH] CSR/CSC: Provide constructor for unsorted but otherwise valid data --- nalgebra-sparse/src/csr.rs | 27 +++++++++++++++++++++++++ nalgebra-sparse/tests/unit_tests/csr.rs | 23 +++++++++++++++++++++ 2 files changed, 50 insertions(+) diff --git a/nalgebra-sparse/src/csr.rs b/nalgebra-sparse/src/csr.rs index c64be915..fd39fc75 100644 --- a/nalgebra-sparse/src/csr.rs +++ b/nalgebra-sparse/src/csr.rs @@ -170,6 +170,24 @@ impl CsrMatrix { Self::try_from_pattern_and_values(pattern, values) } + /// Try to construct a CSR matrix from raw CSR data with unsorted columns. + pub fn try_from_unsorted_csr_data( + num_rows: usize, + num_cols: usize, + row_offsets: Vec, + col_indices: Vec, + values: Vec, + ) -> Result { + let sorted_num_cols: Vec = row_offsets[0..row_offsets.len() - 1] + .iter() + .enumerate() + .flat_map(|(index, &offset)| { + Self::sorted(col_indices[offset..row_offsets[index + 1]].to_vec()) + }) + .collect(); + return Self::try_from_csr_data(num_rows, num_cols, row_offsets, sorted_num_cols, values); + } + /// Try to construct a CSR matrix from a sparsity pattern and associated non-zero values. /// /// Returns an error if the number of values does not match the number of minor indices @@ -190,6 +208,15 @@ impl CsrMatrix { } } + /// Return sorted vector. + #[inline] + #[must_use] + pub fn sorted(row_offsets: Vec) -> Vec { + let mut sorted = row_offsets.clone(); + sorted.sort(); + return sorted; + } + /// The number of rows in the matrix. #[inline] #[must_use] diff --git a/nalgebra-sparse/tests/unit_tests/csr.rs b/nalgebra-sparse/tests/unit_tests/csr.rs index dee1ae1e..73d4dd27 100644 --- a/nalgebra-sparse/tests/unit_tests/csr.rs +++ b/nalgebra-sparse/tests/unit_tests/csr.rs @@ -171,6 +171,29 @@ fn csr_matrix_valid_data() { } } +#[test] +fn csr_matrix_valid_data_unsorted_column_indices() { + let csr = CsrMatrix::try_from_unsorted_csr_data( + 3, + 4, + vec![0, 1, 2, 5], + vec![1, 3, 2, 3, 0], + vec![5, 4, 1, 1, 4], + ) + .unwrap(); + + let expected_csr = CsrMatrix::try_from_csr_data( + 3, + 4, + vec![0, 1, 2, 5], + vec![1, 3, 0, 2, 3], + vec![5, 4, 1, 1, 4], + ) + .unwrap(); + + assert_eq!(csr, expected_csr); +} + #[test] fn csr_matrix_try_from_invalid_csr_data() { {