ldpc-toolbox 0.12.0

Utilities to aid in LDPC code design
Documentation
//! Progressive Edge Growth (PEG) CLI subcommand
//!
//! This uses the Progressive Edge Growth (PEG) pseudorandom construction to
//! build and LDPC parity check matrix. It runs the PEG algorithm and, if the
//! construction is successful, prints to `stout` the alist of the parity check
//! matrix. Optionally, it can also print to `stderr` the girth of the generated
//! code. For more details about this construction, see [`crate::peg`].
//!
//! # Examples
//! An r=1/2, n=16800 regular code with column weight 3 can be generated
//! with
//! ```shell
//! $ ldpc-toolbox peg 8100 16200 3 0
//! ```
//! To construct the code and only show the girth, we run
//! ```shell
//! $ ldpc-toolbox peg 8100 16200 3 0 --girth > /dev/null
//! ```

use crate::cli::*;
use crate::peg::Config;
use clap::Parser;
use std::error::Error;

/// PEG CLI arguments.
#[derive(Debug, Parser)]
#[command(about = "Generates LDPC codes using the Progressive Edge Growth algorithm")]
pub struct Args {
    /// Number of rows
    pub num_rows: usize,
    /// Number of columns
    pub num_columns: usize,
    /// Column weight
    pub wc: usize,
    /// Seed
    pub seed: u64,
    /// Performs girth calculation
    #[arg(long)]
    pub girth: bool,
}

impl Args {
    fn config(&self) -> Config {
        Config {
            nrows: self.num_rows,
            ncols: self.num_columns,
            wc: self.wc,
        }
    }
}

impl Run for Args {
    fn run(&self) -> Result<(), Box<dyn Error>> {
        let conf = self.config();
        let h = conf.run(self.seed)?;
        for r in 0..h.num_rows() {
            if h.row_weight(r) < 2 {
                eprint!("warning: at least 1 row weight ≤ 1");
                if conf.wc < 3 {
                    eprint!(" (try col weight ≥ 3?)");
                }
                eprintln!();
                break;
            }
        }
        println!("{}", h.alist());
        if self.girth {
            match h.girth() {
                Some(g) => eprintln!("Code girth = {}", g),
                None => eprintln!("Code girth = infinity (there are no cycles)"),
            };
        }
        Ok(())
    }
}