54 lines
1.7 KiB
Python
54 lines
1.7 KiB
Python
# 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})")
|