Example #1
0
def main():
    # session = bp.Session(load_from_config=False)
    # bp.output_server(docname='simple_precoded_srs_AN1', session=session)
    bp.output_file('simple_precoded_srs.html', title="Simple Precoded SRS")

    # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
    # xxxxxxxxxxxxxxx Scenario Description xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
    # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
    # 3 Base Stations, each sending data to its own user while interfering
    # with the other users.

    # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
    # xxxxxxxxxxxxxxx Configuration xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
    # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
    num_prbs = 25  # Number of PRBs to simulate
    Nsc = 12 * num_prbs  # Number of subcarriers
    Nzc = 149  # Size of the sequence
    u1 = 1  # Root sequence index of the first user
    u2 = 2  # Root sequence index of the first user
    u3 = 3  # Root sequence index of the first user
    numAnAnt = 4  # Number of Base station antennas
    numUeAnt = 2  # Number of UE antennas

    num_samples = 1  # Number of simulated channel samples (from
    # Jakes process)

    # Channel configuration
    speedTerminal = 0 / 3.6  # Speed in m/s
    fcDbl = 2.6e9  # Central carrier frequency (in Hz)
    timeTTIDbl = 1e-3  # Time of a single TTI
    subcarrierBandDbl = 15e3  # Subcarrier bandwidth (in Hz)
    numOfSubcarriersPRBInt = 12  # Number of subcarriers in each PRB
    L = 16  # The number of rays for the Jakes model.

    # Dependent parameters
    lambdaDbl = 3e8 / fcDbl  # Carrier wave length
    Fd = speedTerminal / lambdaDbl  # Doppler Frequency
    Ts = 1. / (Nsc * subcarrierBandDbl)  # Sampling time

    # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
    # xxxxxxxxxxxxxxx Generate the root sequence xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
    # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
    a_u1 = get_extended_ZF(calcBaseZC(Nzc, u1), Nsc / 2)
    a_u2 = get_extended_ZF(calcBaseZC(Nzc, u2), Nsc / 2)
    a_u3 = get_extended_ZF(calcBaseZC(Nzc, u3), Nsc / 2)

    print("Nsc: {0}".format(Nsc))
    print("a_u.shape: {0}".format(a_u1.shape))

    # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
    # xxxxxxxxxxxxxxx Create shifted sequences for 3 users xxxxxxxxxxxxxxxxxxxx
    # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
    # We arbitrarily choose some cyclic shift index and then we call
    # zadoffchu.get_srs_seq to get the shifted sequence.
    shift_index = 4
    r1 = get_srs_seq(a_u1, shift_index)
    r2 = get_srs_seq(a_u2, shift_index)
    r3 = get_srs_seq(a_u3, shift_index)

    # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
    # xxxxxxxxxxxxxxx Generate channels from users to the BS xxxxxxxxxxxxxx
    # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
    jakes_all_links = np.empty([3, 3], dtype=object)
    tdlchannels_all_links = np.empty([3, 3], dtype=object)
    impulse_responses = np.empty([3, 3], dtype=object)
    # Dimension: `UEs x ANs x num_subcarriers x numUeAnt x numAnAnt`
    freq_responses = np.empty([3, 3, Nsc, numUeAnt, numAnAnt], dtype=complex)

    for ueIdx in range(3):
        for anIdx in range(3):
            jakes_all_links[ueIdx,
                            anIdx] = JakesSampleGenerator(Fd,
                                                          Ts,
                                                          L,
                                                          shape=(numUeAnt,
                                                                 numAnAnt))

            tdlchannels_all_links[ueIdx, anIdx] = TdlChannel(
                jakes_all_links[ueIdx, anIdx],
                tap_powers_dB=COST259_TUx.tap_powers_dB,
                tap_delays=COST259_TUx.tap_delays)

            tdlchannels_all_links[ueIdx,
                                  anIdx].generate_impulse_response(num_samples)

            impulse_responses[ueIdx, anIdx] \
                = tdlchannels_all_links[
                ueIdx, anIdx].get_last_impulse_response()

            freq_responses[ueIdx, anIdx] = \
                impulse_responses[ueIdx, anIdx].get_freq_response(Nsc)[:, :, :,
                0]

    # xxxxxxxxxx Channels in downlink direction xxxxxxxxxxxxxxxxxxxxxxxxxxx
    # Dimension: `Nsc x numUeAnt x numAnAnt`
    dH11 = freq_responses[0, 0]
    dH12 = freq_responses[0, 1]
    dH13 = freq_responses[0, 2]
    dH21 = freq_responses[1, 0]
    dH22 = freq_responses[1, 1]
    dH23 = freq_responses[1, 2]
    dH31 = freq_responses[2, 0]
    dH32 = freq_responses[2, 1]
    dH33 = freq_responses[2, 2]

    # xxxxxxxxxx Principal dimension in downlink direction xxxxxxxxxxxxxxxx
    sc_idx = 124  # Index of the subcarrier we are interested in
    [dU11, _, _] = np.linalg.svd(dH11[sc_idx])
    [dU22, _, _] = np.linalg.svd(dH22[sc_idx])
    [dU33, _, _] = np.linalg.svd(dH33[sc_idx])

    # xxxxxxxxxx Users precoders xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
    # Users' precoders are the main column of the U matrix
    F11 = dU11[:, 0].conj()
    F22 = dU22[:, 0].conj()
    F33 = dU33[:, 0].conj()

    # xxxxxxxxxx Channels in uplink direction xxxxxxxxxxxxxxxxxxxxxxxxxxxxx
    # int_path_loss = 0.05  # Path loss of the interfering links
    # int_g = math.sqrt(int_path_loss)  # Gain of interfering links
    # dir_d = 1.0                   #  Gain of direct links

    pl = np.array([[2.21e-08, 2.14e-09, 1.88e-08],
                   [3.45e-10, 2.17e-08, 4.53e-10],
                   [4.38e-10, 8.04e-10, 4.75e-08]])
    # pl = np.array([[  1,   0.1,   0.1],
    #                [  0.1,   1,   0.1],
    #                [  0.1,   0.1,   1]])

    # Dimension: `Nsc x numAnAnt x numUeAnt`
    uH11 = math.sqrt(pl[0, 0]) * np.transpose(dH11, axes=[0, 2, 1])
    uH12 = math.sqrt(pl[0, 1]) * np.transpose(dH12, axes=[0, 2, 1])
    uH13 = math.sqrt(pl[0, 2]) * np.transpose(dH13, axes=[0, 2, 1])
    uH21 = math.sqrt(pl[1, 0]) * np.transpose(dH21, axes=[0, 2, 1])
    uH22 = math.sqrt(pl[1, 1]) * np.transpose(dH22, axes=[0, 2, 1])
    uH23 = math.sqrt(pl[1, 2]) * np.transpose(dH23, axes=[0, 2, 1])
    uH31 = math.sqrt(pl[2, 0]) * np.transpose(dH31, axes=[0, 2, 1])
    uH32 = math.sqrt(pl[2, 1]) * np.transpose(dH32, axes=[0, 2, 1])
    uH33 = math.sqrt(pl[2, 2]) * np.transpose(dH33, axes=[0, 2, 1])

    # Compute the equivalent uplink channels
    uH11_eq = uH11.dot(F11)
    uH12_eq = uH12.dot(F22)
    uH13_eq = uH13.dot(F33)
    uH21_eq = uH21.dot(F11)
    uH22_eq = uH22.dot(F22)
    uH23_eq = uH23.dot(F33)
    uH31_eq = uH31.dot(F11)
    uH32_eq = uH32.dot(F22)
    uH33_eq = uH33.dot(F33)

    # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
    # xxxxxxxxxxxxxxx Compute Received Signals xxxxxxxxxxxxxxxxxxxxxxxxxxxx
    # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
    # Calculate the received signals
    comb_indexes = np.r_[0:Nsc:2]
    Y1_term11 = uH11_eq[comb_indexes] * r1[:, np.newaxis]
    Y1_term12 = uH12_eq[comb_indexes] * r2[:, np.newaxis]
    Y1_term13 = uH13_eq[comb_indexes] * r3[:, np.newaxis]
    Y1 = Y1_term11 + Y1_term12 + Y1_term13

    Y2_term21 = uH21_eq[comb_indexes] * r1[:, np.newaxis]
    Y2_term22 = uH22_eq[comb_indexes] * r2[:, np.newaxis]
    Y2_term23 = uH23_eq[comb_indexes] * r3[:, np.newaxis]
    Y2 = Y2_term21 + Y2_term22 + Y2_term23

    Y3_term31 = uH31_eq[comb_indexes] * r1[:, np.newaxis]
    Y3_term32 = uH32_eq[comb_indexes] * r2[:, np.newaxis]
    Y3_term33 = uH33_eq[comb_indexes] * r3[:, np.newaxis]
    Y3 = Y3_term31 + Y3_term32 + Y3_term33

    # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
    # xxxxxxxxxxxxxxx Estimate the equivalent channel xxxxxxxxxxxxxxxxxxxxx
    # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
    (uH11_eq_est, uH12_eq_est, uH13_eq_est, uH21_eq_est, uH22_eq_est,
     uH23_eq_est, uH31_eq_est, uH32_eq_est,
     uH33_eq_est) = estimate_channels_remove_only_direct(
         Y1, Y2, Y3, r1, r2, r3, Nsc, comb_indexes)

    (uH11_eq_est_SIC, uH12_eq_est_SIC, uH13_eq_est_SIC, uH21_eq_est_SIC,
     uH22_eq_est_SIC, uH23_eq_est_SIC, uH31_eq_est_SIC, uH32_eq_est_SIC,
     uH33_eq_est_SIC) = estimate_channels_remove_direct_and_perform_SIC(
         Y1, Y2, Y3, r1, r2, r3, Nsc, comb_indexes)

    # Compute the MSE reduction due to SIC
    improve11 = compute_channel_estimation_error_dB(
        uH11_eq, uH11_eq_est) - compute_channel_estimation_error_dB(
            uH11_eq, uH11_eq_est_SIC)
    improve12 = compute_channel_estimation_error_dB(
        uH12_eq, uH12_eq_est) - compute_channel_estimation_error_dB(
            uH12_eq, uH12_eq_est_SIC)
    improve13 = compute_channel_estimation_error_dB(
        uH13_eq, uH13_eq_est) - compute_channel_estimation_error_dB(
            uH13_eq, uH13_eq_est_SIC)

    improve21 = compute_channel_estimation_error_dB(
        uH21_eq, uH21_eq_est) - compute_channel_estimation_error_dB(
            uH21_eq, uH21_eq_est_SIC)
    improve22 = compute_channel_estimation_error_dB(
        uH22_eq, uH22_eq_est) - compute_channel_estimation_error_dB(
            uH22_eq, uH22_eq_est_SIC)
    improve23 = compute_channel_estimation_error_dB(
        uH23_eq, uH23_eq_est) - compute_channel_estimation_error_dB(
            uH23_eq, uH23_eq_est_SIC)

    improve31 = compute_channel_estimation_error_dB(
        uH31_eq, uH31_eq_est) - compute_channel_estimation_error_dB(
            uH31_eq, uH31_eq_est_SIC)
    improve32 = compute_channel_estimation_error_dB(
        uH32_eq, uH32_eq_est) - compute_channel_estimation_error_dB(
            uH32_eq, uH32_eq_est_SIC)
    improve33 = compute_channel_estimation_error_dB(
        uH33_eq, uH33_eq_est) - compute_channel_estimation_error_dB(
            uH33_eq, uH33_eq_est_SIC)
    print(improve11)
    print(improve12)
    print(improve13)
    print(improve21)
    print(improve22)
    print(improve23)
    print(improve31)
    print(improve32)
    print(improve33)

    # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
    # xxxxxxxxxxxxxxx Plot the true and estimated channels xxxxxxxxxxxxxxxx
    # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
    p1 = plot_true_and_estimated_channel_with_bokeh_all_antennas(
        uH11_eq, uH11_eq_est, title='Direct Channel from UE1 to AN1')
    p2 = plot_true_and_estimated_channel_with_bokeh_all_antennas(
        uH12_eq, uH12_eq_est, title='Interfering Channel from UE2 to AN1')
    p3 = plot_true_and_estimated_channel_with_bokeh_all_antennas(
        uH13_eq, uH13_eq_est, title='Interfering Channel from UE3 to AN1')
    tab1 = bw.Panel(child=p1, title="UE1 to AN1")
    tab2 = bw.Panel(child=p2, title="UE2 to AN1")
    tab3 = bw.Panel(child=p3, title="UE3 to AN1")
    tabs_an1 = bw.Tabs(tabs=[tab1, tab2, tab3])

    p1 = plot_true_and_estimated_channel_with_bokeh_all_antennas(
        uH21_eq, uH21_eq_est, title='Interfering Channel from UE1 to AN2')
    p2 = plot_true_and_estimated_channel_with_bokeh_all_antennas(
        uH22_eq, uH22_eq_est, title='Direct Channel from UE2 to AN2')
    p3 = plot_true_and_estimated_channel_with_bokeh_all_antennas(
        uH23_eq, uH23_eq_est, title='Interfering Channel from UE3 to AN2')
    tab1 = bw.Panel(child=p1, title="UE1 to AN2")
    tab2 = bw.Panel(child=p2, title="UE2 to AN2")
    tab3 = bw.Panel(child=p3, title="UE3 to AN2")
    tabs_an2 = bw.Tabs(tabs=[tab1, tab2, tab3])

    p1 = plot_true_and_estimated_channel_with_bokeh_all_antennas(
        uH31_eq, uH31_eq_est, title='Interfering Channel from UE1 to AN3')
    p2 = plot_true_and_estimated_channel_with_bokeh_all_antennas(
        uH32_eq, uH32_eq_est, title='Interfering Channel from UE2 to AN3')
    p3 = plot_true_and_estimated_channel_with_bokeh_all_antennas(
        uH33_eq, uH33_eq_est, title='Direct Channel from UE3 to AN3')
    tab1 = bw.Panel(child=p1, title="UE1 to AN3")
    tab2 = bw.Panel(child=p2, title="UE2 to AN3")
    tab3 = bw.Panel(child=p3, title="UE3 to AN3")
    tabs_an3 = bw.Tabs(tabs=[tab1, tab2, tab3])

    # Put each AN tab as a panel of an "ANs tab" and show it
    tabs1 = bw.Panel(child=tabs_an1, title="AN1")
    tabs2 = bw.Panel(child=tabs_an2, title="AN2")
    tabs3 = bw.Panel(child=tabs_an3, title="AN3")
    tabs_all = bw.Tabs(tabs=[tabs1, tabs2, tabs3])
    bp.show(tabs_all)
