def propagate_transmit_bits_over_channel(transmit_bits, modulation_order, nrof_resource_blocks, channel_coefficients, noise_variance): nrof_constellation_symbols = int(itpp.math.pow2(modulation_order)) modulator = itpp.comm.QAM(nrof_constellation_symbols) nrof_subcarriers = nrof_resource_blocks * CONFIG.SUBCARRIERS_PER_PRB nrof_symbols = CONFIG.NROF_OFDM_SYMBOLS_PER_SUBFRAME modulated_symbols = modulator.modulate_bits(transmit_bits) if (modulated_symbols.length() != nrof_subcarriers * nrof_symbols): print('Mismatched number of modulated symbols: %d and resource elements: %d'%(modulated_symbols.length(), nrof_subcarriers * nrof_symbols)) ofdm_symbols = itpp.cmat(nrof_subcarriers, nrof_symbols) for i in range(nrof_symbols): temp = modulated_symbols.mid(i * nrof_subcarriers, nrof_subcarriers) ofdm_symbols.set_col(i, itpp.signal.ifft(temp, nrof_subcarriers))#.left(nrof_subcarriers)) noise = itpp.randn_c(nrof_subcarriers, nrof_symbols) * (0.5 * itpp.math.sqrt(noise_variance)) block_channel_coefficients = itpp.repmat(channel_coefficients, 1, nrof_symbols, True) received_symbols = itpp.elem_mult_mat(ofdm_symbols, block_channel_coefficients) + noise compensated_symbols = itpp.elem_div_mat(received_symbols, block_channel_coefficients) # Receiver processing demultiplexed_symbols = itpp.cvec(nrof_subcarriers * nrof_symbols) for i in range(nrof_symbols): temp = compensated_symbols.get_col(i) demultiplexed_symbols.set_subvector(i * nrof_subcarriers, itpp.signal.fft(temp, nrof_subcarriers))#.left(nrof_subcarriers)) # receive_soft_values = modulator.demodulate_soft_bits(demultiplexed_symbols, channel_coefficients, noise_variance, itpp.comm.Soft_Method.LOGMAP) receive_soft_values = modulator.demodulate_soft_bits(demultiplexed_symbols, noise_variance, itpp.comm.Soft_Method.LOGMAP) return receive_soft_values
def block_error_ratio_hamming_awgn(snr_db, block_size): mapping_k_m = { 4: 3 } # Mapping from k (block size) to m. m = 3 implies (7,4) code m = mapping_k_m[block_size] '''Hamming encoder and decoder instance''' hamm = itpp.comm.hamming_code(m) n = pow(2, m) - 1 # channel use rate = float(block_size) / float(n) '''Generate random bits''' nrof_bits = 10000 * block_size source_bits = itpp.randb(nrof_bits) '''Encode the bits''' encoded_bits = hamm.encode(source_bits) '''Modulate the bits''' modulator_ = itpp.comm.modulator_2d() constellation = itpp.cvec('-1+0i, 1+0i') symbols = itpp.ivec('0, 1') modulator_.set(constellation, symbols) tx_signal = modulator_.modulate_bits(encoded_bits) '''Add the effect of channel to the signal''' noise_variance = 1.0 / (rate * pow(10, 0.1 * snr_db)) noise = itpp.randn_c(tx_signal.length()) noise *= itpp.math.sqrt(noise_variance) rx_signal = tx_signal + noise '''Demodulate the signal''' demodulated_bits = modulator_.demodulate_bits(rx_signal) '''Decode the received bits''' decoded_bits = hamm.decode(demodulated_bits) '''Calculate the block error ratio''' blerc = itpp.comm.BLERC(block_size) blerc.count(source_bits, decoded_bits) return blerc.get_errorrate()
def block_error_ratio_uncoded_awgn(snr_db, block_size): '''Generate random bits''' nrof_bits = 3 * 10000 * block_size source_bits = itpp.randb(nrof_bits) rate = 1.0 '''Modulate the bits''' modulator_ = itpp.comm.modulator_2d() constellation = itpp.cvec('-1+0i, 1+0i') symbols = itpp.ivec('0, 1') modulator_.set(constellation, symbols) tx_signal = modulator_.modulate_bits(source_bits) '''Add the effect of channel to the signal''' noise_variance = 1.0 / (rate * pow(10, 0.1 * snr_db)) noise = itpp.randn_c(tx_signal.length()) noise *= itpp.math.sqrt(noise_variance) rx_signal = tx_signal + noise '''Demodulate the signal''' demodulated_bits = modulator_.demodulate_bits(rx_signal) '''Calculate the block error ratio''' blerc = itpp.comm.BLERC(block_size) blerc.count(source_bits, demodulated_bits) return blerc.get_errorrate()
def simulate(transport_block_size, modorder, nrof_subcarriers, snr_db, channel_coeff_freq_domain_np): channel_coeff_freq_domain_str = ';'.join([ ' '.join([ str(c).replace('j', 'i').replace('(', '').replace(')', '') for c in r ]) for r in channel_coeff_freq_domain_np ]) channel_coeff_freq_domain = itpp.cmat(channel_coeff_freq_domain_str) nrof_subframe_ofdm_symbols = 12 #--------- TRANSMITTER PROCESSING ---------- # Generate random transmit bits for subframe nrof_frames = channel_coeff_freq_domain.cols() info_bits_uncoded = itpp.random.randb( transport_block_size * nrof_frames) # bmat[block_size, nrof_samples] # Channel encode the transmit data bits info_bits_encoded = codec.encode(transport_block_size, info_bits_uncoded) encoded_block_size = int(info_bits_encoded.length() / nrof_frames) interleaver_bin = itpp.comm.sequence_interleaver_bin(encoded_block_size) interleaver_bin.randomize_interleaver_sequence() interleaver_double = itpp.comm.sequence_interleaver_double( encoded_block_size) interleaver_double.set_interleaver_sequence( interleaver_bin.get_interleaver_sequence()) info_bits_interleaved = interleaver_bin.interleave(info_bits_encoded) # Rate match the encoded bits transmit_block_size = int(nrof_subcarriers * nrof_subframe_ofdm_symbols * modorder) info_bits_rate_matched = codec.rate_match( transmit_block_size, encoded_block_size)(info_bits_interleaved) # Modulate the rate matched bits info_symbols_modulated = modem.modulate_bits(modorder, info_bits_rate_matched) # Obtain the OFDM frequency-domain signal transmit_signal_freq_domain = ofdm.multiplex_symbols( nrof_subframe_ofdm_symbols, nrof_subcarriers, info_symbols_modulated) #--------- CHANNEL EFFECTS ---------- # Apply the channel to the transmitted signal received_signal_freq_domain = itpp.elem_mult_mat( transmit_signal_freq_domain, channel_coeff_freq_domain) # Add receiver noise noise_std_dev = np.sqrt( 1.0 / pow(10, 0.1 * snr_db)) # Signal and channel power is normalized to 1 received_signal_freq_domain_noisy = received_signal_freq_domain + noise_std_dev * itpp.randn_c( received_signal_freq_domain.rows(), received_signal_freq_domain.cols()) #--------- RECEIVER PROCESSING ---------- # Remove the effect of channel received_signal_freq_domain_compensated = itpp.elem_div_mat( received_signal_freq_domain_noisy, channel_coeff_freq_domain) # Obtain the time-domain symbols received_symbols_modulated = ofdm.de_multiplex_symbols( nrof_subframe_ofdm_symbols, nrof_subcarriers, received_signal_freq_domain_compensated) # Demodulate the received symbols according to the modulation order received_soft_values = modem.demodulate_soft_values( modorder, noise_std_dev * noise_std_dev, received_symbols_modulated) # De-rate match the received soft values received_soft_values_de_rate_matched = codec.de_rate_match( transmit_block_size, encoded_block_size)(received_soft_values) received_soft_values_deinterleaved = interleaver_double.deinterleave( received_soft_values_de_rate_matched, 0) # Channel decode the data bits according to the code rate received_bits_decoded = codec.decode(transport_block_size, received_soft_values_deinterleaved) # Count block errors bler, block_success = error_counter(info_bits_uncoded, received_bits_decoded, transport_block_size) # print 'bler', bler logging.info('SNR:%0.2f dB, BLER: %0.4f' % (snr_db, bler)) # channel_to_noise_ratio = channel_coeff_freq_domain.elem_div(noise_realization) return (bler, block_success)