예제 #1
0
    def function_convolution(self, dist_1, dist_2, bins=50):
        a_1, b_1, a_2, b_2 = 0, 0, 0, 0
        if dist_1 in self.bounds:
            a_1, b_1 = self.bounds[dist_1]
        else:
            a_1, b_1 = calculate_bounds_of_probability_distribution(dist_1)
            self.bounds[dist_1] = a_1, b_1
        if dist_2 in self.bounds:
            a_2, b_2 = self.bounds[dist_2]
        else:
            a_2, b_2 = calculate_bounds_of_probability_distribution(dist_2)
            self.bounds[dist_2] = a_2, b_2

        if (type(dist_1.dist), type(dist_2.dist)) == (uniform_gen, uniform_gen):
            return self.function_convolution_uniform((a_1, b_1), (a_2, b_2))

        convolution_bounds_a, convolution_bounds_b = min(a_1, a_2), max(b_1, b_2)

        delta = fabs(convolution_bounds_a - convolution_bounds_b) / bins
        convolution_interval = TimeInterval(convolution_bounds_a, convolution_bounds_b, bins)
        x = [dist_1.pdf(t) for t in convolution_interval]
        y = [dist_2.pdf(t) for t in reversed(convolution_interval)]

        c = convolve(x, y)
        dictionary_convolution = {}
        for t in xrange(len(c)):
            dictionary_convolution[delta * t] = c[t]
        bias = calculateCenterMass(dictionary_convolution)[0] + dist_2.mean() - dist_1.mean()
        dictionary_convolution_biased = {}
        for t in dictionary_convolution:
            dictionary_convolution_biased[t - bias] = dictionary_convolution[t]

        convolution_function = FunctionPiecewiseLinear(dictionary_convolution_biased, FunctionHorizontalLinear(0))
        return convolution_function.normalised()
예제 #2
0
    def function_convolution_uniform(self,
                                     bounds_1,
                                     bounds_2,
                                     probability=None):
        a1, b1 = bounds_1
        a2, b2 = bounds_2
        length_1 = fabs(a1 - b1)
        length_2 = fabs(a2 - b2)

        convolution_bounds_a, convolution_bounds_b = a1 - b2, b1 - a2

        trapezium_0, trapezium_1 = convolution_bounds_a, convolution_bounds_a + min(
            length_2, length_1)
        trapezium_2, trapezium_3 = trapezium_1 + fabs(
            length_1 - length_2), convolution_bounds_b
        #assert trapezium_2 + min(length_2, length_1) == trapezium_3

        if probability is None:
            probability = min(1 / length_1, 1 / length_2)

        result = FunctionPiecewiseLinear(
            {
                trapezium_0: 0,
                trapezium_1: probability,
                trapezium_2: probability,
                trapezium_3: 0
            }, FUNCTION_ZERO)
        result.is_normalised = True

        return result
예제 #3
0
    def compare(self, dist_1, dist_2):
        dist_1_interval = TimeInterval(*self.bounds_of(dist_1))
        dist_2_interval = TimeInterval(*self.bounds_of(dist_2))
        dictionary_input_output = {}
        for time_step in dist_1_interval + dist_2_interval:
            dictionary_input_output[time_step] = sqrt(
                dist_1.pdf(time_step) * dist_2.pdf(time_step))

        geometric_mean = FunctionPiecewiseLinear(
            dictionary_input_output, function_undefined=FUNCTION_ZERO)
        same = integral(geometric_mean, NEGATIVE_INFINITY, POSITIVE_INFINITY)

        dist_1_mean, dist_1_skewness, dist_1_kurtosis = dist_1.stats(
            moments='msk')
        dist_1_standard_deviation = dist_1.std()
        dist_2_mean, dist_2_skewness, dist_2_kurtosis = dist_2.stats(
            moments='msk')
        dist_2_standard_deviation = dist_2.std()

        distance = fabs(dist_1_standard_deviation -
                        dist_2_standard_deviation) + fabs(dist_1_skewness -
                                                          dist_2_skewness)
        distance += fabs(dist_1_kurtosis - dist_2_kurtosis)
        delta = dist_1_mean - dist_2_mean
        non_same_portion = 1.0 - same

        portion_after, portion_before = 1.0, 0.0
        if almost_equals(distance, 0):
            if delta < 0:
                portion_after, portion_before = 0.0, 1.0
        else:
            dist_1_standardized_pdf = lambda x: dist_1.pdf(
                dist_1_standard_deviation * x + dist_1_mean)
            dist_2_standardized_pdf = lambda x: dist_2.pdf(
                dist_2_standard_deviation * x + dist_2_mean)

            geometric_mean = lambda t: sqrt(
                dist_1_standardized_pdf(t) * dist_2_standardized_pdf(t))
            geometric_mean_scaled = lambda p: geometric_mean(p / distance)
            geometric_mean_scaled_length = max(self.duration_of(dist_1),
                                               self.duration_of(dist_2))

            dictionary_input_output = {}
            for time_step in TimeInterval(-geometric_mean_scaled_length / 2.0,
                                          geometric_mean_scaled_length / 2.0):
                dictionary_input_output[time_step] = geometric_mean_scaled(
                    time_step)

            geometric_mean_scaled = FunctionPiecewiseLinear(
                dictionary_input_output, function_undefined=FUNCTION_ZERO)
            portion_after = integral(geometric_mean_scaled, NEGATIVE_INFINITY,
                                     delta)
            portion_before = integral(geometric_mean_scaled, delta,
                                      POSITIVE_INFINITY)

        after = portion_after / (portion_after +
                                 portion_before) * non_same_portion
        return 1.0 - same - after, same, after
