Loading prrt/hec_search.py→prrt/HecSearch.py +5 −3 Original line number Diff line number Diff line from abc import ABC, abstractmethod import prrt import math import ric class AbstractSearch(ABC): Loading @@ -11,9 +10,10 @@ class AbstractSearch(ABC): class HECFullSearch(AbstractSearch): def __init__(self, n_p_max, prrtApplicationParameters, prrtChannelParameters, prrtSystemParameters): 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 @@ -46,7 +46,7 @@ class HECFullSearch(AbstractSearch): 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 = ric.gen_repair_schedule(n - k, n_c, 1, self.n_p_max, self.is_order_ascending) 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) Loading Loading @@ -120,6 +120,7 @@ class HECReducedSpaceSearch(AbstractSearch): 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 + \ Loading Loading @@ -212,6 +213,7 @@ class HECGreadySearch(AbstractSearch): 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 + \ Loading prrt/SearchEvaluation.py 0 → 100644 +42 −0 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/__init__.py 0 → 100644 +0 −0 Empty file added. prrt/prrt.pyx +76 −6 Original line number Diff line number Diff line Loading @@ -10,6 +10,7 @@ import datetime import socket import ipaddress import numpy as np import itertools from scipy.special import comb include "sockets.pxd" Loading Loading @@ -159,16 +160,29 @@ class PrrtApplicationParameters: # max_latency float in seconds # max_residual_loss_rate in percent def __init__(self, max_latency, max_residual_loss_rate): def __init__(self, max_latency, max_residual_loss_rate, data_rate, pkt_length): self.max_latency = max_latency self.max_residual_loss_rate = max_residual_loss_rate self.data_rate = data_rate self.pkt_length = pkt_length def __repr__(self): return "PrrtApplicationParameters(max_latency={}, max_residual_loss_rate={})".format(self.max_latency, self.max_residual_loss_rate) return "PrrtApplicationParameters(max_latency={}, " \ "max_residual_loss_rate={}, " \ "data_rate={}, pkt_length={})".format(self.max_latency, self.max_residual_loss_rate, self.data_rate, self.pkt_length) def __str__(self): return "({},{})".format(self.max_latency, self.max_residual_loss_rate) return "({},{},{},{})".format(self.max_latency, self.max_residual_loss_rate, self.data_rate, self.pkt_length) class PrrtSystemParameters: def __init__(self, Loading Loading @@ -287,6 +301,56 @@ class PrrtCodingConfiguration: if (residual_packet_erasure_rate <= prrtApplicationParameters.max_residual_loss_rate): return True class RestrictedIntegerComposition: def generate_ric(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 RestrictedIntegerComposition.generate_ric(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() f = RestrictedIntegerComposition.generate_ric(redundancy, positions, min, max) for i in f: arbitrary_schedules.add(i) if not is_order_ascending: for i in arbitrary_schedules: ordered_schedules.append(itertools.permutations(i)) 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 cdef class PrrtSocket: cdef cprrt.PrrtSocket* _c_socket Loading Loading @@ -319,6 +383,12 @@ cdef class PrrtSocket: self.processing_delay(), # processing_delay self.packet_loss_detection_delay(), # packet_loss_detection_delay self.source_packet_interval()) property prrt_application_parameters: def __get__(self): return PrrtApplicationParameters(self.max_latency(), self.max_residual_loss_rate(), self.data_rate(), cprrt.PrrtSocket_get_sock_opt(self._c_socket, "maximum_payload_size")) property block_coding_delay: def __get__(self): Loading Loading
prrt/hec_search.py→prrt/HecSearch.py +5 −3 Original line number Diff line number Diff line from abc import ABC, abstractmethod import prrt import math import ric class AbstractSearch(ABC): Loading @@ -11,9 +10,10 @@ class AbstractSearch(ABC): class HECFullSearch(AbstractSearch): def __init__(self, n_p_max, prrtApplicationParameters, prrtChannelParameters, prrtSystemParameters): 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 @@ -46,7 +46,7 @@ class HECFullSearch(AbstractSearch): 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 = ric.gen_repair_schedule(n - k, n_c, 1, self.n_p_max, self.is_order_ascending) 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) Loading Loading @@ -120,6 +120,7 @@ class HECReducedSpaceSearch(AbstractSearch): 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 + \ Loading Loading @@ -212,6 +213,7 @@ class HECGreadySearch(AbstractSearch): 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 + \ Loading
prrt/SearchEvaluation.py 0 → 100644 +42 −0 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/prrt.pyx +76 −6 Original line number Diff line number Diff line Loading @@ -10,6 +10,7 @@ import datetime import socket import ipaddress import numpy as np import itertools from scipy.special import comb include "sockets.pxd" Loading Loading @@ -159,16 +160,29 @@ class PrrtApplicationParameters: # max_latency float in seconds # max_residual_loss_rate in percent def __init__(self, max_latency, max_residual_loss_rate): def __init__(self, max_latency, max_residual_loss_rate, data_rate, pkt_length): self.max_latency = max_latency self.max_residual_loss_rate = max_residual_loss_rate self.data_rate = data_rate self.pkt_length = pkt_length def __repr__(self): return "PrrtApplicationParameters(max_latency={}, max_residual_loss_rate={})".format(self.max_latency, self.max_residual_loss_rate) return "PrrtApplicationParameters(max_latency={}, " \ "max_residual_loss_rate={}, " \ "data_rate={}, pkt_length={})".format(self.max_latency, self.max_residual_loss_rate, self.data_rate, self.pkt_length) def __str__(self): return "({},{})".format(self.max_latency, self.max_residual_loss_rate) return "({},{},{},{})".format(self.max_latency, self.max_residual_loss_rate, self.data_rate, self.pkt_length) class PrrtSystemParameters: def __init__(self, Loading Loading @@ -287,6 +301,56 @@ class PrrtCodingConfiguration: if (residual_packet_erasure_rate <= prrtApplicationParameters.max_residual_loss_rate): return True class RestrictedIntegerComposition: def generate_ric(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 RestrictedIntegerComposition.generate_ric(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() f = RestrictedIntegerComposition.generate_ric(redundancy, positions, min, max) for i in f: arbitrary_schedules.add(i) if not is_order_ascending: for i in arbitrary_schedules: ordered_schedules.append(itertools.permutations(i)) 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 cdef class PrrtSocket: cdef cprrt.PrrtSocket* _c_socket Loading Loading @@ -319,6 +383,12 @@ cdef class PrrtSocket: self.processing_delay(), # processing_delay self.packet_loss_detection_delay(), # packet_loss_detection_delay self.source_packet_interval()) property prrt_application_parameters: def __get__(self): return PrrtApplicationParameters(self.max_latency(), self.max_residual_loss_rate(), self.data_rate(), cprrt.PrrtSocket_get_sock_opt(self._c_socket, "maximum_payload_size")) property block_coding_delay: def __get__(self): Loading