Loading prrt/HecSearch.pydeleted 100644 → 0 +0 −288 Original line number Diff line number Diff line from abc import ABC, abstractmethod import prrt import math class AbstractSearch(ABC): @abstractmethod def search(self): pass class HECFullSearch(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 = False 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 range(1, k_max + 1): n = self.estimate_n_for_k(k) repair_schedules = prrt.gen_repair_schedule(n - k, n_c, 1, 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) 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 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 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 = [] ric = prrt.RestrictedIntegerComposition # 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_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) 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: n = k + self.step_size return n 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 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 = [] ric = prrt.RestrictedIntegerComposition # 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/SearchEvaluation.pydeleted 100644 → 0 +0 −42 Original line number Diff line number Diff line import numpy as np import pandas as pd import prrt from prrt.HecSearch import HECFullSearch from prrt.HecSearch import HECGreadySearch import time def evaluate(searchAlgorithm, appParams, channelParams, systemParams): n_p_min = 1 n_p_max = get_n_p_max(channelParams.rtt_prop_fwd, channelParams.pkt_length, channelParams.data_rate_btl_fwd) if searchAlgorithm == "FullSearch": full_search = HECFullSearch(n_p_min, n_p_max, appParams, channelParams, systemParams) start = time.now() full_search_result = full_search.search() duration = time.now() - start return [full_search_result, duration] if searchAlgorithm == "GreedySearch": greedy_search = HECGreadySearch(n_p_min, n_p_max, appParams, channelParams, systemParams) start = time.now() greedy_search_result = greedy_search.search() duration = time.now() - start return [greedy_search_result, duration] def test_case(csv_file_path): appParams = prrt.PrrtApplicationParameters(max_latency, max_residual_loss_rate, data_rate) chnlParams = prrt.PrrtChannelParameters(...) sysParams = prrt.PrrtSystemParameters(...) for searchAlgorithm in ["FullSearch", "GreedySearch"]: config, duration = evaluate(searchAlgorithm, appParams, chnlParams, sysParams) rows.append(..., search, config, duration) pd.DataFrame(rows).to_csv() def get_n_p_max(rtt_prop_fwd, pkt_length, data_rate_btl_fwd): return rtt_prop_fwd * data_rate_btl_fwd / pkt_length No newline at end of file prrt/ric.pyxdeleted 100644 → 0 +0 −52 Original line number Diff line number Diff line import pyximport; pyximport.install() import itertools def generate_restricted_integer_compositions(redundancy, positions, min, max): cdef c_redundancy = redundancy cdef c_positions = positions cdef c_min = min cdef c_max = max if c_positions < 1: raise StopIteration if c_positions == 1: if c_redundancy >= c_min and c_redundancy <= c_max: yield (c_redundancy,) raise StopIteration for i in range(c_min, c_redundancy + 1): for result in generate_restricted_integer_compositions(c_redundancy - i, c_positions - 1, i, c_max): if (i <= c_max): yield (i,) + result # is_order_ascending = False for full search and True for greedy search def gen_repair_schedules(redundancy, positions, min, max, is_order_ascending): arbitrary_schedules = [] ordered_schedules = set() gen_rics = generate_restricted_integer_compositions(redundancy, positions, min, max) for ric in gen_rics: arbitrary_schedules.append(ric) if not is_order_ascending: for ric in arbitrary_schedules: ordered_schedules.add(itertools.permutations(ric)) 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 prrt/search_evaluation.py +1 −1 Original line number Diff line number Diff line Loading @@ -4,7 +4,7 @@ import prrt import time import numpy as np dataset_file_path = 'in_12_param_4_sz_mini_1000.csv' dataset_file_path = 'documents/in_12_param_4_sz_mini_1000.csv' def get_n_p_max(rtt_prop_fwd, pkt_length, data_rate_btl_fwd): Loading Loading
prrt/HecSearch.pydeleted 100644 → 0 +0 −288 Original line number Diff line number Diff line from abc import ABC, abstractmethod import prrt import math class AbstractSearch(ABC): @abstractmethod def search(self): pass class HECFullSearch(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 = False 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 range(1, k_max + 1): n = self.estimate_n_for_k(k) repair_schedules = prrt.gen_repair_schedule(n - k, n_c, 1, 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) 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 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 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 = [] ric = prrt.RestrictedIntegerComposition # 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_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) 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: n = k + self.step_size return n 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 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 = [] ric = prrt.RestrictedIntegerComposition # 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/SearchEvaluation.pydeleted 100644 → 0 +0 −42 Original line number Diff line number Diff line import numpy as np import pandas as pd import prrt from prrt.HecSearch import HECFullSearch from prrt.HecSearch import HECGreadySearch import time def evaluate(searchAlgorithm, appParams, channelParams, systemParams): n_p_min = 1 n_p_max = get_n_p_max(channelParams.rtt_prop_fwd, channelParams.pkt_length, channelParams.data_rate_btl_fwd) if searchAlgorithm == "FullSearch": full_search = HECFullSearch(n_p_min, n_p_max, appParams, channelParams, systemParams) start = time.now() full_search_result = full_search.search() duration = time.now() - start return [full_search_result, duration] if searchAlgorithm == "GreedySearch": greedy_search = HECGreadySearch(n_p_min, n_p_max, appParams, channelParams, systemParams) start = time.now() greedy_search_result = greedy_search.search() duration = time.now() - start return [greedy_search_result, duration] def test_case(csv_file_path): appParams = prrt.PrrtApplicationParameters(max_latency, max_residual_loss_rate, data_rate) chnlParams = prrt.PrrtChannelParameters(...) sysParams = prrt.PrrtSystemParameters(...) for searchAlgorithm in ["FullSearch", "GreedySearch"]: config, duration = evaluate(searchAlgorithm, appParams, chnlParams, sysParams) rows.append(..., search, config, duration) pd.DataFrame(rows).to_csv() def get_n_p_max(rtt_prop_fwd, pkt_length, data_rate_btl_fwd): return rtt_prop_fwd * data_rate_btl_fwd / pkt_length No newline at end of file
prrt/ric.pyxdeleted 100644 → 0 +0 −52 Original line number Diff line number Diff line import pyximport; pyximport.install() import itertools def generate_restricted_integer_compositions(redundancy, positions, min, max): cdef c_redundancy = redundancy cdef c_positions = positions cdef c_min = min cdef c_max = max if c_positions < 1: raise StopIteration if c_positions == 1: if c_redundancy >= c_min and c_redundancy <= c_max: yield (c_redundancy,) raise StopIteration for i in range(c_min, c_redundancy + 1): for result in generate_restricted_integer_compositions(c_redundancy - i, c_positions - 1, i, c_max): if (i <= c_max): yield (i,) + result # is_order_ascending = False for full search and True for greedy search def gen_repair_schedules(redundancy, positions, min, max, is_order_ascending): arbitrary_schedules = [] ordered_schedules = set() gen_rics = generate_restricted_integer_compositions(redundancy, positions, min, max) for ric in gen_rics: arbitrary_schedules.append(ric) if not is_order_ascending: for ric in arbitrary_schedules: ordered_schedules.add(itertools.permutations(ric)) 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
prrt/search_evaluation.py +1 −1 Original line number Diff line number Diff line Loading @@ -4,7 +4,7 @@ import prrt import time import numpy as np dataset_file_path = 'in_12_param_4_sz_mini_1000.csv' dataset_file_path = 'documents/in_12_param_4_sz_mini_1000.csv' def get_n_p_max(rtt_prop_fwd, pkt_length, data_rate_btl_fwd): Loading