예제 #4
0
    def __init__(self, dictionary_input_output):
        cdf_input_list, cdf_output_list = convert_dict_to_sorted_lists(dictionary_input_output)
        list.__init__(self, cdf_input_list)
        TimeInterval.__init__(self, self[0], self[-1], 2)
        self.cdf = FunctionPiecewiseLinear(dictionary_input_output, function_undefined=FUNCTION_ZERO)
        self.cdf.dictionary_bounds_function[(self.b, POSITIVE_INFINITY)] = FUNCTION_ONE
        pdf_output_list = []
        dictionary_bounds_function = {}
        for bounds in sorted(self.cdf.dictionary_bounds_function):
            a, b = bounds
            if a in [NEGATIVE_INFINITY, POSITIVE_INFINITY] or b in [NEGATIVE_INFINITY, POSITIVE_INFINITY]:
                continue
            pdf_y_intercept = fabs(self.cdf.derivative((a + b) / 2.0))
            pdf_output_list.append(pdf_y_intercept)
            dictionary_bounds_function[bounds] = FunctionHorizontalLinear(pdf_y_intercept)

        self.pdf = FunctionComposite(dictionary_bounds_function, function_undefined=FUNCTION_ZERO, domain=self,
                                     is_normalised=True)

        self.roulette_wheel = []

        self._mean = 0
        for bounds in sorted(self.pdf.dictionary_bounds_function):
            (a, b) = bounds
            if a in [NEGATIVE_INFINITY, POSITIVE_INFINITY] and b in [NEGATIVE_INFINITY, POSITIVE_INFINITY]:
                continue
            cdf = self.cdf.dictionary_bounds_function[bounds]
            pdf = self.pdf.dictionary_bounds_function[bounds]
            share = cdf(b)
            self.roulette_wheel.append((a, b, share))

            self._mean += (a + b) / 2.0 * pdf(a) * (b - a)
예제 #5
0
    def function_convolution_uniform(self, bounds_1, bounds_2, probability=None):
        a1, b1 = bounds_1
        a2, b2 = bounds_2
        length_1 = fabs(a1 - b1)
        length_2 = fabs(a2 - b2)

        convolution_bounds_a, convolution_bounds_b = a1 - b2, b1 - a2

        trapezium_0, trapezium_1 = convolution_bounds_a, convolution_bounds_a + min(length_2, length_1)
        trapezium_2, trapezium_3 = trapezium_1 + fabs(length_1 - length_2), convolution_bounds_b
        #assert trapezium_2 + min(length_2, length_1) == trapezium_3

        if probability is None:
            probability = min(1 / length_1, 1 / length_2)

        result = FunctionPiecewiseLinear(
            {trapezium_0: 0, trapezium_1: probability, trapezium_2: probability, trapezium_3: 0},
            FUNCTION_ZERO)
        result.is_normalised = True

        return result
