def create_purs(pu_id: str, pur_number: int, pur_min_dist: float, pur_max_dist: float, pur_threshold: float, pur_beta: float, pur_height: float) -> List[PUR]: purs = [] angle = float(360/pur_number) for i in range(pur_number): purs.append(PUR(pu_id=pu_id, pur_id=i, rx=RX(element=Element(location=Point(PolarPoint(uniform(pur_min_dist, pur_max_dist), i * math.radians(angle))), height=pur_height)), threshold=pur_threshold, beta=pur_beta)) return purs
def compute_purs_powers(self): # calculate received powers at PURs tmp_pus = [tmp_pu for tmp_pu in self.pus if tmp_pu.ON] for pu in tmp_pus: pu.reset_purs() for pur in pu.purs: pur_element = RX( Element(pu.tx.element.location + pur.rx.element.location, pur.rx.element.height)) # pur location is relational and it should be updated first pur.rx.received_power = self.power_with_path_loss( tx=pu.tx, rx=pur_element) for npu in tmp_pus: # power received from other PUs if pu != npu: npu_pur_loss = self.propagation_model.path_loss( tx=npu.tx.element * self.cell_size, rx=pur_element.element * self.cell_size) pur.add_interference(npu.id, npu.tx.power - npu_pur_loss) # compute max power power for SUs except the last one, O(#su * #pus * #sus) for i in range(len(self.sus) - 1): # get max_power for su su = self.sus[i] su.tx.power = self.calculate_max_power(su) if su.tx.power == -float('inf'): continue # update irp for purs for pu in tmp_pus: for pur in pu.purs: pur_element = RX( Element( pu.tx.element.location + pur.rx.element.location, pur.rx.element.height)) su_pur_loss = self.propagation_model.path_loss( tx=su.tx.element * self.cell_size, rx=pur_element.element * self.cell_size) pur.add_interference(su.id, su.tx.power - su_pur_loss)
def calculate_max_power(self, su: SU) -> float: """Calculate the maximum power(dB) SU can send.""" pus = [tmp_pu for tmp_pu in self.pus if tmp_pu.ON] max_pow = float( 'inf' ) # find the minimum possible without bringing any interference for pu in pus: for pur in pu.purs: pur_element = RX( Element(pu.tx.element.location + pur.rx.element.location, pur.rx.element.height)) # pur location is relational and it should be updated first su_power_at_pur = pur.get_interference_capacity() loss = self.propagation_model.path_loss( tx=su.tx.element * self.cell_size, rx=pur_element.element * self.cell_size) su_power_at_su = su_power_at_pur + loss max_pow = min(max_pow, su_power_at_su) return max_pow
def compute_field_power( self ) -> List[List[ float]]: # calculate received power at specific locations all over the # field to create a heatmap # TODO fix this part before using received_power = [] [min_x, min_y] = [0, 0] # self.corners[0].get_cartesian [max_x, max_y] = [1, 2] # self.corners[-1].get_cartesian for y in range(min_y, max_y, min(1, max(1, (max_y - min_y) // 400))): tmp = [] for x in range(min_x, max_x, min(1, max(1, (max_x - min_x) // 400))): pwr_tmp = -float('inf') for pu in self.pus: pwr_tmp = self.power_with_path_loss( tx=pu.tx, rx=RX(Element(Point((x, y)), 15))) tmp.append(pwr_tmp) received_power.append(tmp) return received_power
def su_request_accept(self) -> bool: # sign: bool=True sign here is temporary and just for create an unreal situation in which learning would fail # option = 0 # 0 means using BETA, 1 means using threshold su = self.sus[-1] for pu in [tmp_pu for tmp_pu in self.pus if tmp_pu.ON]: for pur in pu.purs: if pur.get_interference_capacity() == -float('inf'): continue # TODO reconsider this case(False should be returned). No interference should be allowed pur_element = RX( Element(pu.tx.element.location + pur.rx.element.location, pur.rx.element.height)) su_pur_loss = self.propagation_model.path_loss( tx=su.tx.element * self.cell_size, rx=pur_element.element * self.cell_size) pur.add_interference(su.id, su.tx.power - su_pur_loss) if pur.get_interference_capacity() == -float('inf'): pur.delete_interference_power_from(su.id) return False pur.delete_interference_power_from(su.id) return True
def conservative_model_power(self, min_power: float, noise_floor=-90): send_power = float('inf') su = self.sus[ -1] # TODO this code has written for only one SU. Fix for multiple before using it # upper bound should be calculated based on purs not pus. Assume there is minimum power at a PU; # should calculate min(pur_pow/beta) pus = [pu for pu in self.pus if pu.ON] for pu in pus: for pur in pu.purs: pur_element = RX( Element(pu.tx.element.location + pur.rx.element.location, pur.rx.element.height)) pow_tmp = self.power_with_path_loss(tx=TX( pu.tx.element, min_power), rx=pur_element) send_power = min(send_power, pow_tmp / pur.beta) for pu in pus: su_rx = RX(su.tx.element) power_at_su_from_pus = self.power_with_path_loss(tx=pu.tx, rx=su_rx) if power_at_su_from_pus > noise_floor: return noise_floor # there is already a signal, su cannot send anything. return send_power # all powers from pus is still less than threshold, su can send power
def create_sensors(path: str, sensor_height) -> List[Sensor]: sss = [] try: with open(path, 'r') as f: # max_gain = 0.5 * num_intruders # len(self.transmitters) # index = 0 lines = f.readlines() for line_idx, line in enumerate(lines): inputs = line.split(' ') x, y, std, cost = float(inputs[0]), float(inputs[1]), float( inputs[2]), float(inputs[3]) sss.append( Sensor(ss_id=line_idx, rx=RX( Element(location=Point(CartesianPoint(x, y)), height=sensor_height)), cost=cost, std=std)) except FileNotFoundError: raise ValueError('Sensor file does not exist') except IndexError as e: raise ValueError( 'The file given is not in correct format of x y std cost') return sss
@property def cost(self): return self.__cost @cost.setter def cost(self, cost: float): self.__cost = cost @property def std(self): return self.__std @std.setter def std(self, std: float): self.__std = std def __str__(self): return "id= {0}\n".format(self.id) + \ "{0}\n".format(self.rx) + \ "cost= {0}\n".format(self.cost) + \ "std= {0}\n".format(self.std) if __name__ == "__main__": ss = Sensor(ss_id=15, rx=RX(Element(location=Point((1, 5)), height=15)), cost=15, std=1) print(ss)
# return float(itm_pl) if float(itm_pl) != 0.0 else float(free_pl) # old version return pl_value @staticmethod def process_output(file_name): positive_float = r'(\d+\.\d+)' free_space_pattern = r'Free space.*\D{}.*'.format(positive_float) itm_pattern = r'ITWOM Version 3.0.*\D{}.*'.format(positive_float) free_p = re.compile(free_space_pattern) itm_p = re.compile(itm_pattern) with open(file_name, encoding="ISO-8859-1", mode='r') as f: content = f.read() free_m = free_p.search(content) free_pl = free_m.group(1) if free_m else 0 itm_m = itm_p.search(content) itm_pl = itm_m.group(1) if itm_m else 0 return free_pl, itm_pl def __str__(self): "SPLAT! PM:\nUpper-left corner:{}".format(self.upper_left_ref) if __name__ == "__main__": # 40.800595, -73.107507 top_left_ref = GeographicPoint(40.800595, 73.107507) splat = SPLAT(top_left_ref) # splat.generate_sdf_files() free_pl, itm_pl = splat.path_loss(Element(Point((180, 170)), 300), Element(Point((100, 100)), 15)) print('free path loss:', free_pl, ', itm path loss:', itm_pl)
thr_decimal = get_decimal(self.threshold) return get_db(thr_decimal - irp_decimal) def __str__(self): r, theta = self.rx.element.location.polar.r, self.rx.element.location.polar.theta return "id= {pur_id}\n".format(pur_id=self.__id) + \ "relative location= ({r},{theta})\n".format(r=round(r, 3), theta=round(theta, 3)) +\ "height= {height}\n".format(height=self.rx.element.height) +\ "threshold= {thr}\n".format(thr=self.__thr) +\ "beta= {beta}\n".format(beta=self.__beta) +\ "received power= {rp}\n".format(rp=self.rx.received_power) +\ "received interference= {irp}".format(irp=self.__irp) if __name__ == "__main__": pur = PUR('PU10', 1, RX(Element(location=Point(PolarPoint(5, 0)), height=15)), beta=1) print(pur) pur.received_power = -25 pur.add_interference('PU110', -30) print(pur) pur.add_interference('PU110', -35) pur.update_interference('PU110', -35) print(pur) pur.update_interference('PU10', -30) pur.add_interference('PU10', -30) pur.delete_interference_power_from('PU110') print(pur)
def interpolation_max_power(self, inter_sm_param: InterSMParam): k_pu = self.num_select(inter_sm_param.pu_size, len(self.pus)) k_ss = self.num_select(inter_sm_param.ss_size, len(self.sss)) su = self.sus[ -1] # TODO this code has written for only one SU. Fix for multiple before using it if type( self.propagation_model ) == LogDistancePM: # TODO only written for LogNormal Propagation Model pl_alpha = self.propagation_model.alpha else: raise ValueError("Only Log-Distance has been implemented") pu_inds, sss_inds, sss_dists = [], [], [] if not inter_sm_param.selection_algo: pu_inds = list(range(k_pu)) sss_inds = list(range(k_ss)) sss_dists = [ self.cell_size * su.tx.element.location.distance( self.sss[i].rx.element.location) for i in range(k_ss) ] elif inter_sm_param.selection_algo.lower() == 'sort': pu_dists = [] for i, pu in enumerate(self.pus): dist, ind = self.cell_size * su.tx.element.location.distance( pu.tx.element.location), i if i < k_pu: pu_inds.append(i) pu_dists.append(dist) else: for j in range(len(pu_inds)): if dist < pu_dists[j]: pu_dists[j], dist = dist, pu_dists[j] ind, pu_inds[j] = pu_inds[j], ind for i, ss in enumerate(self.sss): dist, ind = self.cell_size * su.tx.element.location.distance( ss.rx.element.location), i if i < k_ss: sss_inds.append(i) sss_dists.append(dist) else: for j in range(len(sss_inds)): if dist < sss_dists[j]: sss_dists[j], dist = dist, sss_dists[j] ind, sss_inds[j] = sss_inds[j], ind elif inter_sm_param.selection_algo.lower() == 'random': pu_inds = sample(range(len(self.pus)), k_pu) pu_dists = [ self.cell_size * su.tx.element.location.distance( self.pus[i].tx.element.location) for i in pu_inds ] sss_inds = sample(range(len(self.sss)), k_ss) sss_dists = [ self.cell_size * su.tx.element.location.distance( self.sss[i].rx.element.location) for i in sss_inds ] else: print('Unsupported selection algorithm!') return None # end selection # compute weights weights, tmp_sum_weight = [], 0.0 for ss_dist in sss_dists: d = ss_dist d = max(d, 0.0001) # TODO why 0.0001? # Weight of this SS with respect to this SU w = (1.0 / d)**pl_alpha weights.append(w) tmp_sum_weight += w # BY ME received_powers = [] pl_pu_ss = [] for i, ss_idx in enumerate(sss_inds): tmp_ss, all_power, tmp_pl_pu_ss = [], 0, [] for j, pu_idx in enumerate(pu_inds): tmp = get_decimal(self.pus[pu_idx].tx.power) / \ (self.cell_size * self.pus[pu_idx].tx.element.location.distance(self.sss[ss_idx].rx.element.location)) ** pl_alpha tmp_ss.append(tmp) all_power += tmp tmp_pl_pu_ss.append(get_decimal(self.pus[pu_idx].tx.power)) # tmp_pow = power_with_path_loss(TRX(pus[pu_idx].loc, pus[pu_idx].p), TRX(sss[ss_ # idx].loc, -float('inf')), # propagation_model=propagation_model, noise=noise) # # tmp_pow = max(tmp_pow, noise_floor) # tmp_ss.append(tmp_pow) received_powers.append([ get_decimal(self.sss[ss_idx].rx.received_power) / all_power * x for x in tmp_ss ]) pl_pu_ss.append( [x / y for x in tmp_pl_pu_ss for y in received_powers[-1]]) # Compute SU transmit power # tp = thresh * sum(w(SS)) / sum(r(SS) / t(PU) * w(SS)) max_transmit_power, estimated_path_loss = float('inf'), [] for y, j in enumerate(pu_inds): sum_weight = 0.0 sum_weighted_ratio = 0.0 for x, i in enumerate(sss_inds): sum_weight += weights[x] # only DB is implemented here sum_weighted_ratio += weights[x] * ( received_powers[i][j] / get_decimal(self.pus[j].tx.power)) this_pu_path_loss = sum_weighted_ratio / sum_weight # estimated_path_loss_tmp = [] for x, pur in enumerate(self.pus[j].purs): pur_element = Element( self.pus[j].tx.element.location + pur.rx.element.location, pur.rx.element.height) this_pr_path_loss = this_pu_path_loss - inter_sm_param.gamma * \ get_db(self.cell_size * su.tx.element.location.distance(pur_element.location) / su.tx.element.location.distance(self.pus[j].tx.element.location)) # this_pr_path_loss = this_pu_path_loss - 10.0 * inter_sm_param.gamma * \ # math.log10(cell_size * su.loc.distance(pur_location) / # (cell_size * su.loc.distance(pus[j].loc))) # estimated_path_loss_tmp.append(this_pr_path_loss) # this_transmit_power = pur.thr - this_pr_path_loss this_transmit_power = pur.rx.received_power/pur.beta - pur.interference_received_power + \ this_pr_path_loss max_transmit_power = min(max_transmit_power, this_transmit_power) # estimated_path_loss.append(estimated_path_loss_tmp) return max_transmit_power
@staticmethod def create_purs(pu_id: str, pur_number: int, pur_min_dist: float, pur_max_dist: float, pur_threshold: float, pur_beta: float, pur_height: float) -> List[PUR]: purs = [] angle = float(360/pur_number) for i in range(pur_number): purs.append(PUR(pu_id=pu_id, pur_id=i, rx=RX(element=Element(location=Point(PolarPoint(uniform(pur_min_dist, pur_max_dist), i * math.radians(angle))), height=pur_height)), threshold=pur_threshold, beta=pur_beta)) return purs def __str__(self): return "{loc},{power}".format(loc=str(self.tx.element.location), power=round(self.tx.power, 3)) if __name__ == "__main__": <<<<<<< HEAD pu1 = PU(Point(5,5), 10, 13, 2, 10) for i in range(pu1.n): print(str(i+1), "(", pu1.purs[i].loc.get_cartesian[0], ",", pu1.purs[i].loc.get_cartesian[1],")", pu1.loc.distance(pu1.purs[i].loc)) ======= pu1 = PU(pu_id=10, tx=TX(element=Element(location=Point(CartesianPoint(5, 5)), height=15), power=-5), pur_num=16, pur_beta=1.0, pur_dist=[1, 3], pur_height=15) print(pu1) for idx, pur in enumerate(pu1.purs): pur_location = pu1.tx.element.location + pur.rx.element.location print("{0}. ({1}), {2}".format(idx+1, str(pur_location), pu1.tx.element.location.distance(pur_location))) >>>>>>> 2f6fbc9e82c377be81183e276e9e45d79365b964
# loss += 0 if distance == 0 else self.__shadow_amp * sin( # 2 * pi * distance / self.__dist_period) # add shadowing if self.is_noisy: # add multipath loss += gauss(0, self.std) return loss def __str__(self): return "Log-Distance(Normal):\n" +\ "Path-Loss Coeff.= {0}\n".format(self.alpha) +\ "Path-Loss reference {0} in distance reference {1}\n".format(self.pl_ref, self.dist_ref) +\ ("std= {0}" if self.is_noisy else "").format(self.std if self.is_noisy else None) if __name__ == "__main__": log_pm = LogDistancePM(2.0, True, 1) print(log_pm) print( log_pm.path_loss(Element(Point((0, 0)), 15), Element(Point((10, 10)), 15))) # log_pm.is_noisy = False print(log_pm) print(hasattr(log_pm, 'alpha')) x = [i / 10 for i in range(10, 1000)] fig = plt.figure() ax = fig.add_subplot(1, 1, 1) ax.plot(x, [ log_pm.path_loss(Element(Point( (1, 1)), 15), Element(Point((1, 1)) * i, 15)) for i in x ]) ax.set_xscale('log') plt.show()