def test_get_extended_ZF(self): a = zadoffchu.calcBaseZC(139, u=20) b = zadoffchu.calcBaseZC(31, u=14) c = zadoffchu.calcBaseZC(19, u=5) # Compute and test the extended root sequence a for size 150 a_ext = zadoffchu.get_extended_ZF(a, 150) expected_a_ext = np.hstack([a, a[0:11]]) self.assertEqual(a_ext.size, 150) np.testing.assert_almost_equal(expected_a_ext, a_ext) # Compute and test the extended root sequence b for size 32 b_ext = zadoffchu.get_extended_ZF(b, 32) expected_b_ext = np.hstack([b, b[0]]) self.assertEqual(b_ext.size, 32) np.testing.assert_almost_equal(expected_b_ext, b_ext) # Compute and test the extended root sequence c for size 32 c_ext = zadoffchu.get_extended_ZF(c, 32) expected_c_ext = np.hstack([c, c[0:13]]) self.assertEqual(c_ext.size, 32) np.testing.assert_almost_equal(expected_c_ext, c_ext) # Compute and test the extended root sequence c for size 64 c_ext = zadoffchu.get_extended_ZF(c, 64) expected_c_ext = np.hstack([c, c, c, c[0:7]]) self.assertEqual(c_ext.size, 64) np.testing.assert_almost_equal(expected_c_ext, c_ext)
def test_seq_array(self): # calcBaseZC, get_srs_seq, get_extended_ZF expected_user_seq_no_ext1 = get_srs_seq(calcBaseZC(139, 25), 3) np.testing.assert_array_almost_equal(expected_user_seq_no_ext1, self.user_seq_no_ext1.seq_array()) expected_user_seq_no_ext2 = get_srs_seq(calcBaseZC(31, 6), 1) np.testing.assert_array_almost_equal(expected_user_seq_no_ext2, self.user_seq_no_ext2.seq_array()) expected_user_seq_no_ext2_other_shift = get_srs_seq(calcBaseZC(31, 6), 3) np.testing.assert_array_almost_equal( expected_user_seq_no_ext2_other_shift, self.user_seq_no_ext2_other.seq_array()) expected_user_seq1 = get_srs_seq(get_extended_ZF(calcBaseZC(139, 25), 150), 7) np.testing.assert_array_almost_equal(self.user_seq1.seq_array(), expected_user_seq1) expected_user_seq2 = get_srs_seq(get_extended_ZF(calcBaseZC(139, 12), 150), 4) np.testing.assert_array_almost_equal(self.user_seq2.seq_array(), expected_user_seq2) expected_user_seq3 = get_srs_seq(get_extended_ZF(calcBaseZC(31, 25), 64), 1) np.testing.assert_array_almost_equal(self.user_seq3.seq_array(), expected_user_seq3) expected_user_seq4 = get_srs_seq(get_extended_ZF(calcBaseZC(31, 6), 64), 2) np.testing.assert_array_almost_equal(self.user_seq4.seq_array(), expected_user_seq4) expected_user_seq5 = get_srs_seq(get_extended_ZF(calcBaseZC(31, 6), 32), 3) np.testing.assert_array_almost_equal(self.user_seq5.seq_array(), expected_user_seq5) expected_user_seq6 = get_srs_seq(get_extended_ZF(calcBaseZC(31, 6), 256), 5) np.testing.assert_array_almost_equal(self.user_seq6.seq_array(), expected_user_seq6)
def test_calcBaseZC(self): Nzc = 63 n = np.r_[0:Nzc] zf1 = calcBaseZC(Nzc=Nzc, u=0, q=0) self.assertEqual(zf1.size, 63) np.testing.assert_array_almost_equal(zf1, np.ones(63)) zf2 = calcBaseZC(Nzc=Nzc, u=25, q=0) self.assertEqual(zf1.size, 63) expected_zf2 = np.exp(-1j * 25 * np.pi * n * (n + 1) / Nzc) np.testing.assert_array_almost_equal(zf2, expected_zf2)
def test_get_shifted_root_seq(self): Nzc = 63 n = np.r_[0:Nzc] u = 25 n_cs = 4 denominator = 8 zf1 = calcBaseZC(Nzc=Nzc, u=u, q=0) zf1_shifted = get_shifted_root_seq(zf1, n_cs=n_cs, denominator=denominator) expected_shifted_zf1 = zf1 * np.exp( 1j * n * 2 * np.pi * n_cs / denominator) self.assertEqual(zf1_shifted.size, Nzc) np.testing.assert_almost_equal(zf1_shifted, expected_shifted_zf1)
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)
def test_seq_array(self): # xxxxxxxxxx Small Root Sequences xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx # Line 15 of the first table expected_small_root_seq1 = np.exp( 1j * (np.pi / 4.0) * np.array([3, -1, 1, -3, -1, -1, 1, 1, 3, 1, -1, -3])) # Line 23 of the first table expected_small_root_seq2 = np.exp( 1j * (np.pi / 4.0) * np.array([1, 1, -1, -3, -1, -3, 1, -1, 1, 3, -1, 1])) # Line 15 of the second table expected_small_root_seq3 = np.exp(1j * (np.pi / 4.0) * np.array([ -1, -1, 1, -3, 1, 3, -3, 1, -1, -3, -1, 3, 1, 3, 1, -1, -3, -3, -1, -1, -3, -3, -3, -1 ])) # Line 23 of the second table expected_small_root_seq4 = np.exp(1j * (np.pi / 4.0) * np.array([ -1, -1, -1, -1, 3, 3, 3, 1, 3, 3, -3, 1, 3, -1, 3, -1, 3, 3, -3, 3, 1, -1, 3, 3 ])) np.testing.assert_array_almost_equal(self.small_root_seq1.seq_array(), expected_small_root_seq1) np.testing.assert_array_almost_equal(self.small_root_seq2.seq_array(), expected_small_root_seq2) np.testing.assert_array_almost_equal(self.small_root_seq3.seq_array(), expected_small_root_seq3) np.testing.assert_array_almost_equal(self.small_root_seq4.seq_array(), expected_small_root_seq4) # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx # xxxxxxxxxx Zadoff-Chu Sequences xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx expected_root__no_ext1 = calcBaseZC(139, 25) np.testing.assert_array_almost_equal(self.root_seq_no_ext1.seq_array(), expected_root__no_ext1) expected_root__no_ext2 = calcBaseZC(31, 6) np.testing.assert_array_almost_equal(self.root_seq_no_ext2.seq_array(), expected_root__no_ext2) expected_root_seq1 = calcBaseZC(149, 25) expected_root_seq1 = np.hstack( [expected_root_seq1, expected_root_seq1[0:1]]) np.testing.assert_array_almost_equal(self.root_seq1.seq_array(), expected_root_seq1) expected_root_seq2 = calcBaseZC(139, 12) expected_root_seq2 = np.hstack( [expected_root_seq2, expected_root_seq2[0:11]]) np.testing.assert_array_almost_equal(self.root_seq2.seq_array(), expected_root_seq2) expected_root_seq3 = calcBaseZC(31, 25) expected_root_seq3 = np.hstack( [expected_root_seq3, expected_root_seq3, expected_root_seq3[0:2]]) np.testing.assert_array_almost_equal(self.root_seq3.seq_array(), expected_root_seq3) expected_root_seq4 = calcBaseZC(61, 6) expected_root_seq4 = np.hstack( [expected_root_seq4, expected_root_seq4[0:3]]) np.testing.assert_array_almost_equal(self.root_seq4.seq_array(), expected_root_seq4) expected_root_seq5 = calcBaseZC(31, 6) expected_root_seq5 = np.hstack( [expected_root_seq5, expected_root_seq5[0:1]]) np.testing.assert_array_almost_equal(self.root_seq5.seq_array(), expected_root_seq5) expected_root_seq6 = calcBaseZC(31, 6) expected_root_seq6 = np.hstack([ expected_root_seq6, expected_root_seq6, expected_root_seq6, expected_root_seq6, expected_root_seq6, expected_root_seq6, expected_root_seq6, expected_root_seq6, expected_root_seq6[0:8] ]) np.testing.assert_array_almost_equal(self.root_seq6.seq_array(), expected_root_seq6)
def test_seq_array(self): # xxxxxxxxxx Small Root Sequences xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx # Line 15 of the first table expected_small_root_seq1 = np.exp(1j * (np.pi/4.0) * np.array( [3, -1, 1, -3, -1, -1, 1, 1, 3, 1, -1, -3])) # Line 23 of the first table expected_small_root_seq2 = np.exp(1j * (np.pi/4.0) * np.array( [1, 1, -1, -3, -1, -3, 1, -1, 1, 3, -1, 1])) # Line 15 of the second table expected_small_root_seq3 = np.exp(1j * (np.pi/4.0) * np.array( [-1, -1, 1, -3, 1, 3, -3, 1, -1, -3, -1, 3, 1, 3, 1, -1, -3, -3, -1, -1, -3, -3, -3, -1])) # Line 23 of the second table expected_small_root_seq4 = np.exp(1j * (np.pi/4.0) * np.array( [-1, -1, -1, -1, 3, 3, 3, 1, 3, 3, -3, 1, 3, -1, 3, -1, 3, 3, -3, 3, 1, -1, 3, 3])) np.testing.assert_array_almost_equal(self.small_root_seq1.seq_array(), expected_small_root_seq1) np.testing.assert_array_almost_equal(self.small_root_seq2.seq_array(), expected_small_root_seq2) np.testing.assert_array_almost_equal(self.small_root_seq3.seq_array(), expected_small_root_seq3) np.testing.assert_array_almost_equal(self.small_root_seq4.seq_array(), expected_small_root_seq4) # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx # xxxxxxxxxx Zadoff-Chu Sequences xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx expected_root__no_ext1 = calcBaseZC(139, 25) np.testing.assert_array_almost_equal( self.root_seq_no_ext1.seq_array(), expected_root__no_ext1) expected_root__no_ext2 = calcBaseZC(31, 6) np.testing.assert_array_almost_equal( self.root_seq_no_ext2.seq_array(), expected_root__no_ext2) expected_root_seq1 = calcBaseZC(149, 25) expected_root_seq1 = np.hstack([expected_root_seq1, expected_root_seq1[0:1]]) np.testing.assert_array_almost_equal( self.root_seq1.seq_array(), expected_root_seq1) expected_root_seq2 = calcBaseZC(139, 12) expected_root_seq2 = np.hstack([expected_root_seq2, expected_root_seq2[0:11]]) np.testing.assert_array_almost_equal( self.root_seq2.seq_array(), expected_root_seq2) expected_root_seq3 = calcBaseZC(31, 25) expected_root_seq3 = np.hstack( [expected_root_seq3, expected_root_seq3, expected_root_seq3[0:2]]) np.testing.assert_array_almost_equal( self.root_seq3.seq_array(), expected_root_seq3) expected_root_seq4 = calcBaseZC(61, 6) expected_root_seq4 = np.hstack( [expected_root_seq4, expected_root_seq4[0:3]]) np.testing.assert_array_almost_equal( self.root_seq4.seq_array(), expected_root_seq4) expected_root_seq5 = calcBaseZC(31, 6) expected_root_seq5 = np.hstack([expected_root_seq5, expected_root_seq5[0:1]]) np.testing.assert_array_almost_equal( self.root_seq5.seq_array(), expected_root_seq5) expected_root_seq6 = calcBaseZC(31, 6) expected_root_seq6 = np.hstack( [expected_root_seq6, expected_root_seq6, expected_root_seq6, expected_root_seq6, expected_root_seq6, expected_root_seq6, expected_root_seq6, expected_root_seq6, expected_root_seq6[0:8]]) np.testing.assert_array_almost_equal( self.root_seq6.seq_array(), expected_root_seq6)
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 arbitrarely 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, dS11, dV11_H] = np.linalg.svd(dH11[sc_idx]) [dU22, dS22, dV22_H] = np.linalg.svd(dH22[sc_idx]) [dU33, dS33, dV33_H] = 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 pannel 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)