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) if (portion_after + portion_before) == 0: pass after = portion_after / (portion_after + portion_before) * non_same_portion return 1.0 - same - after, same, after
def unpack(self, relation_a_b_beginning, relation_a_b_ending): before_a_b_beginning, same_a_b_beginning, after_a_b_beginning = relation_a_b_beginning before_a_b_ending, same_a_b_ending, after_a_b_ending = relation_a_b_ending if almost_equals(before_a_b_beginning + same_a_b_beginning + same_a_b_ending + after_a_b_ending, 2.0, epsilon): return [], uniform_reference # Inconsistent if almost_equals(before_a_b_beginning + before_a_b_ending, 2.0, epsilon): return [], uniform_reference if almost_equals(after_a_b_beginning + after_a_b_ending, 2.0, epsilon): return [], uniform_reference if almost_equals(before_a_b_ending, 1.0, epsilon): return self.unpack_partial(relation_a_b_beginning), uniform_reference if almost_equals(after_a_b_beginning, 1.0, epsilon): return self.unpack_partial(relation_a_b_ending), uniform_reference a_possibilities = self.unpack_partial(relation_a_b_beginning) if len(a_possibilities) == 1: a_possibility = a_possibilities[0] return else: a_possibility_1, a_possibility_2 = a_possibilities a_possibility = a_possibility_1 if a_possibility.args[1] < a_possibility_2.args[1]: a_possibility = a_possibility_2 a_start_point, length_a = a_possibility.args if before_a_b_ending * same_a_b_ending * after_a_b_ending > 0: if almost_equals(before_a_b_beginning, 0, epsilon): length_b_ending = length_a * same_a_b_ending ** 2 else: length_b_ending = same_a_b_ending ** 2 / same_a_b_beginning ** 2 b_ending = uniform(a_start_point + before_a_b_ending * (length_a - length_b_ending) / (before_a_b_ending + after_a_b_ending), length_b_ending) return [a_possibility], b_ending else: denominator = length_a * same_a_b_ending ** 2 length_b_ending_lower_bound = (length_a * same_a_b_ending ** 2) ** 2 / denominator length_b_ending_upper_bound = (a_start_point + length_a - 1) ** 2 / denominator length_b_ending = (length_b_ending_lower_bound + length_b_ending_upper_bound) / 2.0 b_start_point = a_start_point + length_a - same_a_b_ending * sqrt(length_b_ending * length_a) b_ending = uniform(b_start_point, length_b_ending) return [a_possibility], b_ending
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) if (portion_after + portion_before) == 0: pass after = portion_after / (portion_after + portion_before) * non_same_portion return 1.0 - same - after, same, after
def combine(self, relation_a_b_beginning, relation_a_b_ending, relation_b_beginning_c, relation_b_ending_c): before_a_b, same_a_b, after_a_b = relation_a_b_beginning before_b_c, same_b_c, after_b_c = relation_b_beginning_c unknown = 1.0 / 3 if almost_equals(before_a_b + before_b_c, 2.0, epsilon)\ or almost_equals(before_a_b + same_b_c, 2.0, epsilon)\ or almost_equals(same_a_b + before_b_c, 2.0, epsilon): return [(1.0, 0.0, 0.0)] if almost_equals(after_a_b + after_b_c, 2.0, epsilon)\ or almost_equals(after_a_b + same_b_c, 2.0, epsilon)\ or almost_equals(same_a_b + after_b_c, 2.0, epsilon): return [(1.0, 0.0, 0.0)] if almost_equals(same_a_b + same_b_c, 2.0, epsilon): return [(0.0, 1.0, 0.0)] if almost_equals(before_a_b + after_b_c, 2.0, epsilon) or almost_equals(after_a_b + before_b_c, 2.0, epsilon): return [(unknown, unknown, unknown)] relation_a_c_possibilities = [] a_possibilities, b_ending_1 = self.unpack(relation_a_b_beginning, relation_a_b_ending) c_possibilities, b_ending_2 = self.unpack(tuple(reversed(relation_b_beginning_c)), tuple(reversed(relation_b_ending_c))) if len(a_possibilities) == 0: if before_a_b == 0: if len(c_possibilities) == 1: if before_b_c == 0: relation_a_c_possibilities.append((0.0, 0.0, 1.0)) else: relation_a_c_possibilities.append((unknown, unknown, unknown)) else: relation_a_c_possibilities.append((unknown, unknown, unknown)) relation_a_c_possibilities.append((0.0, 0.0, 1.0)) else: if len(c_possibilities) == 1: if after_b_c == 0: relation_a_c_possibilities.append((1.0, 0.0, 0.0)) else: relation_a_c_possibilities.append((unknown, unknown, unknown)) else: relation_a_c_possibilities.append((unknown, unknown, unknown)) relation_a_c_possibilities.append((1.0, 0.0, 0.0)) if len(c_possibilities) == 0: if before_b_c == 0: if len(a_possibilities) == 1: if before_a_b == 0: relation_a_c_possibilities.append((0.0, 0.0, 1.0)) else: relation_a_c_possibilities.append((unknown, unknown, unknown)) else: relation_a_c_possibilities.append((unknown, unknown, unknown)) relation_a_c_possibilities.append((0.0, 0.0, 1.0)) else: if len(a_possibilities) == 1: if after_a_b == 0: relation_a_c_possibilities.append((1.0, 0.0, 0.0)) else: relation_a_c_possibilities.append((unknown, unknown, unknown)) else: relation_a_c_possibilities.append((unknown, unknown, unknown)) relation_a_c_possibilities.append((1.0, 0.0, 0.0)) for possible_a in a_possibilities: for possible_c in c_possibilities: relation_a_c_possibilities.append(self.relation_formula.compare(possible_a, possible_c)) return relation_a_c_possibilities