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()
Beispiel #3
0
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)