예제 #6
0
    def __init__(self, dictionary_input_output):
        cdf_input_list, cdf_output_list = convert_dict_to_sorted_lists(
            dictionary_input_output)
        list.__init__(self, cdf_input_list)
        TimeInterval.__init__(self, self[0], self[-1], 2)
        self.cdf = FunctionPiecewiseLinear(dictionary_input_output,
                                           function_undefined=FUNCTION_ZERO)
        self.cdf.dictionary_bounds_function[(self.b,
                                             POSITIVE_INFINITY)] = FUNCTION_ONE
        pdf_output_list = []
        dictionary_bounds_function = {}
        for bounds in sorted(self.cdf.dictionary_bounds_function):
            a, b = bounds
            if a in [NEGATIVE_INFINITY, POSITIVE_INFINITY
                     ] or b in [NEGATIVE_INFINITY, POSITIVE_INFINITY]:
                continue
            pdf_y_intercept = fabs(self.cdf.derivative((a + b) / 2.0))
            pdf_output_list.append(pdf_y_intercept)
            dictionary_bounds_function[bounds] = FunctionHorizontalLinear(
                pdf_y_intercept)

        self.pdf = FunctionComposite(dictionary_bounds_function,
                                     function_undefined=FUNCTION_ZERO,
                                     domain=self,
                                     is_normalised=True)

        self.roulette_wheel = []

        self._mean = 0
        for bounds in sorted(self.pdf.dictionary_bounds_function):
            (a, b) = bounds
            if a in [NEGATIVE_INFINITY, POSITIVE_INFINITY
                     ] and b in [NEGATIVE_INFINITY, POSITIVE_INFINITY]:
                continue
            cdf = self.cdf.dictionary_bounds_function[bounds]
            pdf = self.pdf.dictionary_bounds_function[bounds]
            share = cdf(b)
            self.roulette_wheel.append((a, b, share))

            self._mean += (a + b) / 2.0 * pdf(a) * (b - a)
예제 #7
0
    def function_convolution(self, dist_1, dist_2, bins=50):
        a_1, b_1, a_2, b_2 = 0, 0, 0, 0
        if dist_1 in self.bounds:
            a_1, b_1 = self.bounds[dist_1]
        else:
            a_1, b_1 = calculate_bounds_of_probability_distribution(dist_1)
            self.bounds[dist_1] = a_1, b_1
        if dist_2 in self.bounds:
            a_2, b_2 = self.bounds[dist_2]
        else:
            a_2, b_2 = calculate_bounds_of_probability_distribution(dist_2)
            self.bounds[dist_2] = a_2, b_2

        if (type(dist_1.dist), type(dist_2.dist)) == (uniform_gen,
                                                      uniform_gen):
            return self.function_convolution_uniform((a_1, b_1), (a_2, b_2))

        convolution_bounds_a, convolution_bounds_b = min(a_1,
                                                         a_2), max(b_1, b_2)

        delta = fabs(convolution_bounds_a - convolution_bounds_b) / bins
        convolution_interval = TimeInterval(convolution_bounds_a,
                                            convolution_bounds_b, bins)
        x = [dist_1.pdf(t) for t in convolution_interval]
        y = [dist_2.pdf(t) for t in reversed(convolution_interval)]

        c = convolve(x, y)
        dictionary_convolution = {}
        for t in xrange(len(c)):
            dictionary_convolution[delta * t] = c[t]
        bias = calculateCenterMass(
            dictionary_convolution)[0] + dist_2.mean() - dist_1.mean()
        dictionary_convolution_biased = {}
        for t in dictionary_convolution:
            dictionary_convolution_biased[t - bias] = dictionary_convolution[t]

        convolution_function = FunctionPiecewiseLinear(
            dictionary_convolution_biased, FunctionHorizontalLinear(0))
        return convolution_function.normalised()
