def Convolve(self, provided): """ Use min-plus calculus to convolve this *required* profile with an input *provided* profile. This function implements the operation (see :ref:`network_math_formalism`): .. math:: y=l[t] &= (r \otimes p)[t] = min( r[t] , p[t] - (p[t-1] -l[t-1]) ) Where * :math:`r[t]` is the data profile required by the application (*self*) * :math:`p[t]` is the data profile provided by the node's link * :math:`l[t]` is the data profile transmitted onto the link :rtype: :class:`Profile`, :math:`l[t]` :param in provided: a :class:`Profile` describing the node's provided link profile """ r = self.entries['data'] p = provided.entries['data'] o = [] times = [ x[0] for x in p ] times.extend( [ x[0] for x in r ] ) times = sorted(list(set(times))) offset = 0 prevDiff = 0 prevTime = None r_prev = None p_prev = None for t in times: r_data = utils.get_value_at_time(r, t, interpolate = 'data' in self.interpolated_profiles) p_data = utils.get_value_at_time(p, t, interpolate = 'data' in self.interpolated_profiles) - offset diff = p_data - r_data if diff > 0: offset += diff if cmp(diff,0) != cmp(prevDiff,0): intersection = utils.get_intersection( [ prevTime, r_prev ], [ t, r_data ], [ prevTime, p_prev ], [ t, p_data ] ) if intersection: o.append(intersection) newPoint = [t, p_data - max(0,diff)] o.append(newPoint) prevDiff = diff prevTime = t r_prev = r_data p_prev = p_data o = utils.remove_degenerates(o) output = Profile(kind='output') output.entries['data'] = o output.Derive() return output
def Delay(self, delayProf): """ Compute the delayed profile composed of *self* profile and *delayProf*, received by a node for which this *self* profile is the output profile on the sender side. The delay profile describes the delay as a function of time for the link. This function implements the operation: .. math:: o[t + \delta[t]] = l[t] Where * :math:`\delta[t]` is the delay profile * :math:`l[t]` is the profile transmitted into the link (*self*) * :math:`o[t]` is the output profile received at the other end of the link :rtype: :class:`Profile`, :math:`o[t]` :param in delayProf: :class:`Profile` describing the delay """ delays = delayProf.entries['latency'] all0 = True for time, delay in delays: if delay != 0: all0 = False if all0: return copy.deepcopy(self) datas = self.entries['data'] endTime = datas[-1][0] times = [ x[0] for x in delays ] times.extend( [ x[0] for x in datas ] ) times = sorted(list(set(times))) newDatas = [] for t in times: d = utils.get_value_at_time(datas, t) delay = utils.get_value_at_time(delays, t, interpolate = 'latency' in self.interpolated_profiles) newDatas.append([ t + delay, d ]) newDatas = utils.remove_degenerates(newDatas) newDatas, remainder = utils.split(newDatas, endTime) if remainder: t = -remainder[0][0] utils.shift(remainder, t) r_slopes = utils.derive(remainder) d_slopes = utils.derive(newDatas) d_slopes = utils.add_values(d_slopes,r_slopes) newDatas = utils.integrate(d_slopes, endTime) retProf = Profile() retProf.entries['data'] = newDatas retProf.Derive() return retProf
def ConvertToNC(self,filterFunc, step = 0): """ Perform time-window based integration to generate a Network Calculus curve from the profile. The conversion is configurable based on time-window step-size and a filter function (e.g. min or max). Passing :func:`max` will create an arrival curve, while passing :func:`min` will create a service curve. :rtype: :class:`Profile`, the network-calculus version of the *self* profile .. note:: Requires the profile to have been integrated """ time_list = [] data_list = [] for t,d in self.entries['data']: time_list.append(t) data_list.append(-d) new_datas = [] if step <= 0: step = min( [x for x in time_list if x > 0] ) for tw in time_list: extreme_data = -filterFunc(data_list) t = tw while t <= time_list[-1]: start_data = utils.get_value_at_time(self.entries['data'], t - tw, interpolate = 'data' in self.interpolated_profiles) end_data = utils.get_value_at_time(self.entries['data'], t, interpolate = 'data' in self.interpolated_profiles) diff = end_data - start_data extreme_data = filterFunc([diff,extreme_data]) t += step new_datas.append([tw, extreme_data]) new_datas = utils.remove_degenerates(new_datas) retProf = Profile(kind = self.kind) retProf.entries['data'] = new_datas retProf.Derive() return retProf
def EntriesRemoveDegenerates(self): """Remove duplicate entries by time stamp.""" for key, values in self.entries.iteritems(): values = utils.remove_degenerates(values)