def test_calc_receive_filter(self): Pu = self.Pu noise_var = self.noise_var num_users = self.num_users # num_antennas = self.num_antennas channel = randn_c(self.iNr, self.iNt) (newH, _) = blockdiagonalization.block_diagonalize(channel, num_users, Pu, noise_var) # W_bd is a block diagonal matrix, where each "small block" is the # receive filter of one user. W_bd = blockdiagonalization.calc_receive_filter(newH) np.testing.assert_array_almost_equal(np.dot(W_bd, newH), np.eye(self.iNt)) # Retest for each individual user W0 = W_bd[0:2, 0:2] newH0 = newH[0:2, 0:2] np.testing.assert_array_almost_equal(np.dot(W0, newH0), np.eye(self.iNt // 3)) W1 = W_bd[2:4, 2:4] newH1 = newH[2:4, 2:4] np.testing.assert_array_almost_equal(np.dot(W1, newH1), np.eye(self.iNt // 3)) W2 = W_bd[4:, 4:] newH2 = newH[4:, 4:] np.testing.assert_array_almost_equal(np.dot(W2, newH2), np.eye(self.iNt // 3))
def test_calc_receive_filter(self): Pu = self.Pu noise_var = self.noise_var num_users = self.num_users # num_antenas = self.num_antenas channel = randn_c(self.iNr, self.iNt) (newH, _) = blockdiagonalization.block_diagonalize( channel, num_users, Pu, noise_var) # W_bd is a block diagonal matrix, where each "small block" is the # receive filter of one user. W_bd = blockdiagonalization.calc_receive_filter(newH) np.testing.assert_array_almost_equal(np.dot(W_bd, newH), np.eye(np.sum(self.iNt))) # Retest for each individual user W0 = W_bd[0:2, 0:2] newH0 = newH[0:2, 0:2] np.testing.assert_array_almost_equal(np.dot(W0, newH0), np.eye(self.iNt/3)) W1 = W_bd[2:4, 2:4] newH1 = newH[2:4, 2:4] np.testing.assert_array_almost_equal(np.dot(W1, newH1), np.eye(self.iNt/3)) W2 = W_bd[4:, 4:] newH2 = newH[4:, 4:] np.testing.assert_array_almost_equal(np.dot(W2, newH2), np.eye(self.iNt/3))
def test_block_diagonalize(self): Pu = self.Pu noise_var = self.noise_var num_users = self.num_users num_antenas = self.num_antenas channel = randn_c(self.iNr, self.iNt) (newH, Ms) = blockdiagonalization.block_diagonalize( channel, num_users, Pu, noise_var) # xxxxx Test if the channel is really block diagonal xxxxxxxxxxxxxx # First we build a 'mask' to filter out the elements in the block # diagonal. A = np.ones([self.iNrk, self.iNtk]) mask = block_diag(A, A, A) # With the mask we can create a masked array of the block # diagonalized channel masked_newH = np.ma.masked_array(newH, mask) # Now we can sum all elements of this masked array (which # effectively means all elements outside the block diagonal) and # see if it is close to zero. self.assertAlmostEqual(0., np.abs(masked_newH).sum()) # xxxxx Now lets test the power restriction xxxxxxxxxxxxxxxxxxxxxxx # Total power restriction total_power = num_users * Pu self.assertGreaterEqual(total_power, np.linalg.norm(Ms, 'fro') ** 2) # Cummulated number of receive antennas cum_Nt = np.cumsum( np.hstack([0, np.ones(num_users, dtype=int) * num_antenas])) # Individual power restriction of each class individual_powers = [] tol = 1e-12 # Tolerance for the GreaterEqual test for i in range(num_users): # Most likelly only one base station (the one with the worst # channel) will employ a precoder a precoder with total power # of `Pu`, while the other base stations will use less power. individual_powers.append( np.linalg.norm( Ms[:, cum_Nt[i]:cum_Nt[i] + num_antenas], 'fro') ** 2) self.assertGreaterEqual(Pu + tol, individual_powers[-1])
def test_block_diagonalize(self): Pu = self.Pu noise_var = self.noise_var num_users = self.num_users num_antennas = self.num_antennas channel = randn_c(self.iNr, self.iNt) (newH, Ms) = blockdiagonalization.block_diagonalize(channel, num_users, Pu, noise_var) # xxxxx Test if the channel is really block diagonal xxxxxxxxxxxxxx # First we build a 'mask' to filter out the elements in the block # diagonal. A = np.ones([self.iNrk, self.iNtk]) mask = block_diag(A, A, A) # With the mask we can create a masked array of the block # diagonalized channel masked_newH = np.ma.masked_array(newH, mask) # Now we can sum all elements of this masked array (which # effectively means all elements outside the block diagonal) and # see if it is close to zero. self.assertAlmostEqual(0., np.abs(masked_newH).sum()) # xxxxx Now lets test the power restriction xxxxxxxxxxxxxxxxxxxxxxx # Total power restriction total_power = num_users * Pu self.assertGreaterEqual(total_power, np.linalg.norm(Ms, 'fro')**2) # accumulated number of receive antennas cum_Nt = np.cumsum( np.hstack([0, np.ones(num_users, dtype=int) * num_antennas])) # Individual power restriction of each class individual_powers = [] tol = 1e-12 # Tolerance for the GreaterEqual test for i in range(num_users): # Most likely only one base station (the one with the worst # channel) will employ a precoder a precoder with total power # of `Pu`, while the other base stations will use less power. individual_powers.append( np.linalg.norm(Ms[:, cum_Nt[i]:cum_Nt[i] + num_antennas], 'fro')**2) self.assertGreaterEqual(Pu + tol, individual_powers[-1])
# Randomize users channels multiuser_channel.randomize(Nr, Nt, num_cells, ext_int_rank) multiuser_channel.set_pathloss(pathloss, pathlossInt) multiuser_channel.noise_var = noise_var # Generate input data and modulate it input_data = np.random.randint(0, M, [np.sum(Ns_BD), NSymbs]) symbols = modulator.modulate(input_data) # Perform the Block Diagonalization of the channel (newH, Ms) = blockdiagonalization.block_diagonalize( # We only add the first np.sum(Nt) columns of big_H # because the remaining columns come from the external # interference sources, which don't participate in the Block # Diagonalization Process. multiuser_channel.big_H[:, 0 : np.sum(Nt)], num_cells, transmit_power, # noise_var 1e-50, ) # Prepare the transmit data. precoded_data = np.dot(Ms, symbols) external_int_data = np.sqrt(pe) * misc.randn_c(ext_int_rank, NSymbs) all_data = np.vstack([precoded_data, external_int_data]) # Pass the precoded data through the channel received_signal = multiuser_channel.corrupt_concatenated_data(all_data) # Filter the received data
for rep in range(rep_max): # Randomize users channels multiuser_channel.randomize(Nr, Nt, num_cells, ext_int_rank) multiuser_channel.set_pathloss(pathloss, pathlossInt) multiuser_channel.noise_var = noise_var # Generate input data and modulate it input_data = np.random.randint(0, M, [np.sum(Ns_BD), NSymbs]) symbols = modulator.modulate(input_data) # Perform the Block Diagonalization of the channel (newH, Ms) = blockdiagonalization.block_diagonalize( # We only add the first np.sum(Nt) columns of big_H # because the remaining columns come from the external # interference sources, which don't participate in the Block # Diagonalization Process. multiuser_channel.big_H[:, 0:np.sum(Nt)], num_cells, transmit_power, # noise_var 1e-50) # Prepare the transmit data. precoded_data = np.dot(Ms, symbols) external_int_data = np.sqrt(pe) * misc.randn_c(ext_int_rank, NSymbs) all_data = np.vstack([precoded_data, external_int_data]) # Pass the precoded data through the channel received_signal = multiuser_channel.corrupt_concatenated_data(all_data) # Filter the received data receive_filter = np.linalg.pinv(newH)