예제 #8
0
    def __init__(self, dictionary_beginning, dictionary_ending, bins=50):
        input_list_beginning, output_list_beginning = convert_dict_to_sorted_lists(dictionary_beginning)
        for i in xrange(1, len(input_list_beginning)):
            if not dictionary_beginning[input_list_beginning[i]] > dictionary_beginning[input_list_beginning[i - 1]]:
                raise TypeError("values of 'dictionary_beginning' should be increasing in time")

        input_list_ending, output_list_ending = convert_dict_to_sorted_lists(dictionary_ending)
        for i in xrange(1, len(input_list_ending)):
            if not dictionary_ending[input_list_ending[i]] < dictionary_ending[input_list_ending[i - 1]]:
                raise TypeError("values of 'dictionary_ending' should be decreasing in time")
        dictionary_ending = {}
        for i, time_step in enumerate(input_list_ending):
            dictionary_ending[time_step] = output_list_ending[len(input_list_ending) - i - 1]
        input_list_ending, output_list_ending = convert_dict_to_sorted_lists(dictionary_ending)

        distribution_beginning = ProbabilityDistributionPiecewiseLinear(dictionary_beginning)
        distribution_ending = ProbabilityDistributionPiecewiseLinear(dictionary_ending)

        TemporalEvent.__init__(self, distribution_beginning, distribution_ending, bins=bins)
        self._list = sorted(set(input_list_beginning + input_list_ending))
        self.membership_function = FunctionPiecewiseLinear(self.to_dict(), FUNCTION_ZERO)
예제 #9
0
class ProbabilityDistributionPiecewiseLinear(list, TimeInterval, rv_frozen):
    dist = 'ProbabilityDistributionPiecewiseLinear'
    _mean = None
    asd = None

    def __init__(self, dictionary_input_output):
        cdf_input_list, cdf_output_list = convert_dict_to_sorted_lists(dictionary_input_output)
        list.__init__(self, cdf_input_list)
        TimeInterval.__init__(self, self[0], self[-1], 2)
        self.cdf = FunctionPiecewiseLinear(dictionary_input_output, function_undefined=FUNCTION_ZERO)
        self.cdf.dictionary_bounds_function[(self.b, POSITIVE_INFINITY)] = FUNCTION_ONE
        pdf_output_list = []
        dictionary_bounds_function = {}
        for bounds in sorted(self.cdf.dictionary_bounds_function):
            a, b = bounds
            if a in [NEGATIVE_INFINITY, POSITIVE_INFINITY] or b in [NEGATIVE_INFINITY, POSITIVE_INFINITY]:
                continue
            pdf_y_intercept = fabs(self.cdf.derivative((a + b) / 2.0))
            pdf_output_list.append(pdf_y_intercept)
            dictionary_bounds_function[bounds] = FunctionHorizontalLinear(pdf_y_intercept)

        self.pdf = FunctionComposite(dictionary_bounds_function, function_undefined=FUNCTION_ZERO, domain=self,
                                     is_normalised=True)

        self.roulette_wheel = []

        self._mean = 0
        for bounds in sorted(self.pdf.dictionary_bounds_function):
            (a, b) = bounds
            if a in [NEGATIVE_INFINITY, POSITIVE_INFINITY] and b in [NEGATIVE_INFINITY, POSITIVE_INFINITY]:
                continue
            cdf = self.cdf.dictionary_bounds_function[bounds]
            pdf = self.pdf.dictionary_bounds_function[bounds]
            share = cdf(b)
            self.roulette_wheel.append((a, b, share))

            self._mean += (a + b) / 2.0 * pdf(a) * (b - a)

    def std(self):
        # Not properly implemented
        return 0

    def stats(self, moments='mv'):
        # Not properly implemented
        # m, s, k
        return self.mean(), 0, 0

    def mean(self):
        return self._mean

    def interval(self, alpha):
        if alpha == 1:
            return self.a, self.b
        raise NotImplementedError("'interval' is not implemented for 'alpha' other than 1")

    def rvs(self, size=None):
        if size is None:
            size = 1
        else:
            assert isinstance(size, int)

        result = []
        start, end = 0, 0
        for i in xrange(size):
            rand = random()
            for a, b, share in self.roulette_wheel:
                if rand < share:
                    start, end = a, b
                    break
            result.append(random_time(start, end))

        if size == 1:
            return result[0]
        return result

    # def plot(self):
    #     import matplotlib.pyplot as plt
    #     x_axis, y_axis = [], []
    #     for time_step in self:
    #         x_axis.append(UnixTime(time_step - EPSILON).to_datetime())
    #         x_axis.append(UnixTime(time_step + EPSILON).to_datetime())
    #         y_axis.append(self.pdf(time_step - EPSILON))
    #         y_axis.append(self.pdf(time_step + EPSILON))
    #     plt.plot(x_axis, y_axis)
    #     return plt

    def plot(self):
        import matplotlib.pyplot as plt
        x_axis, y_axis = [], []
        for time_step in self:
            x_axis.append(time_step - EPSILON)
            x_axis.append(time_step + EPSILON)
            y_axis.append(self.pdf(time_step - EPSILON))
            y_axis.append(self.pdf(time_step + EPSILON))
        plt.plot(x_axis, y_axis)
        return plt

    def __hash__(self):
        return object.__hash__(self)

    def __repr__(self):
        return TimeInterval.__repr__(self)

    def __str__(self):
        return repr(self)
