def get_Hlist(self):
        # Np array to store `FFT_size` number of Nt*Nr channels
        chan_freq = np.zeros(shape=(self.fft_size, self.Nt, self.Nr),
                             dtype=complex)
        # Initialise the matrices
        for i in range(self.Nt * self.Nr):
            col_idx = i % self.Nr
            row_idx = i // self.Nr
            freq_resp = itpp.cmat()
            inp_resp = itpp.cmat()
            #Get Impulse Response
            inp_resp.set_size(1, self.channel_length, False)
            inp_resp.set_row(0, self.channel.get_row(i))
            # print(inp_resp)
            #Calculate Frequency Response for each Nt*Nr channel (64 length array)
            self.tdl_channels[i].calc_frequency_response(
                inp_resp, freq_resp, 2 * self.fft_size)
            # Store it in chan_freq in appropriate places across 64 matrices
            # print(freq_resp.to_numpy_ndarray().flatten()[0:64]-freq_resp.to_numpy_ndarray().flatten()[64:128])
            chan_freq[:, row_idx][:, col_idx] = freq_resp.to_numpy_ndarray(
            ).flatten()[0:self.fft_size]

        chan_freq_list = []
        for i in range(self.fft_size):
            chan_freq_list.append(chan_freq[i])
        #print(chan_freq_list[0])
        return (chan_freq_list)
def channel_frequency_response(fft_size,
                               relative_speed,
                               channel_model,
                               nrof_subframes):
    
    carrier_freq = 2.0e9 # 2 GHz
    subcarrier_spacing = 15000 # Hz
    
    sampling_frequency = subcarrier_spacing * fft_size
    sampling_interval = 1.0 / sampling_frequency

    relative_speed = relative_speed # in m/s
    doppler_frequency = (carrier_freq / 3e8) * relative_speed
    norm_doppler = doppler_frequency * sampling_interval

    frame_duration = 1.0e-3 # 1 ms
    frame_samples = int(frame_duration / sampling_interval)
    
    model = None
    if channel_model == 'ITU_PEDESTRIAN_A':
        model = itpp.comm.CHANNEL_PROFILE.ITU_Pedestrian_A
    elif channel_model == 'ITU_PEDESTRIAN_B':
        model = itpp.comm.CHANNEL_PROFILE.ITU_Pedestrian_B
    elif channel_model == 'ITU_VEHICULAR_A':
        model = itpp.comm.CHANNEL_PROFILE.ITU_Vehicular_A
    elif channel_model == 'ITU_VEHICULAR_B':
        model = itpp.comm.CHANNEL_PROFILE.ITU_Vehicular_B
    else:
        print('Specified channel model %s not configured in %s'%(model, __file__))

    channel_spec = itpp.comm.Channel_Specification(model)
    channel = itpp.comm.TDL_Channel(channel_spec, sampling_interval)
    
    nrof_taps = channel.taps()
        
    channel.set_norm_doppler(norm_doppler)
    
    # Generate channel coefficients for a few frames
    channel_coeff = itpp.cmat()
    channel_coeff.set_size(nrof_subframes, nrof_taps, False)
    
    for frame_index in range(nrof_subframes):
        frame_start_sample = int(frame_index * frame_samples)
        channel.set_time_offset(frame_start_sample)
        frame_channel_coeff = itpp.cmat()
        channel.generate(1, frame_channel_coeff)
        channel_coeff.set_row(frame_index, frame_channel_coeff.get_row(0))
        
    freq_resp = itpp.cmat()
    channel.calc_frequency_response(channel_coeff, freq_resp, fft_size)
    
    return freq_resp