Example #2
0
    input_data = np.random.random_integers(0, 4 - 1, num_symbols)
    # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

    # xxxxxxxxxx QPSK and OFDM Modulators xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
    qpsk_obj = QPSK()
    ofdm_obj = OFDM(fft_size=fft_size, cp_size=cp_size,
                    num_used_subcarriers=num_used_subcarriers)
    # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

    # xxxxxxxxxx Modulate data xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
    modulated_data = qpsk_obj.modulate(input_data)
    transmit_data = ofdm_obj.modulate(modulated_data)
    # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

    # xxxxxxxxxx Transmit data through the channel xxxxxxxxxxxxxxxxxxxxxxxx
    jakes = JakesSampleGenerator(Fd, Ts, L)
    channel = SuChannel(jakes, channel_profile)
    channel_memory = channel.num_taps_with_padding - 1
    received_data = channel.corrupt_data(transmit_data)
    # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

    # xxxxxxxxxx OFDM Demodulate data xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
    ofdm_received_data = ofdm_obj.demodulate(received_data[:-channel_memory])
    # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

    # xxxxxxxxxx One-Tap Equalization xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
    # First we need to get the frequency response
    impulse_response = channel.get_last_impulse_response()
    freq_response = impulse_response.get_freq_response(fft_size)
    # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Example #3
