def __init__(self, read_command_line_args=True, save_parsed_file=False): default_config_file = 'bd_config_file.txt' # xxxxxxxxxx Simulation Parameters Specification xxxxxxxxxxxxxxxxxx spec = """[Grid] cell_radius=float(min=0.01, default=1.0) num_cells=integer(min=3,default=3) num_clusters=integer(min=1,default=1) [Scenario] NSymbs=integer(min=10, max=1000000, default=500) SNR=real_numpy_array(min=-50, max=100, default=0:3:31) Pe_dBm=real_numpy_array(min=-50, max=100, default=[-10. 0. 10.]) Nr=integer(default=2) Nt=integer(default=2) N0=float(default=-116.4) ext_int_rank=integer(min=1,default=1) user_positioning_method=option("Random", 'Symmetric Far Away', default="Symmetric Far Away") [Modulation] M=integer(min=4, max=512, default=4) modulator=option('QPSK', 'PSK', 'QAM', 'BPSK', default="PSK") packet_length=integer(min=1,default=60) [General] rep_max=integer(min=1, default=5000) unpacked_parameters=string_list(default=list('SNR','Pe_dBm')) """.split("\n") # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx # xxxxxxxxxx Initialize parameters configuration xxxxxxxxxxxxxxxxxx # Among other things, this will create the self.params object with # the simulation parameters read from the config file. SimulationRunner.__init__( self, default_config_file=default_config_file, config_spec=spec, read_command_line_args=read_command_line_args, save_parsed_file=save_parsed_file) # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx # xxxxxxxxxx Channel Parameters xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx self.path_loss_obj = pathloss.PathLoss3GPP1() self.multiuser_channel = multiuser.MultiUserChannelMatrixExtInt() # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx # xxxxxxxxxx RandomState objects seeds xxxxxxxxxxxxxxxxxxxxxxxxxxxx # This is only useful to reproduce a simulation for debugging # purposed channel_seed = None # 22522 self.noise_seed = None # 4445 self.data_gen_seed = np.random.randint(10000) # 2105 ext_data_gen_seed = None # 6114 # self.multiuser_channel.set_channel_seed(channel_seed) self.multiuser_channel.set_noise_seed(self.noise_seed) self.data_RS = np.random.RandomState(self.data_gen_seed) self.ext_data_RS = np.random.RandomState(ext_data_gen_seed) # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx # xxxxxxxxxx Creates the modulator object xxxxxxxxxxxxxxxxxxxxxxxxx M = self.params['M'] modulator_options = { 'PSK': fundamental.PSK, 'QPSK': fundamental.QPSK, 'QAM': fundamental.QAM, 'BPSK': fundamental.BPSK } self.modulator = modulator_options[self.params['modulator']](M) ":type: fundamental.PSK | fundamental.QPSK | fundamental.QAM | fundamental.BPSK" # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx # xxxxxxxxxx General Parameters xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx # Maximum number of repetitions for each unpacked parameters set # self.params self.results self.rep_max = self.params['rep_max'] # # max_bit_errors is used in the _keep_going method to stop the # # simulation earlier if possible. We stop the simulation if the # # accumulated number of bit errors becomes greater then 5% of the # # total number of simulated bits # self.max_bit_errors = self.rep_max * NSymbs * 5. / 100. self.progressbar_message = "SNR: {SNR}, Pe_dBm: {Pe_dBm}" # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx # xxxxxxxxxx Dependent parameters (don't change these) xxxxxxxxxxxx # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx # These two will be set in the _on_simulate_current_params_start # method self.pe = 0 # Path loss (in linear scale) from the cell center to # self.path_loss_border = self.path_loss_obj.calc_path_loss( # self.cell_radius) # Cell Grid self.cell_grid = cell.Grid() self.cell_grid.create_clusters(self.params['num_clusters'], self.params['num_cells'], self.params['cell_radius']) self.noise_var = dBm2Linear(self.params['N0']) self.multiuser_channel.noise_var = self.noise_var # This can be either 'screen' or 'file'. If it is 'file' then the # progressbar will write the progress to a file with appropriated # filename self.progress_output_type = 'screen'
import pyphysim.channels.multiuser tic = time() # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx # xxxxxxxxxxxxxxx Simulation Parameters xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx # 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
def perform_simulation_SINR_heatmap( scenario_params, # pylint: disable=R0914 power_params): """ Perform the simulation. Parameters ---------- scenario_params : dict Dictionary with the scenario parameters. power_params : dict Dictionary with the power related parameters. Returns ------- tuple[np.ndarray] Tuple with 4 numpy arrays with the results. """ # xxxxxxxxxx Simulation Scenario Configuration xxxxxxxxxxxxxxxxxxxxxxxx # The size of the side of each square room side_length = scenario_params['side_length'] # How much (in dB) is lost for each wall teh signal has to pass single_wall_loss_dB = scenario_params['single_wall_loss_dB'] # Square of 12 x 12 square rooms num_rooms_per_side = scenario_params['num_rooms_per_side'] # Total number of rooms in the grid num_rooms = num_rooms_per_side**2 # 1 means 1 ap every room. 2 means 1 ap every 2 rooms and so on. Valid # values are: 1, 2, 4 and 9. ap_decimation = scenario_params['ap_decimation'] # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx # xxxxxxxxxx Simulation Power Configuration xxxxxxxxxxxxxxxxxxxxxxxxxxx # Transmit power of each access point Pt_dBm = power_params['Pt_dBm'] noise_power_dBm = power_params['noise_power_dBm'] Pt = dBm2Linear(Pt_dBm) # 20 dBm transmit power noise_var = dBm2Linear(noise_power_dBm) # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx # xxxxxxxxxx Discretization of the possible positions xxxxxxxxxxxxxxxxx num_discrete_positions_per_room = 15 # Number of discrete positions step = 1. / num_discrete_positions_per_room aux = np.linspace(-(1. - step), (1. - step), num_discrete_positions_per_room) aux = np.meshgrid(aux, aux, indexing='ij') ":type: np.ndarray" user_relative_positions = aux[1] + 1j * aux[0][::-1] # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx # xxxxxxxxxx Calculate the positions of all rooms xxxxxxxxxxxxxxxxxxxxx room_positions = calc_room_positions_square(side_length, num_rooms) room_positions.shape = (num_rooms_per_side, num_rooms_per_side) # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx # xxxxxxxxxx Create the path loss object xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx pl_3gpp_obj = pathloss.PathLoss3GPP1() pl_free_space_obj = pathloss.PathLossFreeSpace() pl_3gpp_obj.handle_small_distances_bool = True pl_free_space_obj.handle_small_distances_bool = True pl_metis_ps7_obj = pathloss.PathLossMetisPS7() pl_metis_ps7_obj.handle_small_distances_bool = True # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx # xxxxxx Add one user in each discrete position of each room xxxxxxxxxx user_relative_positions2 = user_relative_positions * side_length / 2. user_positions = (room_positions[:, :, np.newaxis, np.newaxis] + user_relative_positions2[np.newaxis, np.newaxis, :, :]) # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx # xxxxxxxxxx AP Allocation xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx # 1 AP in each room ap_positions = get_ap_positions(room_positions, ap_decimation) num_aps = ap_positions.size # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx # xxxxxxxxxx Calculate distances: each user to each AP xxxxxxxxxxxxxxxx # Dimension: (room_row, room_c, user_row, user_col, num_APs) dists_m = np.abs(user_positions[:, :, :, :, np.newaxis] - ap_positions.reshape([1, 1, 1, 1, -1])) # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx # xxxxxxxxxx Calculate AP association xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx # Determine with which AP each user is associated with. # Each user will associate with the CLOSEST access point. ap_assoc = np.argmin(dists_m, axis=-1) # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx # xxxxxxxxxx Calculate wall losses xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx # We want to calculate the number walls from each room to the rooms # which have an access point. # Dimension is (num_rooms, num_aps) num_walls = calc_num_walls(side_length, room_positions, ap_positions) # Reshape it to (num_rooms_per_side, num_rooms_per_side, 1, 1, num_aps) num_walls_extended = num_walls.reshape( [num_rooms_per_side, num_rooms_per_side, 1, 1, num_aps]) # And finally broadcast the (1, 1) dimensions to the number of users # per room. This will make num_walls_extended have the same dimension # as dists_m. num_walls_extended, _ = np.broadcast_arrays(num_walls_extended, dists_m) wall_losses_dB = num_walls_extended * single_wall_loss_dB # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx # xxxxxxxxxx Calculate the path losses xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx # The METIS PS7 path loss model require distance values in meters, # while the others are in Kms. All distances were calculates in meters # and, therefore, we divide the distance in by 1000 for 3GPP and free # space. pl_3gpp = pl_3gpp_obj.calc_path_loss(dists_m / 1000.) pl_free_space = pl_free_space_obj.calc_path_loss(dists_m / 1000.) pl_nothing = np.ones([ num_rooms_per_side, num_rooms_per_side, num_discrete_positions_per_room, num_discrete_positions_per_room, num_aps ], dtype=float) # We need to know the number of walls the signal must pass to reach the # receiver to calculate the path loss for the METIS PS7 model. pl_metis_ps7 = pl_metis_ps7_obj.calc_path_loss( dists_m, num_walls=num_walls_extended) # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx # xxxxxxxxxx Calculate the SINRs for each path loss model xxxxxxxxxxxxx sinr_array_pl_nothing_dB = simulate_for_a_given_ap_assoc( pl_nothing, ap_assoc, wall_losses_dB, Pt, noise_var) sinr_array_pl_3gpp_dB = simulate_for_a_given_ap_assoc( pl_3gpp, ap_assoc, wall_losses_dB, Pt, noise_var) sinr_array_pl_free_space_dB = simulate_for_a_given_ap_assoc( pl_free_space, ap_assoc, wall_losses_dB, Pt, noise_var) sinr_array_pl_metis_ps7_dB = simulate_for_a_given_ap_assoc( pl_metis_ps7, ap_assoc, wall_losses_dB, Pt, noise_var) # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx out = (sinr_array_pl_nothing_dB, sinr_array_pl_3gpp_dB, sinr_array_pl_free_space_dB, sinr_array_pl_metis_ps7_dB) return out
def __init__(self, default_config_file, read_command_line_args=True): """ Constructor of the IASimulationRunner class. """ spec = """[Grid] cell_radius=float(min=0.01, default=1.0) num_cells=integer(min=3,default=3) num_clusters=integer(min=1,default=1) [Scenario] NSymbs=integer(min=10, max=1000000, default=200) SNR=real_numpy_array(min=-50, max=100, default=0:5:31) M=integer(min=4, max=512, default=4) modulator=option('QPSK', 'PSK', 'QAM', 'BPSK', default="PSK") Nr=integer_scalar_or_integer_numpy_array_check(min=2,default=3) Nt=integer_scalar_or_integer_numpy_array_check(min=2,default=3) Ns=integer_scalar_or_integer_numpy_array_check(min=1,default=3) N0=float(default=-116.4) scenario=string_list(default=list('Random', 'NoPathLoss')) [IA Algorithm] max_iterations=integer(min=1, default=120) initialize_with=string_list(default=list('random')) stream_sel_method=string_list(default=list('greedy', 'brute')) [General] rep_max=integer(min=1, default=2000) max_bit_errors=integer(min=1, default=3000) unpacked_parameters=string_list(default=list('SNR','stream_sel_method','scenario','initialize_with')) """.split("\n") SimulationRunner.__init__(self, default_config_file, spec, read_command_line_args) # xxxxxxxxxx General Parameters xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx # Maximum number of repetitions for each unpacked parameters set self.rep_max = self.params['rep_max'] # # max_bit_errors is used in the _keep_going method to stop the # # simulation earlier if possible. We stop the simulation if the # # accumulated number of bit errors becomes greater then 5% of the # # total number of simulated bits # self.max_bit_errors = self.params['max_bit_errors'] # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx # xxxxxxxxxx Channel and Path Loss Parameters xxxxxxxxxxxxxxxxxxxxx # Create the channel object self.multiUserChannel = multiuser.MultiUserChannelMatrix() # Create the Path loss object self.path_loss_obj = pathloss.PathLoss3GPP1() # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx # xxxxxxxxxx RandomState objects seeds xxxxxxxxxxxxxxxxxxxxxxxxxxxx # This is only useful to reproduce a simulation for debugging # purposed self.channel_seed = None # 22522 self.noise_seed = None # 4445 self.data_gen_seed = np.random.randint(10000) # 2105 # self.multiUserChannel.set_channel_seed(self.channel_seed) self.multiUserChannel.set_noise_seed(self.noise_seed) self.data_RS = np.random.RandomState(self.data_gen_seed) # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx # xxxxxxxxxx Create the modulator object xxxxxxxxxxxxxxxxxxxxxxxxxx M = self.params['M'] modulator_options = { 'PSK': fundamental.PSK, 'QPSK': fundamental.QPSK, 'QAM': fundamental.QAM, 'BPSK': fundamental.BPSK } self.modulator = modulator_options[self.params['modulator']](M) # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx # xxxxxxxxxx Progress Bar xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx # This can be either 'screen' or 'file'. If it is 'file' then the # progressbar will write the progress to a file with appropriated # filename self.progress_output_type = 'screen' # Set the progressbar message self.progressbar_message = "SNR: {{SNR}}".format(self.modulator.name) # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx # xxxxxxxxxx Dependent parameters (don't change these) xxxxxxxxxxxx # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx # Cell Grid self.cell_grid = cell.Grid() self.cell_grid.create_clusters(self.params['num_clusters'], self.params['num_cells'], self.params['cell_radius']) # Note that the Noise variance will be set in the # _on_simulate_current_params_start method. In the NoPathLoss # scenario it will be set as 1.0 regardless of the value of # params['N0'] to avoid problems in the IA algorithms. In the other # scenarios it will be set to self.params['N0']. # # In any case the transmit power will be calculated accordingly in # the _run_simulation method and the simulation results will still # be correct. self.noise_var = None # Linear path loss from cell center to cell border. self._path_loss_border = self.path_loss_obj.calc_path_loss( self.params['cell_radius']) # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx # TODO: Move code below to the _on_simulate_current_params_start # method # xxxxxxxxxx Interference Alignment objects xxxxxxxxxxxxxxxxxxxxxxx # Create the basic IA Solver object self.ia_solver = algorithms.MMSEIASolver(self.multiUserChannel) # This will be created in the _on_simulate_current_params_start # method. The class of self.ia_top_object will depend on the value # of the 'stream_sel_method' parameter self.ia_top_object = None