# evaluate_zero_error_ratio.py import argparse import numpy as np from encoder import text_to_signal from decoder import signal_to_text from channel import channel def zero_error_ratio(message: str, r: int, Eb: float, n_runs: int) -> float: """ Runs the encode–channel–decode pipeline n_runs times on the same message, and returns the fraction of runs with 0 character errors. """ zero_count = 0 for _ in range(n_runs): # encode x, codebook = text_to_signal(message, r=r, Eb=Eb) # pass through channel y = channel(x) # decode decoded = signal_to_text(y, codebook, r=r) # count errors errors = sum(1 for a, b in zip(message, decoded) if a != b) if errors == 0: zero_count += 1 return zero_count / n_runs if __name__ == "__main__": parser = argparse.ArgumentParser( description="Estimate the zero-error run ratio over n trials." ) parser.add_argument( "--message", type=str, required=True, help="The 40-char message to test." ) parser.add_argument( "--r", type=int, default=6, help="Codebook parameter r (default: 6)." ) parser.add_argument( "--Eb", type=float, default=3.0, help="Energy per bit Eb (default: 3)." ) parser.add_argument( "--n", type=int, default=1000, help="Number of runs (default: 1000)." ) args = parser.parse_args() if len(args.message) != 40: raise ValueError("Message must be exactly 40 characters long.") ratio = zero_error_ratio(args.message, args.r, args.Eb, args.n) print(f"Zero-error runs: {ratio:.3%} ({ratio:.4f} of {args.n})")