# CSVBinaryMatrix operations This module defines the operations for [`CSVBinaryMatrix`]. [`CSVBinaryMatrix`]: crate::matrix::CSVBinaryMatrix ## Producing submatrices Let say we want to obtain the submatrix of `matrix` without the second row and the first column. ```rust use csvbinmatrix::prelude::CSVBinaryMatrix; let matrix = CSVBinaryMatrix::try_from(&[ [0, 0, 0], [0, 0, 1], [0, 1, 1], [1, 1, 1], ]).unwrap(); let expected_sub_matrix = CSVBinaryMatrix::try_from(&[ [0, 0], [1, 1], [1, 1], ]).unwrap(); ``` ### Without consuming the supermatrix ```rust # use csvbinmatrix::prelude::CSVBinaryMatrix; # # let matrix = CSVBinaryMatrix::try_from(&[ # [0, 0, 0], # [0, 0, 1], # [0, 1, 1], # [1, 1, 1], # ]) # .unwrap(); # # let expected_sub_matrix = # CSVBinaryMatrix::try_from(&[[0, 0], [1, 1], [1, 1]]).unwrap(); use csvbinmatrix::prelude::{ClosureDimensionFilter}; let row_filter = ClosureDimensionFilter::new(|i| i != 1); let column_filter = ClosureDimensionFilter::new(|j| j != 0); // Generate submatrices according to the couples of row and column filters. // `matrix` is not consumed. match matrix.to_submatrix(&row_filter, &column_filter) { Ok(sub_matrix) => assert_eq!(sub_matrix, expected_sub_matrix), Err(err) => panic!("[ERROR] {err}"), } ``` ### With consuming the supermatrix Here we show how to obtain an efficient submatrix while consuming the super binary matrix with the [`into_submatrices`] method. The memory and the time complexities are linear according to the number ones of the super binary matrix. As the supermatrix is consumed, `into_submatrices` take as input a vector of tuples of dimension filters, and return for each tuple of filters a submatrix. [`into_submatrices`]: crate::matrix::CSVBinaryMatrix::into_submatrices ```rust # use csvbinmatrix::prelude::CSVBinaryMatrix; # # let matrix = CSVBinaryMatrix::try_from(&[ # [0, 0, 0], # [0, 0, 1], # [0, 1, 1], # [1, 1, 1], # ]) # .unwrap(); # # let expected_sub_matrix = # CSVBinaryMatrix::try_from(&[[0, 0], [1, 1], [1, 1]]).unwrap(); use csvbinmatrix::prelude::{BoolVecDimensionFilter, ClosureDimensionFilter}; // Filter with a boolean vector: // * to represent complex truth states // * costly let row_filter = match BoolVecDimensionFilter::new(vec![true, false, true, true], matrix.number_of_rows()) { Ok(filter) => filter, Err(err) => panic!("[ERROR] {err}"), }; // Filter with a closure // * to represent simple truth states // * efficient let column_filter = ClosureDimensionFilter::new(|j| j != 0); // Generate submatrices according to the couples of row and column filters. // `matrix` is consumed. let mut sub_matrices = matrix.into_submatrices(vec![(&row_filter, &column_filter)]); // Iterate over the submatrices and check them match sub_matrices.pop() { Some(Ok(reversed_sub_matrix)) => { assert_eq!(reversed_sub_matrix, expected_sub_matrix) } Some(Err(err)) => panic!("[ERROR] {err}"), _ => unreachable!("There must be one resulting sub matrix."), } // We give only one filter couple, so there is only one resulting submatrix. assert!(sub_matrices.pop().is_none()); // You can drop the row filter and take the ownership of the boolean vectors. let boolvec_row = row_filter.into_boolean_vector(); println!("Boolean vector for the rows: {boolvec_row:?}"); ```