예제 #10
0
class ProbabilityDistributionPiecewiseLinear(list, TimeInterval, rv_frozen):
    dist = 'ProbabilityDistributionPiecewiseLinear'
    _mean = None
    asd = None

    def __init__(self, dictionary_input_output):
        cdf_input_list, cdf_output_list = convert_dict_to_sorted_lists(
            dictionary_input_output)
        list.__init__(self, cdf_input_list)
        TimeInterval.__init__(self, self[0], self[-1], 2)
        self.cdf = FunctionPiecewiseLinear(dictionary_input_output,
                                           function_undefined=FUNCTION_ZERO)
        self.cdf.dictionary_bounds_function[(self.b,
                                             POSITIVE_INFINITY)] = FUNCTION_ONE
        pdf_output_list = []
        dictionary_bounds_function = {}
        for bounds in sorted(self.cdf.dictionary_bounds_function):
            a, b = bounds
            if a in [NEGATIVE_INFINITY, POSITIVE_INFINITY
                     ] or b in [NEGATIVE_INFINITY, POSITIVE_INFINITY]:
                continue
            pdf_y_intercept = fabs(self.cdf.derivative((a + b) / 2.0))
            pdf_output_list.append(pdf_y_intercept)
            dictionary_bounds_function[bounds] = FunctionHorizontalLinear(
                pdf_y_intercept)

        self.pdf = FunctionComposite(dictionary_bounds_function,
                                     function_undefined=FUNCTION_ZERO,
                                     domain=self,
                                     is_normalised=True)

        self.roulette_wheel = []

        self._mean = 0
        for bounds in sorted(self.pdf.dictionary_bounds_function):
            (a, b) = bounds
            if a in [NEGATIVE_INFINITY, POSITIVE_INFINITY
                     ] and b in [NEGATIVE_INFINITY, POSITIVE_INFINITY]:
                continue
            cdf = self.cdf.dictionary_bounds_function[bounds]
            pdf = self.pdf.dictionary_bounds_function[bounds]
            share = cdf(b)
            self.roulette_wheel.append((a, b, share))

            self._mean += (a + b) / 2.0 * pdf(a) * (b - a)

    def std(self):
        # Not properly implemented
        return 0

    def stats(self, moments='mv'):
        # Not properly implemented
        # m, s, k
        return self.mean(), 0, 0

    def mean(self):
        return self._mean

    def interval(self, alpha):
        if alpha == 1:
            return self.a, self.b
        raise NotImplementedError(
            "'interval' is not implemented for 'alpha' other than 1")

    def rvs(self, size=None):
        if size is None:
            size = 1
        else:
            assert isinstance(size, int)

        result = []
        start, end = 0, 0
        for i in xrange(size):
            rand = random()
            for a, b, share in self.roulette_wheel:
                if rand < share:
                    start, end = a, b
                    break
            result.append(random_time(start, end))

        if size == 1:
            return result[0]
        return result

    # def plot(self):
    #     import matplotlib.pyplot as plt
    #     x_axis, y_axis = [], []
    #     for time_step in self:
    #         x_axis.append(UnixTime(time_step - EPSILON).to_datetime())
    #         x_axis.append(UnixTime(time_step + EPSILON).to_datetime())
    #         y_axis.append(self.pdf(time_step - EPSILON))
    #         y_axis.append(self.pdf(time_step + EPSILON))
    #     plt.plot(x_axis, y_axis)
    #     return plt

    def plot(self):
        import matplotlib.pyplot as plt
        x_axis, y_axis = [], []
        for time_step in self:
            x_axis.append(time_step - EPSILON)
            x_axis.append(time_step + EPSILON)
            y_axis.append(self.pdf(time_step - EPSILON))
            y_axis.append(self.pdf(time_step + EPSILON))
        plt.plot(x_axis, y_axis)
        return plt

    def __hash__(self):
        return object.__hash__(self)

    def __repr__(self):
        return TimeInterval.__repr__(self)

    def __str__(self):
        return repr(self)