use nalgebra::DMatrix;
use nalgebra_block_triangularization::upper_block_triangular_structure;
use proptest::prelude::*;
proptest! {
#[test]
fn output_orders_are_permutations(
bits in prop::collection::vec(any::<u8>(), 1..400)
) {
let n = (bits.len() as f64).sqrt() as usize;
if n < 1 {
return Ok(());
}
let bits: Vec<u8> = bits.into_iter().take(n * n).map(|b| b % 2).collect();
let m = DMatrix::from_row_slice(n, n, &bits);
let structure = upper_block_triangular_structure(&m);
let mut sorted_rows = structure.row_order.clone();
sorted_rows.sort_unstable();
prop_assert_eq!(sorted_rows, (0..n).collect::<Vec<_>>());
let mut sorted_cols = structure.col_order.clone();
sorted_cols.sort_unstable();
prop_assert_eq!(sorted_cols, (0..n).collect::<Vec<_>>());
}
#[test]
fn block_sizes_sum_correctly(
bits in prop::collection::vec(any::<u8>(), 1..400)
) {
let n = (bits.len() as f64).sqrt() as usize;
if n < 1 {
return Ok(());
}
let bits: Vec<u8> = bits.into_iter().take(n * n).map(|b| b % 2).collect();
let m = DMatrix::from_row_slice(n, n, &bits);
let structure = upper_block_triangular_structure(&m);
let sum: usize = structure.block_sizes.iter().sum();
prop_assert_eq!(sum, n);
}
#[test]
fn matching_size_bounded_in_btf(
bits in prop::collection::vec(any::<u8>(), 1..600)
) {
let total = bits.len();
let nrows = ((total as f64) / 1.5).sqrt() as usize;
let ncols = if nrows > 0 { total / nrows } else { 0 };
if nrows < 1 || ncols < 1 {
return Ok(());
}
let bits: Vec<u8> = bits.into_iter().take(nrows * ncols).map(|b| b % 2).collect();
let m = DMatrix::from_row_slice(nrows, ncols, &bits);
let structure = upper_block_triangular_structure(&m);
prop_assert!(structure.matching_size <= nrows.min(ncols));
}
}