0
    def test_estimate_channel_multiple_rx(self):
        Nsc = 24
        size = Nsc
        Nr = 3  # Number of receive antennas
        num_taps_to_keep = 15

        cover_codes = [np.array([-1, 1]), np.array([1, 1])]
        user1_seq = DmrsUeSequence(RootSequence(root_index=25, size=size),
                                   1,
                                   cover_code=cover_codes[0])
        user2_seq = DmrsUeSequence(RootSequence(root_index=25, size=size),
                                   4,
                                   cover_code=cover_codes[0])

        ue1_channel_estimator = CazacBasedWithOCCChannelEstimator(user1_seq)

        speed_terminal = 3 / 3.6  # Speed in m/s
        fcDbl = 2.6e9  # Central carrier frequency (in Hz)
        subcarrier_bandwidth = 15e3  # Subcarrier bandwidth (in Hz)
        wave_length = 3e8 / fcDbl  # Carrier wave length
        Fd = speed_terminal / wave_length  # Doppler Frequency
        Ts = 1. / (Nsc * subcarrier_bandwidth)  # Sampling interval
        L = 16  # Number of jakes taps

        # Create the fading generators and set multiple receive antennas
        jakes1 = JakesSampleGenerator(Fd, Ts, L, shape=(Nr, 1))
        jakes2 = JakesSampleGenerator(Fd, Ts, L, shape=(Nr, 1))

        # Create a TDL channel object for each user
        tdlchannel1 = TdlChannel(jakes1, channel_profile=COST259_TUx)
        tdlchannel2 = TdlChannel(jakes2, channel_profile=COST259_TUx)

        # Generate channel that would corrupt the transmit signal.
        tdlchannel1.generate_impulse_response(1)
        tdlchannel2.generate_impulse_response(1)

        # Get the generated impulse response
        impulse_response1 = tdlchannel1.get_last_impulse_response()
        impulse_response2 = tdlchannel2.get_last_impulse_response()

        # Get the corresponding frequency response
        freq_resp_1 = impulse_response1.get_freq_response(Nsc)
        H1 = freq_resp_1[:, :, 0, 0].T
        freq_resp_2 = impulse_response2.get_freq_response(Nsc)
        H2 = freq_resp_2[:, :, 0, 0].T

        # Sequence of the users
        r1 = user1_seq.seq_array()
        r2 = user2_seq.seq_array()

        # Received signal (in frequency domain) of user 1
        Y1 = H1[:, np.newaxis, :] * r1[np.newaxis, :, :]
        Y2 = H2[:, np.newaxis, :] * r2[np.newaxis, :, :]
        Y = Y1 + Y2  # Dimension: `Nr x cover_code_size x num_elements`

        # Calculate expected estimated channel for user 1
        cover_code1 = cover_codes[0]
        Y_with_cover_code = \
            (cover_code1[0] * Y[:,0,:] + cover_code1[1] * Y[:,1,:]) / 2.0
        ":type: np.ndarray"

        r1_no_cover_code = r1[0] * cover_code1[0]

        y1 = np.fft.ifft(np.conj(r1_no_cover_code[np.newaxis]) *
                         Y_with_cover_code,
                         size,
                         axis=1)
        tilde_h1_espected = y1[:, 0:(num_taps_to_keep + 1)]
        tilde_H1_espected = np.fft.fft(tilde_h1_espected, Nsc, axis=1)

        # Test the CazacBasedWithOCCChannelEstimator estimation

        H1_estimated = ue1_channel_estimator.estimate_channel_freq_domain(
            Y, num_taps_to_keep, extra_dimension=True)
        np.testing.assert_array_almost_equal(H1_estimated, tilde_H1_espected)

        # Test if true channel and estimated channel are similar. Since the
        # channel estimation error is higher at the first and last
        # subcarriers we will test only the inner 200 subcarriers
        error = np.abs(H1 - tilde_H1_espected)
        ":type: np.ndarray"

        np.testing.assert_almost_equal(error / 2.,
                                       np.zeros(error.shape),
                                       decimal=2)
