pdc_project/decoder.py
2025-05-25 14:41:39 +02:00

40 lines
No EOL
1.2 KiB
Python

import numpy as np
from numpy import logaddexp
from utils import index_to_char
from codebook import construct_codebook
def decode_message(Y, codebook):
"""
ML decoding for unknown channel state s:
p(Y|i) = 0.5*p(Y|i,s=1) + 0.5*p(Y|i,s=2)
We use log-sum-exp to combine both branch metrics.
"""
G = 10
Y1, Y2 = Y[::2], Y[1::2]
best_idx = None
best_metric = -np.inf
for i, c in enumerate(codebook):
# Only consider indices that map to characters
if i not in index_to_char:
continue
c1, c2 = c[::2], c[1::2]
# Branch metrics (up to additive constants)
s1 = np.sqrt(G) * np.dot(Y1, c1) + np.dot(Y2, c2)
s2 = np.dot(Y1, c1) + np.sqrt(G) * np.dot(Y2, c2)
# Combine via log-sum-exp
metric = logaddexp(s1, s2)
if metric > best_metric:
best_metric = metric
best_idx = i
return best_idx
def signal_to_text(Y, codebook, r=6):
# Reconstruct codebook length (seg_len)
_, seg_len, _, _ = construct_codebook(r, 1)
text = ''
for i in range(40):
seg = Y[i * seg_len:(i + 1) * seg_len]
idx = decode_message(seg, codebook)
text += index_to_char.get(idx, '?')
return text