def calculate_channel_frequency_response(channel, subframe_index, nrof_resource_blocks=CONFIG.NROF_TOTAL_PRBS):
    channel_impulse_response = itpp.cmat() 
    channel_frequency_response = itpp.cmat()

    nrof_offset_samples = int(subframe_index * CONFIG.SUBFRAME_DURATION / CONFIG.SAMPLING_INTERVAL)
    channel.set_time_offset(nrof_offset_samples)
    
    # Generate channel samples. Each channel sample is shifted by the transmission duration
    channel.generate(1, channel_impulse_response)
    
    channel.calc_frequency_response(channel_impulse_response, channel_frequency_response, CONFIG.SUBCARRIERS_PER_PRB * nrof_resource_blocks)
    
    channel_coefficients = channel_frequency_response.get_col(0)
    
    return channel_coefficients
예제 #4
0
def simluate_rayleigh_fading_channel(nrof_samples,
                                     avg_snr_dB,
                                     awgn_data,
                                     packet_sizes,
                                     norm_doppler=0.01,
                                     seed=9999,
                                     cqi_error_std=0.0):

    # Create a Rayleigh fading channel. The channel power is normalized to 1 by default
    channel = itpp.comm.TDL_Channel(itpp.vec('0.0'), itpp.ivec('0'))
    channel.set_norm_doppler(norm_doppler)

    channel_coeff_itpp = itpp.cmat()
    channel.generate(nrof_samples, channel_coeff_itpp)

    channel_coeff = np.array(channel_coeff_itpp.get_col(0))

    avg_snr = 10**(0.1 * avg_snr_dB)
    instantaneous_channel_snrs = (np.absolute(channel_coeff)**2) * avg_snr

    _, nrof_rates = awgn_data['snr_vs_per'].shape
    instantaneous_blers = []
    channel_quality_indices = []
    for i in range(nrof_samples):
        cqi_sinr_error = (itpp.random.randn() - 0.5) * cqi_error_std

        snr_dB = 10 * np.log10(instantaneous_channel_snrs[i])
        instantaneous_blers.append(determine_bler_at_sinr(snr_dB, awgn_data))
        channel_quality_indices.append(
            determine_cqi_from_sinr(snr_dB, packet_sizes, awgn_data,
                                    cqi_sinr_error))

    return (np.array(instantaneous_blers), np.array(channel_quality_indices))
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 generate(self):
     # Declare a CMAT channel matrix of Nt*Nr size
     self.channel = itpp.cmat()
     self.channel.set_size(self.Nt * self.Nr, self.channel_length, False)
     # Declare another temp CMAT
     channel_coef_one = itpp.cmat()
     # Initialise the matrix element wise
     for i in range(self.Nt):
         for j in range(self.Nr):
             # Generate "1" sample values of the channel,
             # channel_coef_one has one tap per column
             self.tdl_channels[i * self.Nr + j].generate(
                 1, channel_coef_one)
             for l in range(self.channel_length):
                 self.channel.set(i * self.Nr + j, l,
                                  channel_coef_one(0, l))
예제 #7
0
def multiplex_symbols(nrof_ofdm_symbols_per_frame, nrof_subcarriers,
                      constellation_symbols):

    nrof_frames = int(constellation_symbols.length() /
                      (nrof_subcarriers * nrof_ofdm_symbols_per_frame))
    frame_symbols = cmat(nrof_subcarriers * nrof_ofdm_symbols_per_frame,
                         nrof_frames)
    frame_symbols.clear()

    # Pre-allocate vector to store frame symbols for efficiency
    current_frame_symbols = cvec(nrof_subcarriers *
                                 nrof_ofdm_symbols_per_frame)
    for frame_index in range(nrof_frames):
        current_frame_symbols.clear()
        for ofdm_symbol_index in range(nrof_ofdm_symbols_per_frame):
            read_index = frame_index * nrof_subcarriers * nrof_ofdm_symbols_per_frame + ofdm_symbol_index * nrof_subcarriers
            current_frame_symbols.set_subvector(
                ofdm_symbol_index * nrof_subcarriers, (nrof_subcarriers**0.5) *
                ifft(constellation_symbols.mid(read_index, nrof_subcarriers)))

        frame_symbols.set_col(frame_index, current_frame_symbols)

    return frame_symbols
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)