Example #4
0
    def test_estimate_channel_with_dmrs(self):
        Nsc = 24
        size = Nsc

        cover_codes = [np.array([-1, 1]), np.array([1, 1])]
        user1_seq = DmrsUeSequence(root_seq=RootSequence(root_index=17,
                                                         size=size),
                                   n_cs=1,
                                   cover_code=cover_codes[0])
        user2_seq = DmrsUeSequence(root_seq=RootSequence(root_index=17,
                                                         size=size),
                                   n_cs=4,
                                   cover_code=cover_codes[1])

        ue1_channel_estimator = CazacBasedWithOCCChannelEstimator(user1_seq)

        speed_terminal = 3 / 3.6  # Speed in m/s
        fcDbl = 2.6e9  # Central carrier frequency (in Hz)
        subcarrier_bandwidth = 15e3  # Subcarrier bandwidth (in Hz)
        wave_length = 3e8 / fcDbl  # Carrier wave length
        Fd = speed_terminal / wave_length  # Doppler Frequency
        Ts = 1. / (Nsc * subcarrier_bandwidth)  # Sampling interval
        L = 16  # Number of jakes taps

        jakes1 = JakesSampleGenerator(Fd, Ts, L)
        jakes2 = JakesSampleGenerator(Fd, Ts, L)

        # Create a TDL channel object for each user
        tdlchannel1 = TdlChannel(jakes1, channel_profile=COST259_TUx)
        tdlchannel2 = TdlChannel(jakes2, channel_profile=COST259_TUx)

        # Generate channel that would corrupt the transmit signal.
        tdlchannel1.generate_impulse_response(1)
        tdlchannel2.generate_impulse_response(1)

        # Get the generated impulse response
        impulse_response1 = tdlchannel1.get_last_impulse_response()
        impulse_response2 = tdlchannel2.get_last_impulse_response()

        # Get the corresponding frequency response
        freq_resp_1 = impulse_response1.get_freq_response(Nsc)
        H1 = freq_resp_1[:, 0]
        freq_resp_2 = impulse_response2.get_freq_response(Nsc)
        H2 = freq_resp_2[:, 0]

        # Sequence of the users
        r1 = user1_seq.seq_array()
        r2 = user2_seq.seq_array()

        # Received signal (in frequency domain) of user 1
        Y1 = H1 * r1
        Y2 = H2 * r2
        Y = Y1 + Y2

        # Calculate expected estimated channel for user 1
        cover_code1 = cover_codes[0]
        Y_with_cover_code = \
            (cover_code1[0] * Y[0] + cover_code1[1] * Y[1]) / 2.0
        ":type: np.ndarray"
        r1_no_cover_code = r1[0] * cover_code1[0]

        y1 = np.fft.ifft(np.conj(r1_no_cover_code) * Y_with_cover_code, size)
        tilde_h1 = y1[0:4]
        tilde_H1 = np.fft.fft(tilde_h1, Nsc)

        # Test the CazacBasedWithOCCChannelEstimator estimation
        np.testing.assert_array_almost_equal(
            ue1_channel_estimator.estimate_channel_freq_domain(
                Y, 3, extra_dimension=True), tilde_H1)

        # Test if true channel and estimated channel are similar. Since the
        # channel estimation error is higher at the first and last
        # subcarriers we will test only the inner 200 subcarriers
        error = np.abs(H1 - tilde_H1)
        ":type: np.ndarray"

        np.testing.assert_almost_equal(error / 2.,
                                       np.zeros(error.size),
                                       decimal=2)
