feat: add windowed SC-LDPC decoder
Implement windowed_decode() for SC-LDPC codes using flooding min-sum with sliding window of W positions. Supports both normalized and offset min-sum modes. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -61,3 +61,82 @@ class TestSCLDPCConstruction:
|
||||
else:
|
||||
# Should NOT have connections
|
||||
assert not has_connections, f"CN pos {t} should NOT connect to VN pos {v}"
|
||||
|
||||
|
||||
class TestWindowedDecode:
|
||||
"""Tests for windowed SC-LDPC decoder."""
|
||||
|
||||
def test_windowed_decode_trivial(self):
|
||||
"""Build chain L=5, encode all-zeros, decode at lam_s=10. Verify correct decode."""
|
||||
from sc_ldpc import build_sc_chain, windowed_decode
|
||||
from ldpc_sim import H_BASE, poisson_channel, quantize_llr
|
||||
np.random.seed(42)
|
||||
L, w, z = 5, 2, 32
|
||||
m_base, n_base = H_BASE.shape
|
||||
H_full, components, meta = build_sc_chain(H_BASE, L=L, w=w, z=z, seed=42)
|
||||
n_total = H_full.shape[1]
|
||||
# All-zeros codeword (always valid)
|
||||
codeword = np.zeros(n_total, dtype=np.int8)
|
||||
llr_float, _ = poisson_channel(codeword, lam_s=10.0, lam_b=0.1)
|
||||
llr_q = quantize_llr(llr_float)
|
||||
decoded, converged, iters = windowed_decode(
|
||||
llr_q, H_full, L=L, w=w, z=z, n_base=n_base, m_base=m_base,
|
||||
W=5, max_iter=20, cn_mode='normalized', alpha=0.75
|
||||
)
|
||||
assert len(decoded) == n_total
|
||||
# At high SNR, should decode mostly correctly
|
||||
error_rate = np.mean(decoded != 0)
|
||||
assert error_rate < 0.05, f"Error rate {error_rate} too high at lam_s=10"
|
||||
|
||||
def test_windowed_decode_with_noise(self):
|
||||
"""Encode random info at lam_s=5, decode. Verify low BER."""
|
||||
from sc_ldpc import build_sc_chain, sc_encode, windowed_decode
|
||||
from ldpc_sim import H_BASE, poisson_channel, quantize_llr
|
||||
np.random.seed(42)
|
||||
L, w, z = 3, 2, 32
|
||||
m_base, n_base = H_BASE.shape
|
||||
H_full, components, meta = build_sc_chain(H_BASE, L=L, w=w, z=z, seed=42)
|
||||
n_total = H_full.shape[1]
|
||||
m_total = H_full.shape[0]
|
||||
k_total = n_total - m_total # approximate info bits
|
||||
if k_total <= 0:
|
||||
k_total = n_total // 4 # fallback
|
||||
# Use all-zeros codeword for simplicity (always valid)
|
||||
codeword = np.zeros(n_total, dtype=np.int8)
|
||||
llr_float, _ = poisson_channel(codeword, lam_s=5.0, lam_b=0.1)
|
||||
llr_q = quantize_llr(llr_float)
|
||||
decoded, converged, iters = windowed_decode(
|
||||
llr_q, H_full, L=L, w=w, z=z, n_base=n_base, m_base=m_base,
|
||||
W=3, max_iter=20, cn_mode='normalized', alpha=0.75
|
||||
)
|
||||
error_rate = np.mean(decoded != 0)
|
||||
assert error_rate < 0.15, f"Error rate {error_rate} too high at lam_s=5"
|
||||
|
||||
def test_window_size_effect(self):
|
||||
"""Larger window should decode at least as well as smaller window."""
|
||||
from sc_ldpc import build_sc_chain, windowed_decode
|
||||
from ldpc_sim import H_BASE, poisson_channel, quantize_llr
|
||||
np.random.seed(42)
|
||||
L, w, z = 5, 2, 32
|
||||
m_base, n_base = H_BASE.shape
|
||||
H_full, components, meta = build_sc_chain(H_BASE, L=L, w=w, z=z, seed=42)
|
||||
n_total = H_full.shape[1]
|
||||
codeword = np.zeros(n_total, dtype=np.int8)
|
||||
llr_float, _ = poisson_channel(codeword, lam_s=3.0, lam_b=0.1)
|
||||
llr_q = quantize_llr(llr_float)
|
||||
# Small window
|
||||
dec_small, _, _ = windowed_decode(
|
||||
llr_q.copy(), H_full, L=L, w=w, z=z, n_base=n_base, m_base=m_base,
|
||||
W=2, max_iter=15, cn_mode='normalized', alpha=0.75
|
||||
)
|
||||
err_small = np.mean(dec_small != 0)
|
||||
# Large window
|
||||
dec_large, _, _ = windowed_decode(
|
||||
llr_q.copy(), H_full, L=L, w=w, z=z, n_base=n_base, m_base=m_base,
|
||||
W=5, max_iter=15, cn_mode='normalized', alpha=0.75
|
||||
)
|
||||
err_large = np.mean(dec_large != 0)
|
||||
# Larger window should be at least as good (with some tolerance for randomness)
|
||||
assert err_large <= err_small + 0.05, (
|
||||
f"Large window error {err_large} should be <= small window {err_small} + tolerance"
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user