Note
Go to the end to download the full example code.
Reed-Solomon codes: recovering from erasures#
Encodes a short message as the values of a polynomial over GF(929), erases symbols at random, and recovers the message from any k surviving values.
import contextlib
import matplotlib.pyplot as plt
import numpy as np
from mathematicskit.abstract_algebra import rs_decode_erasures, rs_encode
Encode a message#
message [77, 65, 84, 72]
codeword [77, 298, 190, 185, 715, 354, 463, 545, 103, 498, 304, 882]
Erase n - k symbols and decode#
rng = np.random.default_rng(0)
erased = set(rng.choice(n, size=n - len(message), replace=False).tolist())
received = [None if i in erased else c for i, c in enumerate(codeword)]
decoded = rs_decode_erasures(received, k=len(message), p=p)
print(f"received {received}")
print(f"decoded {''.join(map(chr, decoded))}")
received [None, 298, None, None, None, 354, None, 545, None, 498, None, None]
decoded MATH
Success rate against the number of erasures#
trials = 200
rates = []
for e in range(n + 1):
ok = 0
for _ in range(trials):
lost = set(rng.choice(n, size=e, replace=False).tolist())
with contextlib.suppress(ValueError):
ok += rs_decode_erasures([None if i in lost else c for i, c in enumerate(codeword)], len(message), p) == message
rates.append(ok / trials)
fig, ax = plt.subplots()
ax.step(range(n + 1), rates, where="mid")
ax.axvline(n - len(message), color="tab:red", ls="--", label="n - k")
ax.set_xlabel("erased symbols")
ax.set_ylabel("fraction decoded correctly")
ax.legend()
ax.set_title("Reed-Solomon (n=12, k=4): any 8 erasures are recoverable")

Text(0.5, 1.0, 'Reed-Solomon (n=12, k=4): any 8 erasures are recoverable')
Total running time of the script: (0 minutes 0.047 seconds)