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