Example #5
0
    def test_estimate_channel_multiple_rx(self):
        Nsc = 300  # 300 subcarriers
        size = Nsc // 2
        Nzc = 139

        user1_seq = SrsUeSequence(RootSequence(root_index=25,
                                               size=size,
                                               Nzc=Nzc),
                                  1,
                                  normalize=True)
        user2_seq = SrsUeSequence(RootSequence(root_index=25,
                                               size=size,
                                               Nzc=Nzc),
                                  4,
                                  normalize=True)

        ue1_channel_estimator = CazacBasedChannelEstimator(user1_seq)

        speed_terminal = 3 / 3.6  # Speed in m/s
        fcDbl = 2.6e9  # Central carrier frequency (in Hz)
        subcarrier_bandwidth = 15e3  # Subcarrier bandwidth (in Hz)
        wave_length = 3e8 / fcDbl  # Carrier wave length
        Fd = speed_terminal / wave_length  # Doppler Frequency
        Ts = 1. / (Nsc * subcarrier_bandwidth)  # Sampling interval
        L = 16  # Number of jakes taps

        # Create the fading generators and set multiple receive antennas
        jakes1 = JakesSampleGenerator(Fd, Ts, L, shape=(3, 1))
        jakes2 = JakesSampleGenerator(Fd, Ts, L, shape=(3, 1))

        # Create a TDL channel object for each user
        tdlchannel1 = TdlChannel(jakes1, channel_profile=COST259_TUx)
        tdlchannel2 = TdlChannel(jakes2, channel_profile=COST259_TUx)

        # Generate channel that would corrupt the transmit signal.
        tdlchannel1.generate_impulse_response(1)
        tdlchannel2.generate_impulse_response(1)

        # Get the generated impulse response
        impulse_response1 = tdlchannel1.get_last_impulse_response()
        impulse_response2 = tdlchannel2.get_last_impulse_response()

        # Get the corresponding frequency response
        freq_resp_1 = impulse_response1.get_freq_response(Nsc)
        H1 = freq_resp_1[:, :, 0, 0]
        freq_resp_2 = impulse_response2.get_freq_response(Nsc)
        H2 = freq_resp_2[:, :, 0, 0]

        # Sequence of the users
        r1 = user1_seq.seq_array()
        r2 = user2_seq.seq_array()

        # Received signal (in frequency domain) of user 1
        comb_indexes = np.arange(0, Nsc, 2)
        Y1 = H1[comb_indexes, :] * r1[:, np.newaxis]
        Y2 = H2[comb_indexes, :] * r2[:, np.newaxis]
        Y = Y1 + Y2

        # Calculate expected estimated channel for user 1
        y1 = np.fft.ifft(r1.size * np.conj(r1[:, np.newaxis]) * Y,
                         size,
                         axis=0)
        tilde_h1_espected = y1[0:16]
        tilde_H1_espected = np.fft.fft(tilde_h1_espected, Nsc, axis=0)

        # Test the CazacBasedChannelEstimator estimation
        H1_estimated = ue1_channel_estimator.estimate_channel_freq_domain(
            Y.T, 15)
        np.testing.assert_array_almost_equal(H1_estimated, tilde_H1_espected.T)

        # Test if true channel and estimated channel are similar. Since the
        # channel estimation error is higher at the first and last
        # subcarriers we will test only the inner 200 subcarriers
        error = np.abs(H1[50:-50, :] - tilde_H1_espected[50:-50, :])
        ":type: np.ndarray"

        np.testing.assert_almost_equal(error / 2.,
                                       np.zeros(error.shape),
                                       decimal=2)
