Loading prrt/hec_search.py +95 −3 Original line number Diff line number Diff line Loading @@ -102,10 +102,11 @@ class HECFullSearch(AbstractSearch): return residual_packet_erasure_rate class HECGreedySearch(AbstractSearch): def __init__(self, n_p_max, prrtApplicationParameters, prrtChannelParameters, prrtSystemParameters): class HECReducedSpaceSearch(AbstractSearch): def __init__(self, n_p_min, n_p_max, prrtApplicationParameters, prrtChannelParameters, prrtSystemParameters): self.n_max = 255 self.step_size = 2 # Step size in the estimation of the optimum code word length self.n_p_min = n_p_min self.n_p_max = n_p_max self.prrtApplicationParameters = prrtApplicationParameters self.prrtChannelParameters = prrtChannelParameters Loading Loading @@ -138,7 +139,7 @@ class HECGreedySearch(AbstractSearch): k_max = min(self.get_k(n_c, req_delay), self.get_k_lim(1, self.n_max)) for k in [1, k_max]: n = self.estimate_n_for_k(k) repair_schedules = ric.gen_repair_schedule(n - k, n_c, 1, self.n_p_max, self.is_order_ascending) repair_schedules = ric.gen_repair_schedule(n - k, n_c, self.n_p_min, self.n_p_max, self.is_order_ascending) for repair_schedule in repair_schedules: coding_conf = prrt.PrrtCodingConfiguration(n, k, repair_schedule) ri = coding_conf.get_redundant_information(self.prrtChannelParameters) Loading Loading @@ -192,3 +193,94 @@ class HECGreedySearch(AbstractSearch): total_packet_erasure += packet_erasure_at_i residual_packet_erasure_rate = (1 / k) * total_packet_erasure # Pr(k, n) return residual_packet_erasure_rate class HECGreadySearch(AbstractSearch): def __init__(self, n_p_min, n_p_max, prrtApplicationParameters, prrtChannelParameters, prrtSystemParameters): self.n_max = 255 self.step_size = 2 # Step size in the estimation of the optimum code word length self.n_p_min = n_p_min self.n_p_max = n_p_max self.prrtApplicationParameters = prrtApplicationParameters self.prrtChannelParameters = prrtChannelParameters self.prrtSystemParameters = prrtSystemParameters self.p_t = self.prrtApplicationParameters.max_residual_loss_rate self.is_order_ascending = True pass def search(self): ri_opt = math.inf k_opt = 0 n_opt = 0 n_p_opt = [] # Eq.5.9, page 125 fec_delay_min = self.prrtSystemParameters.source_packet_interval + \ self.n_p_max * self.prrtSystemParameters.redundancy_packet_transmission_delay + \ (self.prrtChannelParameters.rtt_prop_fwd + self.prrtSystemParameters.processing_delay) / 2 + \ self.prrtSystemParameters.packet_loss_detection_delay # Eq.5.9 page 125 assumung D_sup = 0 req_delay = self.prrtChannelParameters.rtt_prop_fwd + \ self.n_p_max * self.prrtSystemParameters.redundancy_packet_transmission_delay + \ self.prrtSystemParameters.processing_delay # Eq.5.10, page 125 n_c_max = math.ceil((self.prrtApplicationParameters.max_latency - fec_delay_min) / req_delay) # self.k_lim = somewhat(prrtApplicationParameters.loss_tolerance, self.n_max) # n_c = 0 is the proactive packet for n_c in range(n_c_max): # Eq.5.11, k(Nc, D_T), page 125 k_max = min(self.get_k(n_c, req_delay), self.get_k_lim(1, self.n_max)) for k in [1, k_max]: n = self.estimate_n_for_k(k) repair_schedule = ric.gen_repair_schedule(n - k, n_c, self.n_p_min, self.n_p_max) coding_conf = prrt.PrrtCodingConfiguration(n, k, repair_schedule) ri = coding_conf.get_redundant_information(self.prrtChannelParameters) if ri < ri_opt: k_opt = k n_opt = n n_p_opt = repair_schedule return prrt.PrrtCodingConfiguration(n_opt, k_opt, n_p_opt) def get_k(self, n_c, req_delay): return math.ceil((self.prrtApplicationParameters.max_latency - self.n_p_max * self.prrtSystemParameters.redundancy_packet_transmission_delay - (self.prrtChannelParameters.rtt_prop_fwd + self.prrtSystemParameters.processing_delay) / 2 - self.prrtSystemParameters.packet_loss_detection_delay - n_c * req_delay) / self.prrtSystemParameters.source_packet_interval) def get_k_lim(self, start, end): mid_point = math.ceil((end - start) / 2) p_r = self.get_max_coding_block_length(mid_point) if p_r == self.p_t: return mid_point elif p_r > self.p_t: self.get_k_lim(start, mid_point - 1) else: self.get_k_lim(mid_point + 1, end) # Pr(k, n_max) def get_max_coding_block_length(self, k): total_packet_erasure = 0 for i in range(1, k): for j in range(max(self.n_max - k + 1, i), self.n_max - k + i): packet_erasure_at_i = i * self.hypergeometric_distribution(self.n_max, k, i, j) * self.get_error_prob( j, self.n_max, self.prrtChannelParameters.loss_rate_fwd) total_packet_erasure += packet_erasure_at_i return (1 / k) * total_packet_erasure def estimate_n_for_k(self, k): n = k + 1 while self.residual_packet_erasure_rate(k, n, self.prrtApplicationParameters, self.prrtChannelParameters) > self.prrtApplicationParameters.max_residual_loss_rate\ and n <= self.n_max - self.step_size: print("") return 0 def residual_packet_erasure_rate(self, k, n, prrtApplicationParameters, prrtChannelParameters): total_packet_erasure = 0 for i in range(1, k): for j in range(max(n - k + 1, i), n - k + i): packet_erasure_at_i = i * self.hypergeometric_distribution(n, k, i, j) * self.get_error_prob(j, n, prrtChannelParameters.loss_rate_fwd) total_packet_erasure += packet_erasure_at_i residual_packet_erasure_rate = (1 / k) * total_packet_erasure # Pr(k, n) return residual_packet_erasure_rate No newline at end of file prrt/ric.pyx +18 −2 Original line number Diff line number Diff line Loading @@ -20,7 +20,7 @@ def generate_restricted_integer_compositions(redundancy, positions, min, max): yield (i,) + result # is_order_ascending = False for full search and True for greedy search def gen_repair_schedule(redundancy, positions, min, max, is_order_ascending): def gen_repair_schedules(redundancy, positions, min, max, is_order_ascending): arbitrary_schedules = [] ordered_schedules = set() Loading @@ -34,3 +34,19 @@ def gen_repair_schedule(redundancy, positions, min, max, is_order_ascending): return list(ordered_schedules) else: return arbitrary_schedules def gen_repair_schedule(redundancy, positions, min, max): if(redundancy < positions * min or min > max): raise Exception("Illegal input combinations. Make sure the min > max. And, number of total redundancy is greater that positions*min.") opt_schedule = [min for p in range(positions)] redundancy_left_over = redundancy - min * positions last_index = positions - 1 while(redundancy_left_over > 0): if(opt_schedule[last_index] < max): opt_schedule[last_index] += 1 redundancy_left_over -= 1 else: last_index -= 1 return opt_schedule No newline at end of file Loading
prrt/hec_search.py +95 −3 Original line number Diff line number Diff line Loading @@ -102,10 +102,11 @@ class HECFullSearch(AbstractSearch): return residual_packet_erasure_rate class HECGreedySearch(AbstractSearch): def __init__(self, n_p_max, prrtApplicationParameters, prrtChannelParameters, prrtSystemParameters): class HECReducedSpaceSearch(AbstractSearch): def __init__(self, n_p_min, n_p_max, prrtApplicationParameters, prrtChannelParameters, prrtSystemParameters): self.n_max = 255 self.step_size = 2 # Step size in the estimation of the optimum code word length self.n_p_min = n_p_min self.n_p_max = n_p_max self.prrtApplicationParameters = prrtApplicationParameters self.prrtChannelParameters = prrtChannelParameters Loading Loading @@ -138,7 +139,7 @@ class HECGreedySearch(AbstractSearch): k_max = min(self.get_k(n_c, req_delay), self.get_k_lim(1, self.n_max)) for k in [1, k_max]: n = self.estimate_n_for_k(k) repair_schedules = ric.gen_repair_schedule(n - k, n_c, 1, self.n_p_max, self.is_order_ascending) repair_schedules = ric.gen_repair_schedule(n - k, n_c, self.n_p_min, self.n_p_max, self.is_order_ascending) for repair_schedule in repair_schedules: coding_conf = prrt.PrrtCodingConfiguration(n, k, repair_schedule) ri = coding_conf.get_redundant_information(self.prrtChannelParameters) Loading Loading @@ -192,3 +193,94 @@ class HECGreedySearch(AbstractSearch): total_packet_erasure += packet_erasure_at_i residual_packet_erasure_rate = (1 / k) * total_packet_erasure # Pr(k, n) return residual_packet_erasure_rate class HECGreadySearch(AbstractSearch): def __init__(self, n_p_min, n_p_max, prrtApplicationParameters, prrtChannelParameters, prrtSystemParameters): self.n_max = 255 self.step_size = 2 # Step size in the estimation of the optimum code word length self.n_p_min = n_p_min self.n_p_max = n_p_max self.prrtApplicationParameters = prrtApplicationParameters self.prrtChannelParameters = prrtChannelParameters self.prrtSystemParameters = prrtSystemParameters self.p_t = self.prrtApplicationParameters.max_residual_loss_rate self.is_order_ascending = True pass def search(self): ri_opt = math.inf k_opt = 0 n_opt = 0 n_p_opt = [] # Eq.5.9, page 125 fec_delay_min = self.prrtSystemParameters.source_packet_interval + \ self.n_p_max * self.prrtSystemParameters.redundancy_packet_transmission_delay + \ (self.prrtChannelParameters.rtt_prop_fwd + self.prrtSystemParameters.processing_delay) / 2 + \ self.prrtSystemParameters.packet_loss_detection_delay # Eq.5.9 page 125 assumung D_sup = 0 req_delay = self.prrtChannelParameters.rtt_prop_fwd + \ self.n_p_max * self.prrtSystemParameters.redundancy_packet_transmission_delay + \ self.prrtSystemParameters.processing_delay # Eq.5.10, page 125 n_c_max = math.ceil((self.prrtApplicationParameters.max_latency - fec_delay_min) / req_delay) # self.k_lim = somewhat(prrtApplicationParameters.loss_tolerance, self.n_max) # n_c = 0 is the proactive packet for n_c in range(n_c_max): # Eq.5.11, k(Nc, D_T), page 125 k_max = min(self.get_k(n_c, req_delay), self.get_k_lim(1, self.n_max)) for k in [1, k_max]: n = self.estimate_n_for_k(k) repair_schedule = ric.gen_repair_schedule(n - k, n_c, self.n_p_min, self.n_p_max) coding_conf = prrt.PrrtCodingConfiguration(n, k, repair_schedule) ri = coding_conf.get_redundant_information(self.prrtChannelParameters) if ri < ri_opt: k_opt = k n_opt = n n_p_opt = repair_schedule return prrt.PrrtCodingConfiguration(n_opt, k_opt, n_p_opt) def get_k(self, n_c, req_delay): return math.ceil((self.prrtApplicationParameters.max_latency - self.n_p_max * self.prrtSystemParameters.redundancy_packet_transmission_delay - (self.prrtChannelParameters.rtt_prop_fwd + self.prrtSystemParameters.processing_delay) / 2 - self.prrtSystemParameters.packet_loss_detection_delay - n_c * req_delay) / self.prrtSystemParameters.source_packet_interval) def get_k_lim(self, start, end): mid_point = math.ceil((end - start) / 2) p_r = self.get_max_coding_block_length(mid_point) if p_r == self.p_t: return mid_point elif p_r > self.p_t: self.get_k_lim(start, mid_point - 1) else: self.get_k_lim(mid_point + 1, end) # Pr(k, n_max) def get_max_coding_block_length(self, k): total_packet_erasure = 0 for i in range(1, k): for j in range(max(self.n_max - k + 1, i), self.n_max - k + i): packet_erasure_at_i = i * self.hypergeometric_distribution(self.n_max, k, i, j) * self.get_error_prob( j, self.n_max, self.prrtChannelParameters.loss_rate_fwd) total_packet_erasure += packet_erasure_at_i return (1 / k) * total_packet_erasure def estimate_n_for_k(self, k): n = k + 1 while self.residual_packet_erasure_rate(k, n, self.prrtApplicationParameters, self.prrtChannelParameters) > self.prrtApplicationParameters.max_residual_loss_rate\ and n <= self.n_max - self.step_size: print("") return 0 def residual_packet_erasure_rate(self, k, n, prrtApplicationParameters, prrtChannelParameters): total_packet_erasure = 0 for i in range(1, k): for j in range(max(n - k + 1, i), n - k + i): packet_erasure_at_i = i * self.hypergeometric_distribution(n, k, i, j) * self.get_error_prob(j, n, prrtChannelParameters.loss_rate_fwd) total_packet_erasure += packet_erasure_at_i residual_packet_erasure_rate = (1 / k) * total_packet_erasure # Pr(k, n) return residual_packet_erasure_rate No newline at end of file
prrt/ric.pyx +18 −2 Original line number Diff line number Diff line Loading @@ -20,7 +20,7 @@ def generate_restricted_integer_compositions(redundancy, positions, min, max): yield (i,) + result # is_order_ascending = False for full search and True for greedy search def gen_repair_schedule(redundancy, positions, min, max, is_order_ascending): def gen_repair_schedules(redundancy, positions, min, max, is_order_ascending): arbitrary_schedules = [] ordered_schedules = set() Loading @@ -34,3 +34,19 @@ def gen_repair_schedule(redundancy, positions, min, max, is_order_ascending): return list(ordered_schedules) else: return arbitrary_schedules def gen_repair_schedule(redundancy, positions, min, max): if(redundancy < positions * min or min > max): raise Exception("Illegal input combinations. Make sure the min > max. And, number of total redundancy is greater that positions*min.") opt_schedule = [min for p in range(positions)] redundancy_left_over = redundancy - min * positions last_index = positions - 1 while(redundancy_left_over > 0): if(opt_schedule[last_index] < max): opt_schedule[last_index] += 1 redundancy_left_over -= 1 else: last_index -= 1 return opt_schedule No newline at end of file