Compare commits

...

3 Commits

Author SHA1 Message Date
5e997b58d9 text recu works 2026-02-13 17:32:46 +01:00
b343675fa7 vraiment la merde 2026-02-13 17:13:11 +01:00
8c2abd902c c'est la merde 2026-02-13 16:48:28 +01:00
7 changed files with 126 additions and 26 deletions

View File

@ -12,7 +12,9 @@ pub fn generate_random_h(rows: usize, cols: usize, wc: usize, wr: usize) -> Matr
for c in 0..cols { for c in 0..cols {
let mut ones_placed = 0; let mut ones_placed = 0;
let mut avail_rows: Vec<usize> = (0..rows).filter(|&r| row_w[r] < wr).collect(); let mut avail_rows: Vec<usize> = (0..rows)
.filter(|&r| row_w[r] < wr && !creates_cycle_4(rows, cols, &data, r, c))
.collect();
if avail_rows.len() < wc { if avail_rows.len() < wc {
// Les problèmes... // Les problèmes...
@ -60,3 +62,16 @@ pub fn generate_random_h_for_k(k: usize, wc: usize, wr: usize) -> MatrixGF2 {
} }
best_h best_h
} }
fn creates_cycle_4(rows: usize, cols: usize, data: &[u8], row: usize, col: usize) -> bool {
for r2 in 0..rows {
if r2 != row && data[r2 * cols + col] == 1 {
for c2 in 0..col {
if data[row * cols + c2] == 1 && data[r2 * cols + c2] == 1 {
return true;
}
}
}
}
false
}

View File

@ -1,3 +1,5 @@
use rand::RngExt;
use crate::code::LdpcCode; use crate::code::LdpcCode;
pub struct BitFlipDecoder<'a> { pub struct BitFlipDecoder<'a> {
@ -35,6 +37,7 @@ impl<'a> BitFlipDecoder<'a> {
} }
} }
// println!("poid syndome: {s_w}");
// Aucune erreurs // Aucune erreurs
if s_w == 0 { if s_w == 0 {
return Some(curr_bits); return Some(curr_bits);
@ -65,8 +68,21 @@ impl<'a> BitFlipDecoder<'a> {
curr_bits[i] ^= 1; // Bit flip curr_bits[i] ^= 1; // Bit flip
} }
} }
// Seuil de 3
// if max_cpt >= 3 {
// for i in 0..n {
// if cpt[i] == max_cpt {
// curr_bits[i] ^= 1;
// }
// }
// } else if max_cpt > 0 {
// if let Some(idx) = cpt.iter().position(|&x| x == max_cpt) {
// curr_bits[idx] ^= 1;
// }
// } else {
// break;
// }
} }
None
return Some(curr_bits);
} }
} }

View File

@ -7,6 +7,7 @@ pub struct DenseEncoder {
pub k: usize, pub k: usize,
pub n: usize, pub n: usize,
pub col_swaps: Vec<(usize, usize)>, pub col_swaps: Vec<(usize, usize)>,
pub rank: usize,
} }
impl DenseEncoder { impl DenseEncoder {
@ -33,6 +34,7 @@ impl DenseEncoder {
k, k,
n, n,
col_swaps, col_swaps,
rank,
} }
} }
@ -48,10 +50,25 @@ impl DenseEncoder {
.collect(); .collect();
// Reverse les changement de colonnes // Reverse les changement de colonnes
for &(c1, c2) in self.col_swaps.iter().rev() { // for &(c1, c2) in self.col_swaps.iter().rev() {
codeword.swap(c1, c2); // codeword.swap(c1, c2);
} // }
self.g_matrix
.apply_inverse_permutation(&mut codeword, &self.col_swaps);
codeword codeword
} }
pub fn extract_message(&self, decoded_codeword: &[u8]) -> Vec<u8> {
let mut working_copy = decoded_codeword.to_vec();
self.g_matrix
.apply_permutation(&mut working_copy, &self.col_swaps);
let mut message = Vec::with_capacity(self.k);
for i in 0..self.k {
message.push(working_copy[self.rank + i]);
}
message
}
} }

View File

@ -7,25 +7,28 @@ mod encoder;
mod matrix; mod matrix;
mod simulation; mod simulation;
mod tanner; mod tanner;
mod utils;
use analysis::{AnalysisConfig, Analyzer, DecoderAlgorithm}; use analysis::{AnalysisConfig, Analyzer, DecoderAlgorithm};
fn main() { fn main() {
println!("Analyse des performences"); // println!("Analyse des performences");
let config = AnalysisConfig { // let config = AnalysisConfig {
k_values: vec![50, 200, 400, 800, 1000], // k_values: vec![50, 200, 400, 800, 1000],
wc_values: vec![3, 4, 5], // wc_values: vec![3, 4, 5],
wr_values: vec![6, 8, 9, 12, 15, 16], // wr_values: vec![6, 8, 9, 12, 15, 16],
min_error_prob: 0.00, // min_error_prob: 0.00,
max_error_prob: 0.12, // max_error_prob: 0.12,
steps: 15, // steps: 15,
frames_per_step: 1000, // frames_per_step: 1000,
max_iter: 50, // max_iter: 50,
algorithm: DecoderAlgorithm::BitFlipping, // algorithm: DecoderAlgorithm::BitFlipping,
}; // };
//
// let res = Analyzer::run_batch(config);
// Analyzer::save_csv(&res, "ldpc_analysis_results.csv");
let res = Analyzer::run_batch(config); let message = "Je suis un test";
Analyzer::save_csv(&res, "ldpc_analysis_results.csv"); simulation::run_simulation(message, 3, 6, 0.01);
// simulation::run_simulation(1000, 3, 6, 0.005);
} }

