51 lines
No EOL
1.5 KiB
Python
51 lines
No EOL
1.5 KiB
Python
# PDC Project 2025 - Peters Stefan, Pelletier Antoine, Jeong Jaeyi, Cohen Adam
|
|
|
|
import numpy as np
|
|
from encoder import G, ALPHABET, make_codebook
|
|
|
|
def decode_blocks_with_state(Y: np.ndarray, C: np.ndarray):
|
|
N = Y.size
|
|
assert N % 2 == 0
|
|
assert N <= 1_000_000
|
|
|
|
n_cw = C.shape[1] * 2
|
|
nb = Y.size // n_cw
|
|
assert nb * n_cw == Y.size, "length mismatch between Y and codebook"
|
|
|
|
Y_blocks = Y.reshape(nb, n_cw)
|
|
Y_even = Y_blocks[:, ::2].astype(np.float32)
|
|
Y_odd = Y_blocks[:, 1::2].astype(np.float32)
|
|
C = C.astype(np.float32)
|
|
|
|
sqrtg = np.sqrt(G)
|
|
s1 = sqrtg * (Y_even @ C.T) + (Y_odd @ C.T)
|
|
s2 = (Y_even @ C.T) + sqrtg * (Y_odd @ C.T)
|
|
|
|
best_if_s1 = np.argmax(s1, axis=1)
|
|
best_if_s2 = np.argmax(s2, axis=1)
|
|
|
|
tot1 = np.sum(np.max(s1, axis=1))
|
|
tot2 = np.sum(np.max(s2, axis=1))
|
|
|
|
state = 1 if tot1 >= tot2 else 2
|
|
indices = best_if_s1 if state == 1 else best_if_s2
|
|
|
|
msg_chars = []
|
|
for idx in indices:
|
|
first = ALPHABET[idx >> 6]
|
|
second = ALPHABET[idx & 0x3F]
|
|
msg_chars.append(first)
|
|
msg_chars.append(second)
|
|
|
|
decoded = ''.join(msg_chars)
|
|
return decoded, state
|
|
|
|
def decode_blocks(Y: np.ndarray, C: np.ndarray) -> str:
|
|
return decode_blocks_with_state(Y, C)[0]
|
|
|
|
if __name__ == "__main__":
|
|
Y = np.loadtxt("output.txt")
|
|
C, _ = make_codebook()
|
|
decoded, state = decode_blocks_with_state(Y, C)
|
|
print(f"Decoded message: {decoded}")
|
|
print(f"Detected channel state: {state}") |