예제 #1
0
    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
예제 #2
0
    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
예제 #3
0
    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
예제 #4
0
 def EntriesRemoveDegenerates(self):
     """Remove duplicate entries by time stamp."""
     for key, values in self.entries.iteritems():
         values = utils.remove_degenerates(values)