ldpc_toolbox/cli/
peg.rs

1//! Progressive Edge Growth (PEG) CLI subcommand
2//!
3//! This uses the Progressive Edge Growth (PEG) pseudorandom construction to
4//! build and LDPC parity check matrix. It runs the PEG algorithm and, if the
5//! construction is successful, prints to `stout` the alist of the parity check
6//! matrix. Optionally, it can also print to `stderr` the girth of the generated
7//! code. For more details about this construction, see [`crate::peg`].
8//!
9//! # Examples
10//! An r=1/2, n=16800 regular code with column weight 3 can be generated
11//! with
12//! ```shell
13//! $ ldpc-toolbox peg 8100 16200 3 0
14//! ```
15//! To construct the code and only show the girth, we run
16//! ```shell
17//! $ ldpc-toolbox peg 8100 16200 3 0 --girth > /dev/null
18//! ```
19
20use crate::cli::*;
21use crate::peg::Config;
22use clap::Parser;
23use std::error::Error;
24
25/// PEG CLI arguments.
26#[derive(Debug, Parser)]
27#[command(about = "Generates LDPC codes using the Progressive Edge Growth algorithm")]
28pub struct Args {
29    /// Number of rows
30    pub num_rows: usize,
31    /// Number of columns
32    pub num_columns: usize,
33    /// Column weight
34    pub wc: usize,
35    /// Seed
36    pub seed: u64,
37    /// Performs girth calculation
38    #[arg(long)]
39    pub girth: bool,
40}
41
42impl Args {
43    fn config(&self) -> Config {
44        Config {
45            nrows: self.num_rows,
46            ncols: self.num_columns,
47            wc: self.wc,
48        }
49    }
50}
51
52impl Run for Args {
53    fn run(&self) -> Result<(), Box<dyn Error>> {
54        let conf = self.config();
55        let h = conf.run(self.seed)?;
56        for r in 0..h.num_rows() {
57            if h.row_weight(r) < 2 {
58                eprint!("warning: at least 1 row weight ≤ 1");
59                if conf.wc < 3 {
60                    eprint!(" (try col weight ≥ 3?)");
61                }
62                eprintln!();
63                break;
64            }
65        }
66        println!("{}", h.alist());
67        if self.girth {
68            match h.girth() {
69                Some(g) => eprintln!("Code girth = {}", g),
70                None => eprintln!("Code girth = infinity (there are no cycles)"),
71            };
72        }
73        Ok(())
74    }
75}