def test_calc_effective_throughput(self): psk_obj = fundamental.PSK(8) packet_length = 60 SINRs_dB = np.array([11.4, 20.3]) sinrs_linear = dB2Linear(SINRs_dB) expected_spectral_efficiency = np.sum( psk_obj.calcTheoreticalSpectralEfficiency(SINRs_dB, packet_length)) spectral_efficiency = blockdiagonalization._calc_effective_throughput( sinrs_linear, psk_obj, packet_length) np.testing.assert_array_almost_equal(spectral_efficiency, expected_spectral_efficiency)
def __init__(self, ): SimulationRunner.__init__(self) SNR = np.array([0, 3, 6, 9, 12]) M = 4 self.modulator = fundamental.PSK(M) self.NSymbs = 500 self.rep_max = 1000 self.max_bit_errors = 1. / 100. * self.NSymbs * self.rep_max # self.progressbar_message = None self.progressbar_message = "{0}-PSK".format(M) + \ " Simulation - SNR: {SNR}" # Add the parameters to the self.params variable self.params.add('SNR', SNR) self.params.set_unpack_parameter('SNR')
def __init__(self, ): super().__init__() SNR = np.array([0, 3, 6, 9, 12]) M = 4 modulator = fundamental.PSK(M) NSymbs = 500 self.params.add('modulator', modulator) self.params.add('NSymbs', NSymbs) self.rep_max = 1000 # self.max_bit_errors = 1. / 100. * NSymbs * self.rep_max max_bit_errors = 1. / 100. * NSymbs * self.rep_max self.params.add('max_bit_errors', max_bit_errors) # self.progressbar_message = None self.progressbar_message = "{0}-PSK".format(M) + \ " Simulation - SNR: {SNR}" # Add the parameters to the self.params variable self.params.add('SNR', SNR) self.params.set_unpack_parameter('SNR')
# xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx # Cell and Grid Parameters cell_radius = 1.0 # Cell radius (in Km) num_cells = 3 num_clusters = 1 # Channel Parameters Nr = np.ones(num_cells) * 2 # Number of receive antennas Nt = np.ones(num_cells) * 2 # Number of transmit antennas Ns_BD = Nt # Number of streams (per user) in the BD algorithm path_loss_obj = pathloss.PathLoss3GPP1() multiuser_channel = pyphysim.channels.multiuser.MultiUserChannelMatrixExtInt() # Modulation Parameters M = 4 modulator = fundamental.PSK(M) # Transmission Parameters NSymbs = 500 # Number of symbols (/stream /user simulated at each iteration SNR_dB = 15. N0_dBm = -116.4 # Noise power (in dBm) # External Interference Parameters Pe_dBm = -10000 # transmit power (in dBm) of the ext. interference ext_int_rank = 1 # Rank of the external interference # xxxxxxxxxx General Parameters xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx rep_max = 20000 # Maximum number of repetitions for each pbar = progressbar.ProgressbarText( rep_max, message="Simulating for SNR: {0}".format(SNR_dB))
def test_block_diagonalize_no_waterfilling(self): Nr = np.array([2, 2]) Nt = np.array([2, 2]) K = Nt.size Nti = 1 iPu = 1e-1 # Power for each user (linear scale) pe = 1e-3 # External interference power (in linear scale) noise_var = 1e-1 # The modulator and packet_length are required in the # effective_throughput metric case psk_obj = fundamental.PSK(4) packet_length = 120 multiUserChannel = multiuser.MultiUserChannelMatrixExtInt() multiUserChannel.randomize(Nr, Nt, K, Nti) multiUserChannel.noise_var = noise_var # Channel from all transmitters to the first receiver H1 = multiUserChannel.get_Hk_without_ext_int(0) # Channel from all transmitters to the second receiver H2 = multiUserChannel.get_Hk_without_ext_int(1) # Create the enhancedBD object enhancedBD_obj = blockdiagonalization.EnhancedBD(K, iPu, noise_var, pe) noise_plus_int_cov_matrix \ = multiUserChannel.calc_cov_matrix_extint_plus_noise(pe) # xxxxx First we test without ext. int. handling xxxxxxxxxxxxxxxxxx enhancedBD_obj.set_ext_int_handling_metric(None) (Ms_all, Wk_all, Ns_all) \ = enhancedBD_obj.block_diagonalize_no_waterfilling( multiUserChannel) Ms1 = Ms_all[0] Ms2 = Ms_all[1] self.assertEqual(Ms1.shape[1], Ns_all[0]) self.assertEqual(Ms2.shape[1], Ns_all[1]) # Most likely only one base station (the one with the worst # channel) will employ a precoder with total power of `Pu`, # while the other base stations will use less power. tol = 1e-10 self.assertGreaterEqual(iPu + tol, np.linalg.norm(Ms1, 'fro')**2) # 1e-12 is included to avoid false test fails due to small # precision errors self.assertGreaterEqual(iPu + tol, np.linalg.norm(Ms2, 'fro')**2) # Test if the precoder block diagonalizes the channel self.assertNotAlmostEqual(np.linalg.norm(np.dot(H1, Ms1), 'fro'), 0) self.assertAlmostEqual(np.linalg.norm(np.dot(H1, Ms2), 'fro'), 0) self.assertNotAlmostEqual(np.linalg.norm(np.dot(H2, Ms2), 'fro'), 0) self.assertAlmostEqual(np.linalg.norm(np.dot(H2, Ms1), 'fro'), 0) # Equivalent sinrs (in linear scale) sinrs = np.empty(K, dtype=np.ndarray) sinrs[0] = blockdiagonalization.EnhancedBD._calc_linear_SINRs( np.dot(H1, Ms1), Wk_all[0], noise_plus_int_cov_matrix[0]) sinrs[1] = blockdiagonalization.EnhancedBD._calc_linear_SINRs( np.dot(H2, Ms2), Wk_all[1], noise_plus_int_cov_matrix[1]) # Spectral efficiency # noinspection PyPep8 se = (np.sum( psk_obj.calcTheoreticalSpectralEfficiency(linear2dB( sinrs[0]), packet_length)) + np.sum( psk_obj.calcTheoreticalSpectralEfficiency( linear2dB(sinrs[1]), packet_length))) # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx # xxxxx Now with the Naive Stream Reduction xxxxxxxxxxxxxxxxxxxxxxx num_streams = 1 enhancedBD_obj.set_ext_int_handling_metric( 'naive', {'num_streams': num_streams}) (MsPk_naive_all, Wk_naive_all, Ns_naive_all) \ = enhancedBD_obj.block_diagonalize_no_waterfilling( multiUserChannel) MsPk_naive_1 = MsPk_naive_all[0] MsPk_naive_2 = MsPk_naive_all[1] self.assertEqual(MsPk_naive_1.shape[1], Ns_naive_all[0]) self.assertEqual(MsPk_naive_2.shape[1], Ns_naive_all[1]) self.assertEqual(Ns_naive_all[0], num_streams) self.assertEqual(Ns_naive_all[1], num_streams) # Test if the square of the Frobenius norm of the precoder of each # user is equal to the power available to that user. self.assertAlmostEqual(iPu, np.linalg.norm(MsPk_naive_1, 'fro')**2) self.assertAlmostEqual(iPu, np.linalg.norm(MsPk_naive_2, 'fro')**2) # Test if MsPk really block diagonalizes the channel self.assertNotAlmostEqual( np.linalg.norm(np.dot(H1, MsPk_naive_1), 'fro'), 0) self.assertAlmostEqual(np.linalg.norm(np.dot(H1, MsPk_naive_2), 'fro'), 0) self.assertNotAlmostEqual( np.linalg.norm(np.dot(H2, MsPk_naive_2), 'fro'), 0) self.assertAlmostEqual(np.linalg.norm(np.dot(H2, MsPk_naive_1), 'fro'), 0) sinrs4 = np.empty(K, dtype=np.ndarray) sinrs4[0] = blockdiagonalization.EnhancedBD._calc_linear_SINRs( np.dot(H1, MsPk_naive_1), Wk_naive_all[0], noise_plus_int_cov_matrix[0]) sinrs4[1] = blockdiagonalization.EnhancedBD._calc_linear_SINRs( np.dot(H2, MsPk_naive_2), Wk_naive_all[1], noise_plus_int_cov_matrix[1]) # Spectral efficiency # se4 = ( # np.sum(psk_obj.calcTheoreticalSpectralEfficiency( # linear2dB(sinrs4[0]), # packet_length)) # + # np.sum(psk_obj.calcTheoreticalSpectralEfficiency( # linear2dB(sinrs4[1]), # packet_length))) # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx # xxxxx Now with the Fixed Stream Reduction xxxxxxxxxxxxxxxxxxxxxxx # The 'fixed' metric requires that metric_func_extra_args_dict is # provided and has the 'num_streams' key. If this is not the case # an exception is raised with self.assertRaises(AttributeError): enhancedBD_obj.set_ext_int_handling_metric('fixed') # Now let's test the fixed metric num_streams = 1 enhancedBD_obj.set_ext_int_handling_metric( 'fixed', {'num_streams': num_streams}) (MsPk_fixed_all, Wk_fixed_all, Ns_fixed_all) \ = enhancedBD_obj.block_diagonalize_no_waterfilling( multiUserChannel) MsPk_fixed_1 = MsPk_fixed_all[0] MsPk_fixed_2 = MsPk_fixed_all[1] self.assertEqual(MsPk_fixed_1.shape[1], Ns_fixed_all[0]) self.assertEqual(MsPk_fixed_2.shape[1], Ns_fixed_all[1]) self.assertEqual(Ns_fixed_all[0], num_streams) self.assertEqual(Ns_fixed_all[1], num_streams) # Test if the square of the Frobenius norm of the precoder of each # user is equal to the power available to that user. self.assertAlmostEqual(iPu, np.linalg.norm(MsPk_fixed_1, 'fro')**2) self.assertAlmostEqual(iPu, np.linalg.norm(MsPk_fixed_2, 'fro')**2) # Test if MsPk really block diagonalizes the channel self.assertNotAlmostEqual( np.linalg.norm(np.dot(H1, MsPk_fixed_1), 'fro'), 0) self.assertAlmostEqual(np.linalg.norm(np.dot(H1, MsPk_fixed_2), 'fro'), 0) self.assertNotAlmostEqual( np.linalg.norm(np.dot(H2, MsPk_fixed_2), 'fro'), 0) self.assertAlmostEqual(np.linalg.norm(np.dot(H2, MsPk_fixed_1), 'fro'), 0) sinrs5 = np.empty(K, dtype=np.ndarray) sinrs5[0] = blockdiagonalization.EnhancedBD._calc_linear_SINRs( np.dot(H1, MsPk_fixed_1), Wk_fixed_all[0], noise_plus_int_cov_matrix[0]) sinrs5[1] = blockdiagonalization.EnhancedBD._calc_linear_SINRs( np.dot(H2, MsPk_fixed_2), Wk_fixed_all[1], noise_plus_int_cov_matrix[1]) # Spectral efficiency # se5 = ( # np.sum(psk_obj.calcTheoreticalSpectralEfficiency( # linear2dB(sinrs5[0]), # packet_length)) # + # np.sum(psk_obj.calcTheoreticalSpectralEfficiency( # linear2dB(sinrs5[1]), # packet_length))) # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx # xxxxx Handling external interference xxxxxxxxxxxxxxxxxxxxxxxxxxxx # Handling external interference using the capacity metric enhancedBD_obj.set_ext_int_handling_metric('capacity') (MsPk_all, Wk_cap_all, Ns_cap_all) \ = enhancedBD_obj.block_diagonalize_no_waterfilling( multiUserChannel) MsPk_cap_1 = MsPk_all[0] MsPk_cap_2 = MsPk_all[1] self.assertEqual(MsPk_cap_1.shape[1], Ns_cap_all[0]) self.assertEqual(MsPk_cap_2.shape[1], Ns_cap_all[1]) # Test if the square of the Frobenius norm of the precoder of each # user is equal to the power available to that user. self.assertAlmostEqual(iPu, np.linalg.norm(MsPk_cap_1, 'fro')**2) self.assertAlmostEqual(iPu, np.linalg.norm(MsPk_cap_2, 'fro')**2) # Test if MsPk really block diagonalizes the channel self.assertNotAlmostEqual( np.linalg.norm(np.dot(H1, MsPk_cap_1), 'fro'), 0) self.assertAlmostEqual(np.linalg.norm(np.dot(H1, MsPk_cap_2), 'fro'), 0) self.assertNotAlmostEqual( np.linalg.norm(np.dot(H2, MsPk_cap_2), 'fro'), 0) self.assertAlmostEqual(np.linalg.norm(np.dot(H2, MsPk_cap_1), 'fro'), 0) sinrs2 = np.empty(K, dtype=np.ndarray) sinrs2[0] = blockdiagonalization.EnhancedBD._calc_linear_SINRs( np.dot(H1, MsPk_cap_1), Wk_cap_all[0], noise_plus_int_cov_matrix[0]) sinrs2[1] = blockdiagonalization.EnhancedBD._calc_linear_SINRs( np.dot(H2, MsPk_cap_2), Wk_cap_all[1], noise_plus_int_cov_matrix[1]) # Spectral efficiency # noinspection PyPep8 se2 = (np.sum( psk_obj.calcTheoreticalSpectralEfficiency(linear2dB( sinrs2[0]), packet_length)) + np.sum( psk_obj.calcTheoreticalSpectralEfficiency( linear2dB(sinrs2[1]), packet_length))) # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx # xxxxx Handling external interference xxxxxxxxxxxxxxxxxxxxxxxxxxxx # Handling external interference using the effective_throughput metric enhancedBD_obj.set_ext_int_handling_metric( 'effective_throughput', { 'modulator': psk_obj, 'packet_length': packet_length }) (MsPk_effec_all, Wk_effec_all, Ns_effec_all) \ = enhancedBD_obj.block_diagonalize_no_waterfilling( multiUserChannel) MsPk_effec_1 = MsPk_effec_all[0] MsPk_effec_2 = MsPk_effec_all[1] self.assertEqual(MsPk_effec_1.shape[1], Ns_effec_all[0]) self.assertEqual(MsPk_effec_2.shape[1], Ns_effec_all[1]) # Test if the square of the Frobenius norm of the precoder of each # user is equal to the power available to that user. self.assertAlmostEqual(iPu, np.linalg.norm(MsPk_effec_1, 'fro')**2) self.assertAlmostEqual(iPu, np.linalg.norm(MsPk_effec_2, 'fro')**2) # Test if MsPk really block diagonalizes the channel self.assertNotAlmostEqual( np.linalg.norm(np.dot(H1, MsPk_effec_1), 'fro'), 0) self.assertAlmostEqual(np.linalg.norm(np.dot(H1, MsPk_effec_2), 'fro'), 0) self.assertNotAlmostEqual( np.linalg.norm(np.dot(H2, MsPk_effec_2), 'fro'), 0) self.assertAlmostEqual(np.linalg.norm(np.dot(H2, MsPk_effec_1), 'fro'), 0) sinrs3 = np.empty(K, dtype=np.ndarray) sinrs3[0] = blockdiagonalization.EnhancedBD._calc_linear_SINRs( np.dot(H1, MsPk_effec_1), Wk_effec_all[0], noise_plus_int_cov_matrix[0]) sinrs3[1] = blockdiagonalization.EnhancedBD._calc_linear_SINRs( np.dot(H2, MsPk_effec_2), Wk_effec_all[1], noise_plus_int_cov_matrix[1]) # Spectral efficiency # noinspection PyPep8 se3 = (np.sum( psk_obj.calcTheoreticalSpectralEfficiency(linear2dB( sinrs3[0]), packet_length)) + np.sum( psk_obj.calcTheoreticalSpectralEfficiency( linear2dB(sinrs3[1]), packet_length))) # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx # Test if the effective_throughput obtains a better spectral # efficiency then the capacity and not handling interference. self.assertGreater(se3 + tol, se2) self.assertGreater(se3 + tol, se)
def test_set_ext_int_handling_metric(self): K = 3 iPu = 1e-3 # Power for each user (linear scale) noise_var = 1e-4 pe = 0 # Create the EnhancedBD object enhancedBD_obj = blockdiagonalization.EnhancedBD(K, iPu, noise_var, pe) # xxxxx Test if an assert is raised for invalid arguments xxxxxxxxx with self.assertRaises(AttributeError): enhancedBD_obj.set_ext_int_handling_metric('lala') with self.assertRaises(AttributeError): # If we set the metric to effective_throughput but not provide # the modulator and packet_length attributes. enhancedBD_obj.set_ext_int_handling_metric('effective_throughput') with self.assertRaises(AttributeError): enhancedBD_obj.set_ext_int_handling_metric('naive') # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx # xxxxx Test setting the metric to effective_throughput xxxxxxxxxxx psk_obj = fundamental.PSK(4) enhancedBD_obj.set_ext_int_handling_metric('effective_throughput', { 'modulator': psk_obj, 'packet_length': 120 }) self.assertEqual(enhancedBD_obj._metric_func, blockdiagonalization._calc_effective_throughput) self.assertEqual(enhancedBD_obj.metric_name, "effective_throughput") metric_func_extra_args = enhancedBD_obj._metric_func_extra_args self.assertEqual(metric_func_extra_args['modulator'], psk_obj) self.assertEqual(metric_func_extra_args['packet_length'], 120) # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx # xxxxx Test setting the metric to capacity xxxxxxxxxxxxxxxxxxxxxxx enhancedBD_obj.set_ext_int_handling_metric('capacity') self.assertEqual(enhancedBD_obj._metric_func, calc_shannon_sum_capacity) self.assertEqual(enhancedBD_obj.metric_name, "capacity") # metric_func_extra_args is an empty dictionary for the capacity # metric self.assertEqual(enhancedBD_obj._metric_func_extra_args, {}) # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx # xxxxx Test setting the metric to None xxxxxxxxxxxxxxxxxxxxxxxxxxx enhancedBD_obj.set_ext_int_handling_metric(None) self.assertIsNone(enhancedBD_obj._metric_func) self.assertEqual(enhancedBD_obj.metric_name, "None") # metric_func_extra_args is an empty dictionary for the None metric self.assertEqual(enhancedBD_obj._metric_func_extra_args, {}) # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx # xxxxx Test setting the metric to naive xxxxxxxxxxxxxxxxxxxxxxxxxx enhancedBD_obj.set_ext_int_handling_metric('naive', {'num_streams': 2}) self.assertIsNone(enhancedBD_obj._metric_func) self.assertEqual(enhancedBD_obj.metric_name, "naive") metric_func_extra_args = enhancedBD_obj._metric_func_extra_args self.assertEqual(metric_func_extra_args['num_streams'], 2)
def setUp(self): """Called before each test.""" self.psk_obj = fundamental.PSK(4) self.psk_obj2 = fundamental.PSK(8)
def _update_modulator_object(self, ): """Updates the modulator object whenever M changes """ self.modulator = mod.PSK(self.M)