54 lines
1.6 KiB
Rust
54 lines
1.6 KiB
Rust
use crate::matrix::MatrixGF2;
|
|
use rand::RngExt;
|
|
|
|
// H doit respecter les contraine des poids w_c et w_r
|
|
pub fn generate_random_h(rows: usize, cols: usize, wc: usize, wr: usize) -> MatrixGF2 {
|
|
assert_eq!(rows * wr, cols * wc, "Erreur");
|
|
loop {
|
|
let mut data = vec![0; rows * cols];
|
|
let mut row_w = vec![0; rows];
|
|
let mut rng = rand::rng();
|
|
let mut success = true;
|
|
|
|
for c in 0..cols {
|
|
let mut ones_placed = 0;
|
|
let mut avail_rows: Vec<usize> = (0..rows).filter(|&r| row_w[r] < wr).collect();
|
|
|
|
if avail_rows.len() < wc {
|
|
// Les problèmes...
|
|
success = false;
|
|
break;
|
|
}
|
|
|
|
while ones_placed < wc {
|
|
let id = rng.random_range(0..avail_rows.len());
|
|
let r = avail_rows.remove(id);
|
|
data[r * cols + c] = 1;
|
|
row_w[r] += 1;
|
|
ones_placed += 1;
|
|
}
|
|
}
|
|
if success {
|
|
return MatrixGF2::new(rows, cols, data);
|
|
}
|
|
}
|
|
}
|
|
|
|
pub fn generate_random_h_for_k(k: usize, wc: usize, wr: usize) -> MatrixGF2 {
|
|
assert!(wr > wc, "wr < wc ...");
|
|
assert!((k * wr) % (wr - wc) == 0, "Colonnes non entieres");
|
|
|
|
let n = (k * wr) / (wr - wc);
|
|
let m = n - k;
|
|
|
|
// On garde que les matrice de rang m
|
|
loop {
|
|
let h_matrix = generate_random_h(m, n, wc, wr);
|
|
let mut h_test = h_matrix.clone();
|
|
let (rank, _) = h_test.gauss_jordan_swap_cols();
|
|
if rank == m {
|
|
return h_matrix;
|
|
}
|
|
}
|
|
}
|