pdc_project/receiver.py
2025-05-20 19:17:08 +02:00

69 lines
No EOL
2.1 KiB
Python

import numpy as np
def bits_to_text(bits, alphabet):
"""Convert binary bits to text using the alphabet."""
char_to_idx = {char: idx for idx, char in enumerate(alphabet)}
idx_to_char = {idx: char for char, idx in char_to_idx.items()}
text = ''
for i in range(0, len(bits), 6):
# Convert 6 bits to an integer
idx = int(''.join(map(str, bits[i:i + 6])), 2)
text += idx_to_char.get(idx, '?') # Default to '?' if index invalid
return text
def receiver(Y):
"""
Decode the received signal Y to a 40-character text message.
Parameters:
Y (np.ndarray): Received signal of length 480.
Returns:
str: Decoded 40-character text message.
"""
# Define constants
G = 10 # Power gain
sigma2 = 10 # Noise variance
alphabet = (
'abcdefghijklmnopqrstuvwxyz'
'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
'0123456789 .'
)
# Input validation
if Y.size != 480:
raise ValueError("Received signal must have length 480.")
n = 480
bits = np.zeros(240, dtype=int)
E = 4 # Energy per bit, must match transmitter
# Process each bit (sent at indices 2i and 2i+1)
for i in range(240):
y_odd = Y[2 * i] # Even index in Y (0-based)
y_even = Y[2 * i + 1] # Odd index in Y
# LLR for channel 1: odd indices have gain sqrt(G), even have gain 1
# H0: bit = 0 (sent +sqrt(E)), H1: bit = 1 (sent -sqrt(E))
llr_ch1 = (
(y_odd * np.sqrt(E) * np.sqrt(G) / sigma2) + # Odd index term
(y_even * np.sqrt(E) / sigma2) # Even index term
)
# LLR for channel 2: even indices have gain sqrt(G), odd have gain 1
llr_ch2 = (
(y_odd * np.sqrt(E) / sigma2) + # Odd index term
(y_even * np.sqrt(E) * np.sqrt(G) / sigma2) # Even index term
)
# Combine LLRs (assuming equal prior probabilities for both channels)
llr = 0.5 * (llr_ch1 + llr_ch2)
# Decode bit: LLR > 0 implies bit = 0, LLR < 0 implies bit = 1
bits[i] = 1 if llr < 0 else 0
# Convert bits to text
text = bits_to_text(bits, alphabet)
return text