aboutsummaryrefslogtreecommitdiffstats
path: root/resources/libraries/python/MLRsearch
diff options
context:
space:
mode:
Diffstat (limited to 'resources/libraries/python/MLRsearch')
-rw-r--r--resources/libraries/python/MLRsearch/AbstractMeasurer.py2
-rw-r--r--resources/libraries/python/MLRsearch/AbstractSearchAlgorithm.py4
-rw-r--r--resources/libraries/python/MLRsearch/MultipleLossRatioSearch.py67
-rw-r--r--resources/libraries/python/MLRsearch/NdrPdrResult.py4
-rw-r--r--resources/libraries/python/MLRsearch/ReceiveRateInterval.py4
5 files changed, 63 insertions, 18 deletions
diff --git a/resources/libraries/python/MLRsearch/AbstractMeasurer.py b/resources/libraries/python/MLRsearch/AbstractMeasurer.py
index b972c4eb18..c9b5987124 100644
--- a/resources/libraries/python/MLRsearch/AbstractMeasurer.py
+++ b/resources/libraries/python/MLRsearch/AbstractMeasurer.py
@@ -30,6 +30,6 @@ class AbstractMeasurer(object):
:type duration: float
:type transmit_rate: float
:returns: Structure containing the result of the measurement.
- :rtype: ReceiveRateMeasurement
+ :rtype: ReceiveRateMeasurement.ReceiveRateMeasurement
"""
pass
diff --git a/resources/libraries/python/MLRsearch/AbstractSearchAlgorithm.py b/resources/libraries/python/MLRsearch/AbstractSearchAlgorithm.py
index 538322a42c..08f8b7e0a9 100644
--- a/resources/libraries/python/MLRsearch/AbstractSearchAlgorithm.py
+++ b/resources/libraries/python/MLRsearch/AbstractSearchAlgorithm.py
@@ -25,7 +25,7 @@ class AbstractSearchAlgorithm(object):
"""Store the rate provider.
:param measurer: Object able to perform trial or composite measurements.
- :type measurer: AbstractMeasurer
+ :type measurer: AbstractMeasurer.AbstractMeasurer
"""
# TODO: Type check for AbstractMeasurer?
self.measurer = measurer
@@ -45,7 +45,7 @@ class AbstractSearchAlgorithm(object):
:type packet_loss_ratio: float
:returns: Structure containing narrowed down intervals
and their measurements.
- :rtype: NdrPdrResult
+ :rtype: NdrPdrResult.NdrPdrResult
"""
# TODO: Do we agree on arguments related to precision or trial duration?
pass
diff --git a/resources/libraries/python/MLRsearch/MultipleLossRatioSearch.py b/resources/libraries/python/MLRsearch/MultipleLossRatioSearch.py
index 0eb1d7da4c..be7ffba3a3 100644
--- a/resources/libraries/python/MLRsearch/MultipleLossRatioSearch.py
+++ b/resources/libraries/python/MLRsearch/MultipleLossRatioSearch.py
@@ -97,7 +97,7 @@ class MultipleLossRatioSearch(AbstractSearchAlgorithm):
for the current search [pps].
:param maximum_transmit_rate: Maximum target transmit rate
for the current search [pps].
- :type result: NdrPdrResult
+ :type result: NdrPdrResult.NdrPdrResult
:type phases: int
:type duration: float
:type width_goal: float
@@ -115,7 +115,7 @@ class MultipleLossRatioSearch(AbstractSearchAlgorithm):
def __init__(self, measurer, final_relative_width=0.005,
final_trial_duration=30.0, initial_trial_duration=1.0,
- number_of_intermediate_phases=2, timeout=600.0):
+ number_of_intermediate_phases=2, timeout=600.0, doublings=1):
"""Store the measurer object and additional arguments.
:param measurer: Rate provider to use by this search object.
@@ -128,12 +128,16 @@ class MultipleLossRatioSearch(AbstractSearchAlgorithm):
to perform before the final phase [1].
:param timeout: The search will fail itself when not finished
before this overall time [s].
- :type measurer: AbstractMeasurer
+ :param doublings: How many doublings to do in external search step.
+ Default 1 is suitable for fairly stable tests,
+ less stable tests might get better overal duration with 2 or more.
+ :type measurer: AbstractMeasurer.AbstractMeasurer
:type final_relative_width: float
:type final_trial_duration: float
:type initial_trial_duration: int
:type number_of_intermediate_phases: int
:type timeout: float
+ :type doublings: int
"""
super(MultipleLossRatioSearch, self).__init__(measurer)
self.final_trial_duration = float(final_trial_duration)
@@ -141,6 +145,7 @@ class MultipleLossRatioSearch(AbstractSearchAlgorithm):
self.number_of_intermediate_phases = int(number_of_intermediate_phases)
self.initial_trial_duration = float(initial_trial_duration)
self.timeout = float(timeout)
+ self.doublings = int(doublings)
@staticmethod
@@ -172,6 +177,24 @@ class MultipleLossRatioSearch(AbstractSearchAlgorithm):
relative_width))
@staticmethod
+ def expand_down(relative_width, doublings, current_bound):
+ """Return rate of expanded logarithmic width below.
+
+ :param relative_width: The base relative width to double.
+ :param doublings: How many doublings to do for expansion.
+ :param current_bound: The current target transmit rate to move [pps].
+ :type relative_width: float
+ :type doublings: int
+ :type current_bound: float
+ :returns: Transmit rate smaller by logarithmically double width [pps].
+ :rtype: float
+ """
+ for _ in range(doublings):
+ relative_width = MultipleLossRatioSearch.double_relative_width(
+ relative_width)
+ return current_bound * (1.0 - relative_width)
+
+ @staticmethod
def double_step_up(relative_width, current_bound):
"""Return rate of double logarithmic width above.
@@ -187,6 +210,24 @@ class MultipleLossRatioSearch(AbstractSearchAlgorithm):
relative_width))
@staticmethod
+ def expand_up(relative_width, doublings, current_bound):
+ """Return rate of expanded logarithmic width above.
+
+ :param relative_width: The base relative width to double.
+ :param doublings: How many doublings to do for expansion.
+ :param current_bound: The current target transmit rate to move [pps].
+ :type relative_width: float
+ :type doublings: int
+ :type current_bound: float
+ :returns: Transmit rate smaller by logarithmically double width [pps].
+ :rtype: float
+ """
+ for _ in range(doublings):
+ relative_width = MultipleLossRatioSearch.double_relative_width(
+ relative_width)
+ return current_bound / (1.0 - relative_width)
+
+ @staticmethod
def half_relative_width(relative_width):
"""Return relative width corresponding to half logarithmic width.
@@ -224,7 +265,7 @@ class MultipleLossRatioSearch(AbstractSearchAlgorithm):
:type packet_loss_ratio: float
:returns: Structure containing narrowed down intervals
and their measurements.
- :rtype: NdrPdrResult
+ :rtype: NdrPdrResult.NdrPdrResult
:raises RuntimeError: If total duration is larger than timeout.
"""
minimum_transmit_rate = float(minimum_transmit_rate)
@@ -296,11 +337,11 @@ class MultipleLossRatioSearch(AbstractSearchAlgorithm):
:param old_interval: The current interval before the measurement.
:param measurement: The new meaqsurement to take into account.
:param packet_loss_ratio: Fraction for PDR (or zero for NDR).
- :type old_interval: ReceiveRateInterval
- :type measurement: ReceiveRateMeasurement
+ :type old_interval: ReceiveRateInterval.ReceiveRateInterval
+ :type measurement: ReceiveRateMeasurement.ReceiveRateMeasurement
:type packet_loss_ratio: float
:returns: The updated interval.
- :rtype: ReceiveRateInterval
+ :rtype: ReceiveRateInterval.ReceiveRateInterval
"""
old_lo, old_hi = old_interval.measured_low, old_interval.measured_high
# Priority zero: direct replace if the target Tr is the same.
@@ -399,7 +440,8 @@ class MultipleLossRatioSearch(AbstractSearchAlgorithm):
if ndr_lo.target_tr > state.minimum_transmit_rate:
new_tr = max(
state.minimum_transmit_rate,
- self.double_step_down(ndr_rel_width, ndr_lo.target_tr))
+ self.expand_down(
+ ndr_rel_width, self.doublings, ndr_lo.target_tr))
logging.info("ndr lo external %s", new_tr)
state = self._measure_and_update_state(state, new_tr)
continue
@@ -412,7 +454,8 @@ class MultipleLossRatioSearch(AbstractSearchAlgorithm):
if pdr_lo.target_tr > state.minimum_transmit_rate:
new_tr = max(
state.minimum_transmit_rate,
- self.double_step_down(pdr_rel_width, pdr_lo.target_tr))
+ self.expand_down(
+ pdr_rel_width, self.doublings, pdr_lo.target_tr))
logging.info("pdr lo external %s", new_tr)
state = self._measure_and_update_state(state, new_tr)
continue
@@ -425,7 +468,8 @@ class MultipleLossRatioSearch(AbstractSearchAlgorithm):
if ndr_hi.target_tr < state.maximum_transmit_rate:
new_tr = min(
state.maximum_transmit_rate,
- self.double_step_up(ndr_rel_width, ndr_hi.target_tr))
+ self.expand_up(
+ ndr_rel_width, self.doublings, ndr_hi.target_tr))
logging.info("ndr hi external %s", new_tr)
state = self._measure_and_update_state(state, new_tr)
continue
@@ -438,7 +482,8 @@ class MultipleLossRatioSearch(AbstractSearchAlgorithm):
if pdr_hi.target_tr < state.maximum_transmit_rate:
new_tr = min(
state.maximum_transmit_rate,
- self.double_step_up(pdr_rel_width, pdr_hi.target_tr))
+ self.expand_up(
+ pdr_rel_width, self.doublings, pdr_hi.target_tr))
logging.info("pdr hi external %s", new_tr)
state = self._measure_and_update_state(state, new_tr)
continue
diff --git a/resources/libraries/python/MLRsearch/NdrPdrResult.py b/resources/libraries/python/MLRsearch/NdrPdrResult.py
index b69a57ecbe..80df0ef333 100644
--- a/resources/libraries/python/MLRsearch/NdrPdrResult.py
+++ b/resources/libraries/python/MLRsearch/NdrPdrResult.py
@@ -27,8 +27,8 @@ class NdrPdrResult(object):
:param ndr_interval: Object containing data for NDR part of the result.
:param pdr_interval: Object containing data for PDR part of the result.
- :type ndr_interval: ReceiveRateInterval
- :type pdr_interval: ReceiveRateInterval
+ :type ndr_interval: ReceiveRateInterval.ReceiveRateInterval
+ :type pdr_interval: ReceiveRateInterval.ReceiveRateInterval
"""
# TODO: Type checking is not very pythonic,
# perhaps users can fix wrong usage without it?
diff --git a/resources/libraries/python/MLRsearch/ReceiveRateInterval.py b/resources/libraries/python/MLRsearch/ReceiveRateInterval.py
index 05e0f10013..6dff1b8a7a 100644
--- a/resources/libraries/python/MLRsearch/ReceiveRateInterval.py
+++ b/resources/libraries/python/MLRsearch/ReceiveRateInterval.py
@@ -26,8 +26,8 @@ class ReceiveRateInterval(object):
:param measured_low: Measurement for the lower bound.
:param measured_high: Measurement for the upper bound.
- :type measured_low: ReceiveRateMeasurement
- :type measured_high: ReceiveRateMeasurement
+ :type measured_low: ReceiveRateMeasurement.ReceiveRateMeasurement
+ :type measured_high: ReceiveRateMeasurement.ReceiveRateMeasurement
"""
# TODO: Type checking is not very pythonic,
# perhaps users can fix wrong usage without it?