View File

@ -130,4 +130,16 @@ impl MatrixGF2 {
} }
(rank, col_swaps) (rank, col_swaps)
} }
pub fn apply_inverse_permutation(&self, data: &mut [u8], swaps: &[(usize, usize)]) {
for &(c1, c2) in swaps.iter().rev() {
data.swap(c1, c2);
}
}
pub fn apply_permutation(&self, data: &mut [u8], swaps: &[(usize, usize)]) {
for &(c1, c2) in swaps.iter() {
data.swap(c1, c2);
}
}
} }

View File

@ -6,12 +6,15 @@ use crate::code::{self, LdpcCode};
use crate::construction::random::{generate_random_h, generate_random_h_for_k}; use crate::construction::random::{generate_random_h, generate_random_h_for_k};
use crate::decoder::bit_flip::BitFlipDecoder; use crate::decoder::bit_flip::BitFlipDecoder;
use crate::encoder::dense::DenseEncoder; use crate::encoder::dense::DenseEncoder;
use crate::utils;
use rand::{Rng, RngExt}; use rand::{Rng, RngExt};
pub fn run_simulation(k: usize, wc: usize, wr: usize, error_prob: f64) { pub fn run_simulation(text: &str, wc: usize, wr: usize, error_prob: f64) {
let mut message_bits = utils::string_to_bits(text);
let k = message_bits.len();
println!( println!(
"\nSimulation LDPC : k = {} bits, wc = {}, wr = {}, p = {:.2}", "\nSimulation LDPC : k = {} bits, wc = {}, wr = {}, p = {:.2}, text : {}",
k, wc, wr, error_prob k, wc, wr, error_prob, text
); );
println!("Construction"); println!("Construction");
@ -36,7 +39,9 @@ pub fn run_simulation(k: usize, wc: usize, wr: usize, error_prob: f64) {
println!("Encodage"); println!("Encodage");
let mut rng = rand::rng(); let mut rng = rand::rng();
let message: Vec<u8> = (0..k).map(|_| rng.random_range(0..2)).collect(); // let message: Vec<u8> = (0..k).map(|_| rng.random_range(0..2)).collect();
let mut message = message_bits.clone();
message.resize(encoder.k, 0);
let codeword = encoder.encode(&message); let codeword = encoder.encode(&message);
@ -64,21 +69,27 @@ pub fn run_simulation(k: usize, wc: usize, wr: usize, error_prob: f64) {
} }
let decoder = BitFlipDecoder::new(&ldpc); let decoder = BitFlipDecoder::new(&ldpc);
let max_iter = 50; let max_iter = 100;
match decoder.decode(&received, max_iter) { match decoder.decode(&received, max_iter) {
Some(decoded) => { Some(decoded) => {
let decoded_message_bits = encoder.extract_message(&decoded);
let res_text = utils::bits_to_string(&decoded_message_bits);
if decoded == codeword { if decoded == codeword {
println!(" -> Réussite"); println!(" -> Réussite");
} else { } else {
println!(" -> Echec : le decoder a convergé vers un mauvais codeword"); println!(" -> Echec : le decoder a convergé vers un mauvais codeword");
} }
println!(" -> Texte recu : {}", res_text);
} }
None => { None => {
let rec_bits = encoder.extract_message(&received);
let failed_text = utils::bits_to_string(&rec_bits);
println!( println!(
" -> Echec : impossible decorriger après {} itérations", " -> Echec : impossible decorriger après {} itérations",
max_iter max_iter
); );
println!(" -> Texte recu : {}", failed_text);
} }
} }
} }

26
Code/ldpc/src/utils.rs Normal file
View File

@ -0,0 +1,26 @@
pub fn string_to_bits(s: &str) -> Vec<u8> {
let mut bits = Vec::new();
for byte in s.as_bytes() {
for i in (0..8).rev() {
bits.push((byte >> i) & 1);
}
}
bits
}
pub fn bits_to_string(bits: &[u8]) -> String {
let mut bytes = Vec::new();
for chunk in bits.chunks(8) {
if chunk.len() < 8 {
break;
}
let mut byte = 0u8;
for (i, &bit) in chunk.iter().enumerate() {
if bit == 1 {
byte |= 1 << (7 - i);
}
}
bytes.push(byte);
}
String::from_utf8_lossy(&bytes).into_owned()
}