Example #6
0
    def test_estimate_channel_without_comb_pattern(self):
        Nsc = 300  # 300 subcarriers
        size = Nsc  # The size is also 300, since there is no comb pattern
        Nzc = 139

        user1_seq = SrsUeSequence(
            RootSequence(root_index=25, size=size, Nzc=Nzc), 1)
        user2_seq = SrsUeSequence(
            RootSequence(root_index=25, size=size, Nzc=Nzc), 4)

        # Set size_multiplier to 1, since we won't use the comb pattern
        ue1_channel_estimator = CazacBasedChannelEstimator(user1_seq,
                                                           size_multiplier=1)

        speed_terminal = 3 / 3.6  # Speed in m/s
        fcDbl = 2.6e9  # Central carrier frequency (in Hz)
        subcarrier_bandwidth = 15e3  # Subcarrier bandwidth (in Hz)
        wave_length = 3e8 / fcDbl  # Carrier wave length
        Fd = speed_terminal / wave_length  # Doppler Frequency
        Ts = 1. / (Nsc * subcarrier_bandwidth)  # Sampling interval
        L = 16  # Number of jakes taps

        jakes1 = JakesSampleGenerator(Fd, Ts, L)
        jakes2 = JakesSampleGenerator(Fd, Ts, L)

        # Create a TDL channel object for each user
        tdlchannel1 = TdlChannel(jakes1, channel_profile=COST259_TUx)
        tdlchannel2 = TdlChannel(jakes2, channel_profile=COST259_TUx)

        # Generate channel that would corrupt the transmit signal.
        tdlchannel1.generate_impulse_response(1)
        tdlchannel2.generate_impulse_response(1)

        # Get the generated impulse response
        impulse_response1 = tdlchannel1.get_last_impulse_response()
        impulse_response2 = tdlchannel2.get_last_impulse_response()

        # Get the corresponding frequency response
        freq_resp_1 = impulse_response1.get_freq_response(Nsc)
        H1 = freq_resp_1[:, 0]
        freq_resp_2 = impulse_response2.get_freq_response(Nsc)
        H2 = freq_resp_2[:, 0]

        # Sequence of the users
        r1 = user1_seq.seq_array()
        r2 = user2_seq.seq_array()

        # Received signal (in frequency domain) of user 1
        Y1 = H1 * r1
        Y2 = H2 * r2
        Y = Y1 + Y2

        # Calculate expected estimated channel for user 1
        y1 = np.fft.ifft(np.conj(r1) * Y, size)
        tilde_h1 = y1[0:16]
        tilde_H1 = np.fft.fft(tilde_h1, Nsc)

        # Test the CazacBasedChannelEstimator estimation
        np.testing.assert_array_almost_equal(
            ue1_channel_estimator.estimate_channel_freq_domain(Y, 15),
            tilde_H1)

        # Test if true channel and estimated channel are similar. Since the
        # channel estimation error is higher at the first and last
        # subcarriers we will test only the inner 200 subcarriers
        error = np.abs(H1[50:-50] - tilde_H1[50:-50])
        ":type: np.ndarray"

        np.testing.assert_almost_equal(error / 2.,
                                       np.zeros(error.size),
                                       decimal=2)
