def encode(self, data_bits): if len(data_bits) != 400: raise ValueError("WIRT only supports 400 bits data") # Polar coding data_polar = polar_encode(wirt.POLAR_SIZE, wirt.DATA_SIZE, data_bits) data_enc = repack_bits(data_polar, 1, 2) data_enc_rep = np.tile(data_enc, (1, wirt.NUM_REPETITIONS)).ravel() # QPSK modulate data_enc_mod = qpsk_modulate(data_enc_rep) # OFDM modulation (subcarrier mapping, pilot insertion, IFFT, cyclic prefix insert) IQ_data_clean = self.mod.modulate(data_enc_mod) IQ_data_power = IQ_data_clean.var() # Add preamble sequence # The ZC sequence is given the same variance as the IQ data in order to normalize the power zc_sequence_norm = self.zc_sequence * np.sqrt(IQ_data_power) IQ_data_preamp = np.hstack((zc_sequence_norm, IQ_data_clean)) # Upsampling, Polyphase IQ_data = upsample_poly(IQ_data_preamp, wirt.SAMP_PER_SYMBOL, self.upsamp_filter) # Normalize the power to mean 0 dBm signal_power = (IQ_data.conj() * IQ_data).mean().real IQ_data /= np.sqrt(signal_power) return IQ_data
def __init__(self, fft_size=32, num_cyclic_prefix=2, add_pilot=True, num_pilots=4, num_guardbands=None): super(OFDMModulator, self).__init__() self.fft_size = fft_size self.num_cyclic_prefix = num_cyclic_prefix self.num_data_carriers = self.fft_size if num_guardbands is None: self.num_guardbands = (2, 2) elif type(num_guardbands) == tuple: self.num_guardbands = num_guardbands elif type(num_guardbands) == int: gb = (np.floor(num_guardbands / 2).astype(int), np.ceil(num_guardbands / 2).astype(int)) self.num_guardbands = gb else: raise ValueError("num_guardbands must be integer or tuple") self.num_data_carriers -= sum(self.num_guardbands) self.add_pilot = add_pilot if self.add_pilot: self.num_data_carriers -= num_pilots first_pilot = self.num_data_carriers / (num_pilots) self.pilot_index = np.round(np.linspace(first_pilot, (num_pilots - 1) * first_pilot, num_pilots)).astype(np.int) self.pilot = np.tile(qpsk_modulate(np.array([0, 1])), (1, num_pilots // 2)).ravel()
def matlab_test(): print("Matlab test") matlab_data = loadmat('tests/data/ofdm_test.mat') FFT_SIZE = int(matlab_data['fft_size']) CYCLIC_PREFIX_LEN = int(matlab_data['num_cyclic_prefix']) # Structures mod = OFDM.OFDMModulator(fft_size=FFT_SIZE, num_cyclic_prefix=CYCLIC_PREFIX_LEN, add_pilot=False, num_guardbands=(0, 0)) data = matlab_data['data'].flatten() python_modulated = mod.modulate(qpsk_modulate(data)) / (len(data) / 2) # Python normalizes power, matlab does not matlab_modulated = matlab_data['moddat'].flatten() print("Modulation correct:", np.allclose(python_modulated, matlab_modulated)) print("Demodulation identical:", np.allclose(mod.demodulate(python_modulated), mod.demodulate(matlab_modulated))) print("Demodulation correct:", (data == qpsk_demodulate(mod.demodulate(matlab_modulated))[:len(data)]).all())
def benchmark_test(): """ Test the chain through with timing output """ print("Benchmark test") # Options FFT_SIZE = int(2**10) CYCLIC_PREFIX_LEN = 2 # Structures mod = OFDM.OFDMModulator(fft_size=FFT_SIZE, num_cyclic_prefix=CYCLIC_PREFIX_LEN, add_pilot=True) # Generate some bytes to send st = perf_counter() data_orig = np.random.bytes(int(1e7)) print("Generation {:.3f} ms".format(1000 * (perf_counter() - st))) st = perf_counter() data = packed_to_unpacked(data_orig) print("Unpacking {:.3f} ms".format(1000 * (perf_counter() - st))) # Transmitter st = perf_counter() transmit_data = mod.modulate(qpsk_modulate(data)) print("Modulation {:.3f} ms".format(1000 * (perf_counter() - st))) # Receiver st = perf_counter() data_recv = qpsk_demodulate(mod.demodulate(transmit_data)) print("Demodulation {:.3f} ms".format(1000 * (perf_counter() - st))) data_recv = data_recv[:len(data)] st = perf_counter() data_recv_packed = unpacked_to_packed(data_recv) print("Packing {:.3f} ms".format(1000 * (perf_counter() - st))) # print(data_recv_packed) # Decoded! Find BER: bit_error_rate = 1 - (np.frombuffer(data_recv_packed[:len(data_orig)], dtype=np.byte) == np.frombuffer(data_orig, dtype=np.byte)).mean() if bit_error_rate != 0: print("Bit errors! BER:", bit_error_rate) else: print("No bit errors!")
def test_polar_compare_impl_runtime(): K = 400 N = 2048 num_runs = 10000 ### data = np.frombuffer(np.random.bytes(K // 8), dtype=np.uint8) data_bits = np.unpackbits(data) ### polar_data = polar_encode(N, K, data_bits) polar_data_repacked = packed_to_unpacked(np.packbits(polar_data)) polar_data_modulated = qpsk_modulate(polar_data_repacked) polar_channel_LLRs = qpsk_demodulate_soft(polar_data_modulated, 2).flatten() ### st = pc() for _ in range(num_runs): polar_decode_alternate(N, K, polar_channel_LLRs, use_f_approx=False) time_none = (pc() - st) / num_runs st = pc() for _ in range(num_runs): polar_decode_alternate(N, K, polar_channel_LLRs, use_f_approx=True) time_f = (pc() - st) / num_runs st = pc() for _ in range(num_runs): polar_decode_ssc(N, K, polar_channel_LLRs) time_ssc = (pc() - st) / num_runs print(f"Results from timing test, N={N}, K={K}, num_runs={num_runs}") print("None & {:.2f} \\\\".format(1000 * time_none)) print("$F$ approximation & {:.2f} \\\\".format(1000 * time_f)) print("SSC + $F$ approximation & {:.2f}".format(1000 * time_ssc))
add_pilot=False, num_guardbands=(80, 80)) # Insert only symbols in specific subcarriers to create a nice spectrum. # subcarrier_index = np.concatenate((np.arange(-26, -3), np.arange(4, 27))) + 32 # subcarrier_index = np.concatenate((np.arange(-30, 0), np.arange(1, 31))) + 32 # Good looking pattern where the subcarriers are easily visible. # subcarrier_index = np.array([7, 8, 9, 15, 16, 17, 23, 24, 25, 31, 32, 33, 39, 40, 41, 47, 48, 49, 55, 56, 57]) - 6 #bits_split = np.array(np.split(qpsk_modulate(bits_packed), (len(bits_packed) // len(subcarrier_index)))) #bits_padded = np.zeros((len(bits_split), 56), dtype=np.complex) #bits_padded[:, subcarrier_index] = bits_split #bits_padded = np.hstack(bits_padded) # Perform OFDM modulation OFDM_symbols = ofdm_mod.modulate(qpsk_modulate(bits_packed)) # Upsample to FS OFDM_samples = np.zeros(len(OFDM_symbols) * samp_per_symbol, dtype=np.complex) OFDM_samples[::samp_per_symbol] = 1000 * OFDM_symbols * samp_per_symbol IQ_data = np.repeat(OFDM_symbols, samp_per_symbol) # Filter for upsampling # h = signal.firwin(time_bandwidth_product * samp_per_symbol, 1/samp_per_symbol) OFDM_bandwidth = FS / samp_per_symbol # h = signal.firwin(20 * samp_per_symbol, OFDM_bandwidth/2, fs=FS) FILTER_LEN = 31 FILTER_ALPHA = 0.15 upsamp_filter = rrcosfilter(FILTER_LEN, FILTER_ALPHA, samp_per_symbol / FS, FS)
time_bandwidth_product = 4 h = signal.firwin(time_bandwidth_product * samp_per_symb, 1 / samp_per_symb) BPSK_samples_shaped = np.zeros(samp_per_symb * N_bits) BPSK_samples_shaped[::samp_per_symb] = BPSK_symbols BPSK_samples_shaped = signal.fftconvolve(BPSK_samples_shaped, h, mode='same') BPSK_time_series_shaped = BPSK_samples_shaped * carrier_I BPSK_time_series_shaped /= BPSK_time_series_shaped.max() if PLOT_BPSK: plot_response('Binary PSK', t, freq, BPSK_time_series, BPSK_time_series_shaped) # QPSK bits_packed = 2 * bits[::2] + bits[1::2] QPSK_samp_per_symb = 2 * samp_per_symb QPSK_symbols = qpsk_modulate(bits_packed) QPSK_samples = np.repeat(QPSK_symbols, QPSK_samp_per_symb) time_bandwidth_product = 4 h = signal.firwin(time_bandwidth_product * QPSK_samp_per_symb, 1 / QPSK_samp_per_symb) QPSK_samples_shaped = np.zeros(QPSK_samp_per_symb * N_bits // 2, dtype=np.complex) QPSK_samples_shaped[::QPSK_samp_per_symb] = QPSK_symbols * QPSK_samp_per_symb QPSK_samples_shaped = np.convolve(QPSK_samples_shaped, h, mode='same') QPSK_time_series = QPSK_samples.real * carrier_I + QPSK_samples.imag * carrier_Q QPSK_time_series_shaped = QPSK_samples_shaped.real * carrier_I + QPSK_samples_shaped.imag * carrier_Q if PLOT_QPSK: plot_response('Quadrature PSK',
IQ_data_full = np.empty( (num_runs, samp_per_symbol * (symbol_count + len(zc_sequence))), np.complex) for i in range(num_runs): bytes_idx = slice(i * num_databytes, (i + 1) * num_databytes) data = np.frombuffer(data_orig[bytes_idx], dtype=np.uint8) data_bits = np.unpackbits(data) # Encode with a simple (systematic) conv ECC from # data_enc = conv_encode(data, 3, 4, 5) # data_enc = np.concatenate(data_enc) data_polar = polar_encode(polar_size, num_databits, data_bits) data_enc = np.packbits(data_polar) # QPSK modulate data_enc_mod = qpsk_modulate(packed_to_unpacked(data_enc)) # OFDM modulate IQ_data_clean = mod.modulate(data_enc_mod) # Repeat the package to match the size of the transmission window IQ_data_clean = np.tile(IQ_data_clean, (1, num_ofdm_repeats)).ravel() # Upsampling, Polyphase IQ_data = np.zeros(len(IQ_data_clean) * samp_per_symbol, dtype=np.complex) for j in range(samp_per_symbol): IQ_data[j::samp_per_symbol] = np.convolve(IQ_data_clean, h[j], mode='same') # Normalize the power to mean 0 dBm
def test_polar_compare_impl(filename='output/polar_compare_impl.npz'): print("Polar with and without approximation.") num_runs_max = 20000 num_frame_errors = 150 ESNOs = np.arange(-12, -9, 0.25) total_bits = 14400 K = 400 N = 2048 reps = total_bits // N run_types = ["None", "F approx", "SSC + F_approx"] results_BER = np.empty((len(run_types), len(ESNOs))) results_BLER = np.empty((len(run_types), len(ESNOs))) for i, esno in enumerate(ESNOs): print("ESNO", esno) for rt_i, _ in enumerate(run_types): total_errors = 0 total_frame_errors = 0 total_bits = 0 total_frames = 0 for _ in range(num_runs_max): ### data = np.frombuffer(np.random.bytes(K // 8), dtype=np.uint8) data_bits = np.unpackbits(data) ### polar_data = np.tile(polar_encode(N, K, data_bits), reps) polar_data_repacked = packed_to_unpacked( np.packbits(polar_data)) polar_data_modulated = qpsk_modulate(polar_data_repacked) ### polar_coded = channel_AWGN(polar_data_modulated, esno) ###### polar_reshaped = polar_coded.reshape((reps, -1)) polar_channel_LLRs = qpsk_demodulate_soft(polar_reshaped, esno) ##### mean_LLRs = polar_channel_LLRs.mean(axis=0).flatten() if rt_i == 0: polar_result = polar_decode_alternate(N, K, mean_LLRs, use_f_approx=False) elif rt_i == 1: polar_result = polar_decode_alternate(N, K, mean_LLRs, use_f_approx=True) elif rt_i == 2: polar_result = polar_decode_ssc(N, K, mean_LLRs) ###### errors = (polar_result != data_bits) total_errors += errors.sum() total_frame_errors += errors.any() total_bits += K total_frames += 1 if total_frame_errors >= num_frame_errors: break else: print("Timeout at {} dB".format(esno)) results_BER[rt_i, i] = total_errors / total_bits results_BLER[rt_i, i] = total_frame_errors / total_frames np.savez(filename, N=N, K=K, repeats=reps, ESNOs=ESNOs, results_BER=results_BER, results_BLER=results_BLER, legend=run_types, config={ 'num_runs_max': num_runs_max, 'num_frame_errors': num_frame_errors, 'total_bits': total_bits })
def test_polar_soft_combine(filename='output/polar_soft_combine.npz'): print("Polar compare post- vs pre-combining.") num_runs_max = 50000 num_frame_errors = 100 ESNOs = np.arange(-12, -9, 0.25) total_bits = 14400 K = 400 Ns = np.array([2048, 2048, 4096, 4096]) repeats = (total_bits / Ns).astype(int) results_BER = np.empty((len(repeats), len(ESNOs))) results_BLER = np.empty((len(repeats), len(ESNOs))) for i, esno in enumerate(ESNOs): print("ESNO", esno) for n_rep in range(len(repeats)): total_errors = 0 total_frame_errors = 0 total_bits = 0 total_frames = 0 for _ in range(num_runs_max): ### data = np.frombuffer(np.random.bytes(K // 8), dtype=np.uint8) data_bits = np.unpackbits(data) ### polar_data = np.tile(polar_encode(Ns[n_rep], K, data_bits), repeats[n_rep]) polar_data_repacked = packed_to_unpacked( np.packbits(polar_data)) polar_data_modulated = qpsk_modulate(polar_data_repacked) ### polar_coded = channel_AWGN(polar_data_modulated, esno) ###### polar_reshaped = polar_coded.reshape((repeats[n_rep], -1)) polar_channel_LLRs = qpsk_demodulate_soft(polar_reshaped, esno) ##### if n_rep % 1 == 0: polar_result = polar_decode_ssc( Ns[n_rep], K, polar_channel_LLRs.mean(axis=0).flatten()) ###### else: polar_results_soft_all = np.empty((repeats[n_rep], K)) for j in range(len(polar_channel_LLRs)): polar_results_soft_all[j] = polar_decode_ssc( Ns[n_rep], K, polar_channel_LLRs[j], soft_output=True) polar_result = polar_results_soft_all.mean(axis=0) ###### errors = (polar_result != data_bits) total_errors += errors.sum() total_frame_errors += errors.any() total_bits += K total_frames += 1 if total_frame_errors >= num_frame_errors: break else: print("Timeout at {} dB".format(esno)) results_BER[n_rep, i] = total_errors / total_bits results_BLER[n_rep, i] = total_frame_errors / total_frames np.savez(filename, N=Ns, K=K, repeats=repeats, ESNOs=ESNOs, results_BER=results_BER, results_BLER=results_BLER, legend=[ "Hard combine", "Soft combine", "Hard combine", "Soft combine" ], config={ 'num_runs_max': num_runs_max, 'num_frame_errors': num_frame_errors, 'total_bits': total_bits })
def test_polar_rate_vs_rep(filename='output/polar_rates_vs_rep.npz'): num_runs_max = 50000 num_frame_errors = 100 ESNOs = np.arange(-12, -6, 0.25) total_bits = 14400 K = 400 Ns = 2**(np.arange(9, 14)) repeats = (total_bits / Ns).astype(int) results_BER = np.empty((len(repeats), len(ESNOs))) results_BLER = np.empty((len(repeats), len(ESNOs))) for i, esno in enumerate(ESNOs): print("ESNO", esno) for n_rep in range(len(repeats)): total_errors = 0 total_frame_errors = 0 total_bits = 0 total_frames = 0 for _ in range(num_runs_max): ### data = np.frombuffer(np.random.bytes(K // 8), dtype=np.uint8) data_bits = np.unpackbits(data) ### polar_data = np.tile(polar_encode(Ns[n_rep], K, data_bits), repeats[n_rep]) polar_data_repacked = packed_to_unpacked( np.packbits(polar_data)) polar_data_modulated = qpsk_modulate(polar_data_repacked) ### polar_coded = channel_AWGN(polar_data_modulated, esno) ### polar_reshaped = polar_coded.reshape((repeats[n_rep], -1)) polar_channel_LLRs = np.mean(qpsk_demodulate_soft( polar_reshaped, esno), axis=0) polar_result = polar_decode_ssc(Ns[n_rep], K, polar_channel_LLRs.flatten()) ### errors = (polar_result != data_bits) total_errors += errors.sum() total_frame_errors += errors.any() total_bits += K total_frames += 1 if total_frame_errors >= num_frame_errors: break else: print("Timeout at {} dB".format(esno)) results_BER[n_rep, i] = total_errors / total_bits results_BLER[n_rep, i] = total_frame_errors / total_frames np.savez(filename, N=Ns, K=K, repeats=repeats, ESNOs=ESNOs, results_BER=results_BER, results_BLER=results_BLER, legend=[f"N: {Ns[i]}, Rep: {repeats[i]}" for i in range(len(Ns))], config={ 'num_runs_max': num_runs_max, 'num_frame_errors': num_frame_errors, 'total_bits': total_bits, })
def test_polar_combining(K=32, repetitions=2, plot=False): num_runs = 100 ESNOs = np.arange(-13, -2, 0.5) # First just repeating and combining soft LLRs # Then a rate 1/2 code, repeated a number of times # Then polar code with the lowest rate possible results_uncoded_BER = np.empty((num_runs, len(ESNOs))) results_uncoded_BLER = np.empty((num_runs, len(ESNOs))) results_rate_half_BER = np.empty((num_runs, len(ESNOs))) results_rate_half_BLER = np.empty((num_runs, len(ESNOs))) results_rate_min_BER = np.empty((num_runs, len(ESNOs))) results_rate_min_BLER = np.empty((num_runs, len(ESNOs))) for n_run in range(num_runs): if num_runs > 10 and n_run % (num_runs // 10) == 0: print(n_run) # Generate data data = np.frombuffer(np.random.bytes(K // 8), dtype=np.uint8) data_bits = np.unpackbits(data) # Match N uncoded_data = np.tile(data_bits, (2 * repetitions)) polar_rate_half = np.tile(polar_encode(2 * K, K, data_bits), repetitions) polar_rate_min = polar_encode(repetitions * 2 * K, K, data_bits) # Pack uncoded_repacked = packed_to_unpacked(np.packbits(uncoded_data)) polar_rate_half_repacked = packed_to_unpacked( np.packbits(polar_rate_half)) polar_rate_min_repacked = packed_to_unpacked( np.packbits(polar_rate_min)) # Modulate uncoded_modulated = qpsk_modulate(uncoded_repacked) polar_rate_half_modulated = qpsk_modulate(polar_rate_half_repacked) polar_rate_min_modulated = qpsk_modulate(polar_rate_min_repacked) for i, esno in enumerate(ESNOs): # print("{}: esno {}".format(i, esno)) uncoded_channel = channel_AWGN(uncoded_modulated, esno) uncoded_reshaped = uncoded_channel.reshape((-1, K // 2)) uncoded_channel_LLRs = np.mean(qpsk_demodulate_soft( uncoded_reshaped, esno), axis=0) uncoded_bits = np.unpackbits( unpacked_to_packed(qpsk_hard_decision(uncoded_channel_LLRs))) results_uncoded_BER[n_run, i] = (uncoded_bits != data_bits).mean() results_uncoded_BLER[n_run, i] = (uncoded_bits != data_bits).any() ### polar_rate_half_channel = channel_AWGN(polar_rate_half_modulated, esno) polar_rate_half_reshaped = polar_rate_half_channel.reshape((-1, K)) polar_rate_half_channel_LLRs = np.mean(qpsk_demodulate_soft( polar_rate_half_reshaped, esno), axis=0) polar_result_rate_half = polar_decode_ssc( 2 * K, K, polar_rate_half_channel_LLRs.flatten()) results_rate_half_BER[n_run, i] = (polar_result_rate_half != data_bits).mean() results_rate_half_BLER[n_run, i] = (polar_result_rate_half != data_bits).any() ### polar_rate_min_channel = channel_AWGN(polar_rate_min_modulated, esno) polar_rate_min_demod = qpsk_demodulate_soft( polar_rate_min_channel, esno).flatten() polar_result_rate_min = polar_decode_ssc(repetitions * 2 * K, K, polar_rate_min_demod) results_rate_min_BER[n_run, i] = (polar_result_rate_min != data_bits).mean() results_rate_min_BLER[n_run, i] = (polar_result_rate_min != data_bits).any() if plot: ### plt.figure("Polar BER test") plt.title( f"Comparison of different rate polar codes, QPSK, AWGN channel, K={K}" ) plt.plot(ESNOs, results_uncoded_BER.mean(axis=0), label=f'Repetition code R = 1 / {1/(2*repetitions)}') plt.plot( ESNOs, results_rate_half_BER.mean(axis=0), label= f'Polar code (SC decoder) R = 1 / {1/2}, repeated = {repetitions}') plt.plot(ESNOs, results_rate_min_BER.mean(axis=0), label=f'Polar code (SC decoder) R = 1 / {1/(2*repetitions)}') plt.ylabel("BER") plt.yscale('log') plt.legend() ### plt.figure("Polar BLER test") plt.title( f"Comparison of different rate polar codes, QPSK, AWGN channel, K={K}" ) plt.plot(ESNOs, results_uncoded_BLER.mean(axis=0), label=f'Repetition code R = 1 / {1/(2*repetitions)}') plt.plot( ESNOs, results_rate_half_BLER.mean(axis=0), label= f'Polar code (SC decoder) R = 1 / {1/2}, repeated = {repetitions}') plt.plot(ESNOs, results_rate_min_BLER.mean(axis=0), label=f'Polar code (SC decoder) R = 1 / {1/(2*repetitions)}') plt.xlabel("ESNO") plt.ylabel("BLER") plt.yscale('log') plt.legend() ### plt.show()
def test_polar_rates(filename='output/polar_various_rates.npz'): print("Polar compare performance at different rates") num_runs_max = 1000 num_frame_errors = 100 ESNOs = np.arange(-11, 3, 0.5) rates = 1 / np.array([2, 3, 5, 10, 16, 20.48]) N = 2**13 K = (N * rates).astype(int) results_BER = np.empty((len(rates), len(ESNOs))) results_BLER = np.empty((len(rates), len(ESNOs))) for i, esno in enumerate(ESNOs): print("ESNO", esno) for K_i, cur_K in enumerate(K): total_errors = 0 total_frame_errors = 0 total_bits = 0 total_frames = 0 for _ in range(num_runs_max): data_bits = np.random.binomial(1, 0.5, cur_K).astype(np.uint8) polar_data = polar_encode(N, cur_K, data_bits) polar_data_repacked = packed_to_unpacked( np.packbits(polar_data)) polar_data_modulated = qpsk_modulate(polar_data_repacked) polar_coded = channel_AWGN(polar_data_modulated, esno) polar_coded_demod_soft = qpsk_demodulate_soft( polar_coded, esno).flatten() polar_result = polar_decode_ssc(N, cur_K, polar_coded_demod_soft) ###### errors = (polar_result != data_bits) total_errors += errors.sum() total_frame_errors += errors.any() total_bits += cur_K total_frames += 1 if total_frame_errors >= num_frame_errors: break else: print("Timeout at {} dB".format(esno)) results_BER[K_i, i] = total_errors / total_bits results_BLER[K_i, i] = total_frame_errors / total_frames np.savez(filename, N=N, K=K, ESNOs=ESNOs, results_BER=results_BER, results_BLER=results_BLER, legend=[f"Rate: {r}" for r in rates], config={ 'num_runs_max': num_runs_max, 'num_frame_errors': num_frame_errors, 'total_bits': total_bits, })
def test_BER(filename='output/BER_compare.npz', enable_conv=False): num_runs_max = 20000 num_frame_errors = 150 ESNOs = np.arange(-1, 10, 0.25) N = 2**13 K = N // 2 types = [ "Uncoded", "Repetition code (Hard)", "Repetition code (Soft)", "Polar code" ] if enable_conv: conv_params = (3, 7, 5) types += "Convolutional code" N_types = len(types) results_BER = np.empty((N_types, len(ESNOs))) results_BLER = np.empty((N_types, len(ESNOs))) if enable_conv: conv_params = (3, 7, 5) for i, esno in enumerate(ESNOs): print("ESNO", esno) # A counter for the total number of frame errors, so we can stop when some of the # schemes have reached their limit. total_frame_errors = np.zeros(N_types, np.int) total_bit_errors = np.zeros(N_types, np.int) total_frames = np.zeros(N_types, np.int) total_bits = np.zeros(N_types, np.int) for _ in range(num_runs_max): data = np.frombuffer(np.random.bytes(K // 8), dtype=np.uint8) data_unpacked = packed_to_unpacked(data) data_bits = np.unpackbits(data) ### if total_frame_errors[0] < num_frame_errors: data_modulated = qpsk_modulate(data_unpacked) uncoded = channel_AWGN(data_modulated, esno) uncoded_bits = np.unpackbits( unpacked_to_packed(qpsk_demodulate(uncoded))) total_frame_errors[0] += (uncoded_bits != data_bits).any() total_bit_errors[0] += np.count_nonzero( uncoded_bits != data_bits) total_frames[0] += 1 total_bits[0] += K ### if (total_frame_errors[1] < num_frame_errors) and ( total_frame_errors[2] < num_frame_errors): rep_modulated = np.tile(data_modulated, (1, 2)).ravel() rep_coded = channel_AWGN(rep_modulated, esno) rep_coded_reshaped = rep_coded.reshape((-1, len(uncoded))) rep_coded_hard = np.array([1, 2], np.uint8) @ (np.stack( (rep_coded_reshaped.real < 0, rep_coded_reshaped.imag < 0)).sum(axis=1) >= 1) rep_coded_hard_bits = np.unpackbits( unpacked_to_packed(rep_coded_hard)) rep_coded_LLRs = np.roll(qpsk_demodulate_soft( rep_coded_reshaped, esno).mean(axis=0), 1, axis=1) rep_coded_soft_bits = np.unpackbits( unpacked_to_packed(qpsk_hard_decision(rep_coded_LLRs))) total_frame_errors[1] += (rep_coded_hard_bits != data_bits).any() total_bit_errors[1] += np.count_nonzero( rep_coded_hard_bits != data_bits) total_frame_errors[2] += (rep_coded_soft_bits != data_bits).any() total_bit_errors[2] += np.count_nonzero( rep_coded_soft_bits != data_bits) total_frames[1:3] += 1 total_bits[1:3] += K ### if total_frame_errors[3] < num_frame_errors: polar_data = polar_encode(N, K, data_bits) polar_data_repacked = packed_to_unpacked( np.packbits(polar_data)) polar_data_modulated = qpsk_modulate(polar_data_repacked) polar_coded = channel_AWGN(polar_data_modulated, esno) polar_coded_demod_soft = qpsk_demodulate_soft( polar_coded, esno).flatten() polar_result = polar_decode_ssc(N, K, polar_coded_demod_soft) total_frame_errors[3] += (polar_result != data_bits).any() total_bit_errors[3] += np.count_nonzero( polar_result != data_bits) total_frames[3] += 1 total_bits[3] += K ### if enable_conv and total_frame_errors[4] < num_frame_errors: conv_data = conv_encode(data, *conv_params) conv_data_modulated = qpsk_modulate( packed_to_unpacked(conv_data)) conv_coded = channel_AWGN(conv_data_modulated, esno) conv_coded_demod = np.frombuffer(unpacked_to_packed( qpsk_demodulate(conv_coded)), dtype=np.uint8) conv_decoded = conv_decode(conv_coded_demod[::2], conv_coded_demod[1::2], *conv_params) total_frame_errors[4] += (np.unpackbits(conv_decoded) != data_bits).any() total_bit_errors[4] += np.count_nonzero( np.unpackbits(conv_decoded) != data_bits) total_frames[4] += 1 total_bits[4] += K results_BER[:, i] = total_bit_errors / total_bits results_BLER[:, i] = total_frame_errors / total_frames qfunc = lambda x: 0.5 * erfc(x / np.sqrt(2)) expected_uncoded_BER = qfunc(np.sqrt(10**(ESNOs / 10))) np.savez(filename, N=N, K=K, ESNOs=ESNOs, results_BER=results_BER, results_BLER=results_BLER, expected_BER_uncoded=expected_uncoded_BER, legend=types, config={ 'num_runs_max': num_runs_max, 'num_frame_errors': num_frame_errors, })
def test_polar_limit(filename='output/polar_limit_rate05_nossc.npz'): num_runs_max = 20000 num_frame_errors = 100 ESNOs = np.arange(-1, 5, 0.25) SEED = 456 N = 8192 K = 4096 np.random.seed(SEED) results_BER = np.empty((len(ESNOs))) results_BLER = np.empty((len(ESNOs))) results_frame_errors = np.empty((len(ESNOs))) for i, esno in enumerate(ESNOs): print("ESNO", esno) total_errors = 0 total_frame_errors = 0 total_bits = 0 total_frames = 0 for _ in range(num_runs_max): ### data = np.frombuffer(np.random.bytes(K // 8), dtype=np.uint8) data_bits = np.unpackbits(data) ### polar_data = polar_encode(N, K, data_bits) polar_data_repacked = packed_to_unpacked(np.packbits(polar_data)) polar_data_modulated = qpsk_modulate(polar_data_repacked) ### polar_coded = channel_AWGN(polar_data_modulated, esno) ### polar_coded_demod_soft = qpsk_demodulate_soft(polar_coded, esno).flatten() # polar_result = polar_decode_ssc(N, K, polar_coded_demod_soft) polar_result = polar_decode_alternate(N, K, polar_coded_demod_soft, use_f_approx=False) ### errors = (polar_result != data_bits) total_errors += errors.sum() total_frame_errors += errors.any() total_frames += 1 total_bits += len(data_bits) if total_frame_errors >= num_frame_errors: break else: print("Timeout at {} dB".format(esno)) results_BER[i] = total_errors / total_bits results_BLER[i] = total_frame_errors / total_frames results_frame_errors[i] = total_frame_errors #% Save file config = { "seed": SEED, "num_runs": num_runs_max, "ESNOs": ESNOs, "Time": datetime.now(), 'num_runs_max': num_runs_max, 'num_frame_errors_max': num_frame_errors } np.savez(filename, N=N, K=K, ESNOs=ESNOs, results_BER=results_BER, results_BLER=results_BLER, frame_errors=results_frame_errors, config=config)