csvbinmatrix 0.8.0

Binary matrix Compressed Sparse Vector
Documentation
use rstest::{fixture, rstest};

#[fixture]
fn init_matrices() -> (
    csvbinmatrix::prelude::CSVBinaryMatrix,
    csvbinmatrix::prelude::CSVBinaryMatrix,
) {
    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();

    (matrix, expected_sub_matrix)
}

#[rstest]
fn sub_with_copy(
    init_matrices: (
        csvbinmatrix::prelude::CSVBinaryMatrix,
        csvbinmatrix::prelude::CSVBinaryMatrix,
    ),
) {
    let matrix = init_matrices.0;
    let expected_sub_matrix = init_matrices.1;
    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}"),
    }
}

#[rstest]
fn with_bool_vector_and_closure(
    init_matrices: (
        csvbinmatrix::prelude::CSVBinaryMatrix,
        csvbinmatrix::prelude::CSVBinaryMatrix,
    ),
) {
    let matrix = init_matrices.0;
    let expected_sub_matrix = init_matrices.1;
    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:?}");
}