Example #7
0
    def test_estimate_channel_with_srs(self):
        Nsc = 300  # 300 subcarriers
        size = Nsc // 2
        Nzc = 139

        user1_seq = SrsUeSequence(RootSequence(root_index=25,
                                               size=size,
                                               Nzc=Nzc),
                                  1,
                                  normalize=True)
        user2_seq = SrsUeSequence(RootSequence(root_index=25,
                                               size=size,
                                               Nzc=Nzc),
                                  4,
                                  normalize=True)

        ue1_channel_estimator = CazacBasedChannelEstimator(user1_seq)
        ue2_channel_estimator = CazacBasedChannelEstimator(user2_seq)

        speed_terminal = 3 / 3.6  # Speed in m/s
        fcDbl = 2.6e9  # Central carrier frequency (in Hz)
        subcarrier_bandwidth = 15e3  # Subcarrier bandwidth (in Hz)
        wave_length = 3e8 / fcDbl  # Carrier wave length
        Fd = speed_terminal / wave_length  # Doppler Frequency
        Ts = 1. / (Nsc * subcarrier_bandwidth)  # Sampling interval
        L = 16  # Number of jakes taps

        jakes1 = JakesSampleGenerator(Fd, Ts, L)
        jakes2 = JakesSampleGenerator(Fd, Ts, L)

        # Create a TDL channel object for each user
        tdlchannel1 = TdlChannel(jakes1, channel_profile=COST259_TUx)
        tdlchannel2 = TdlChannel(jakes2, channel_profile=COST259_TUx)

        # Generate channel that would corrupt the transmit signal.
        tdlchannel1.generate_impulse_response(1)
        tdlchannel2.generate_impulse_response(1)

        # Get the generated impulse response
        impulse_response1 = tdlchannel1.get_last_impulse_response()
        impulse_response2 = tdlchannel2.get_last_impulse_response()

        # Get the corresponding frequency response
        freq_resp_1 = impulse_response1.get_freq_response(Nsc)
        H1 = freq_resp_1[:, 0]
        freq_resp_2 = impulse_response2.get_freq_response(Nsc)
        H2 = freq_resp_2[:, 0]

        # Sequence of the users
        r1 = user1_seq.seq_array()
        r2 = user2_seq.seq_array()

        # Received signal (in frequency domain) of user 1
        comb_indexes = np.arange(0, Nsc, 2)
        Y1 = H1[comb_indexes] * r1
        Y2 = H2[comb_indexes] * r2
        Y = Y1 + Y2

        # xxxxxxxxxx USER 1 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
        # Calculate expected estimated channel for user 1
        y1 = np.fft.ifft(r1.size * np.conj(r1) * Y, size)
        tilde_h1 = y1[0:16]
        tilde_H1 = np.fft.fft(tilde_h1, Nsc)

        # Test the CazacBasedChannelEstimator estimation
        np.testing.assert_array_almost_equal(
            ue1_channel_estimator.estimate_channel_freq_domain(Y, 15),
            tilde_H1)

        # Check that the estimated channel and the True channel have similar
        # norms
        self.assertAlmostEqual(np.linalg.norm(
            ue1_channel_estimator.estimate_channel_freq_domain(Y, 15)),
                               np.linalg.norm(H1),
                               delta=0.5)

        # Test if true channel and estimated channel are similar. Since the
        # channel estimation error is higher at the first and last
        # subcarriers we will test only the inner 200 subcarriers
        error = np.abs(H1[50:-50] - tilde_H1[50:-50])
        ":type: np.ndarray"

        np.testing.assert_almost_equal(error / 2.,
                                       np.zeros(error.size),
                                       decimal=2)
        # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

        # xxxxxxxxxx USER 2 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
        # Calculate expected estimated channel for user 2
        y2 = np.fft.ifft(r2.size * np.conj(r2) * Y, size)
        tilde_h2 = y2[0:16]
        tilde_H2 = np.fft.fft(tilde_h2, Nsc)

        # Test the CazacBasedChannelEstimator estimation
        np.testing.assert_array_almost_equal(
            ue2_channel_estimator.estimate_channel_freq_domain(Y, 15),
            tilde_H2)

        # Check that the estimated channel and the True channel have similar
        # norms
        self.assertAlmostEqual(np.linalg.norm(
            ue2_channel_estimator.estimate_channel_freq_domain(Y, 15)),
                               np.linalg.norm(H2),
                               delta=0.5)

        # Test if true channel and estimated channel are similar. Since the
        # channel estimation error is higher at the first and last
        # subcarriers we will test only the inner 200 subcarriers
        error = np.abs(H2[50:-50] - tilde_H2[50:-50])
        ":type: np.ndarray"

        np.testing.assert_almost_equal(error / 2.,
                                       np.zeros(error.size),
                                       decimal=2)