def bind_wagons_vertical(self, rail_1_key, wagon_1_index, rail_2_key, wagon_2_index): wagon_1 = self.rails[rail_1_key][wagon_1_index] wagon_2 = self.rails[rail_2_key][wagon_2_index] self.memo.append(('bind_wagons_vertical', (rail_1_key, wagon_1_index, rail_2_key, wagon_2_index))) wagon_2.bind(wagon_1) equals_a = almost_equals(wagon_1.a, wagon_2.a, EPSILON) equals_b = almost_equals(wagon_1.b, wagon_2.b, EPSILON) if (wagon_1.a < wagon_2.a or equals_a) and (wagon_1.b < wagon_2.b or equals_b): self.dag[wagon_1][wagon_2] = 1 if (wagon_1.a > wagon_2.a or equals_a) and (wagon_1.b > wagon_2.b or equals_b): self.dag[wagon_2][wagon_1] = 1
def expand(node, relations): successors = [] rails = node.rails new_unpack_states = deepcopy(node.unpack_states) relation = None for key, unpacked in node.unpack_states.items(): if not unpacked: relation = key new_unpack_states[relation] = True break if relation is None: return [] temporal_event_1_key, portion_index_1, temporal_event_2_key, portion_index_2 = relation relation = relations[relation] start_reference = rails[temporal_event_2_key][portion_index_2].a length_reference = rails[temporal_event_2_key][portion_index_2].length if relation == (1.0, 0.0, 0.0): new_rails = deepcopy(rails) new_rails.bind_wagons_before_horizontal(temporal_event_1_key, portion_index_1, temporal_event_2_key, portion_index_2) return [Node(new_rails, new_unpack_states)] if relation == (0.0, 0.0, 1.0): new_rails = deepcopy(rails) new_rails.bind_wagons_after_horizontal(temporal_event_1_key, portion_index_1, temporal_event_2_key, portion_index_2) return [Node(new_rails, new_unpack_states)] candidates = unpack(relation, start_reference, length_reference) for a, b in candidates: reference = rails[temporal_event_2_key][portion_index_2] new_rails = deepcopy(rails) new_rails.move_and_bind_vertical(temporal_event_1_key, portion_index_1, temporal_event_2_key, portion_index_2, a, b) new_reference = new_rails[temporal_event_2_key][portion_index_2] if not almost_equals(new_reference.a, reference.a, EPSILON) or\ not almost_equals(new_reference.b, reference.b, EPSILON): continue successors.append(Node(new_rails, deepcopy(new_unpack_states))) return successors
def expand(node, relations): successors = [] rails = node.rails new_unpack_states = deepcopy(node.unpack_states) relation = None for key, unpacked in node.unpack_states.items(): if not unpacked: relation = key new_unpack_states[relation] = True break if relation is None: return [] temporal_event_1_key, portion_index_1, temporal_event_2_key, portion_index_2 = relation relation = relations[relation] start_reference = rails[temporal_event_2_key][portion_index_2].a length_reference = rails[temporal_event_2_key][portion_index_2].length if relation == (1.0, 0.0, 0.0): new_rails = deepcopy(rails) new_rails.bind_wagons_before_horizontal( temporal_event_1_key, portion_index_1, temporal_event_2_key, portion_index_2 ) return [Node(new_rails, new_unpack_states)] if relation == (0.0, 0.0, 1.0): new_rails = deepcopy(rails) new_rails.bind_wagons_after_horizontal( temporal_event_1_key, portion_index_1, temporal_event_2_key, portion_index_2 ) return [Node(new_rails, new_unpack_states)] candidates = unpack(relation, start_reference, length_reference) for a, b in candidates: reference = rails[temporal_event_2_key][portion_index_2] new_rails = deepcopy(rails) new_rails.move_and_bind_vertical( temporal_event_1_key, portion_index_1, temporal_event_2_key, portion_index_2, a, b ) new_reference = new_rails[temporal_event_2_key][portion_index_2] if not almost_equals(new_reference.a, reference.a, EPSILON) or not almost_equals( new_reference.b, reference.b, EPSILON ): continue successors.append(Node(new_rails, deepcopy(new_unpack_states))) return successors
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
def __init__(self, a, b, beginning=None, ending=None, beginning_factor=None, ending_factor=None): """ start and end can be in either datetime or unix time """ a, b = UnixTime(a), UnixTime(b) assert a < b, "'b' should be greater than 'a'" if (beginning, ending) != (None, None): assert (beginning_factor, ending_factor) == (None, None), "PiecewiseTemporalEvent() only accepts " \ "either 'beginning_factor' and 'ending_factor' " \ "or 'beginning' and 'ending'" if not a < beginning and ending < b and (beginning < ending or almost_equals(beginning, ending)): raise AttributeError("The inputs should satisfy 'a < beginning <= ending < b' relation") if beginning_factor is not None: assert beginning_factor > 0 self.beginning_factor = beginning_factor if ending_factor is not None: assert ending_factor > 0 self.ending_factor = ending_factor if (beginning, ending) == (None, None): beginning, ending = 0, 0 while not a < beginning < ending < b: beginning = random_time( a, b, probability_distribution=t( # df, mean, variance 4, a + float(b - a) / self.beginning_factor, float(b - a) / self.beginning_factor ) ) ending = random_time( a, b, probability_distribution=t( # df, mean, variance 4, b - float(b - a) / self.ending_factor, float(b - a) / self.ending_factor ) ) TemporalEvent.__init__(self, uniform(loc=a, scale=UnixTime(beginning - a)), uniform(loc=ending, scale=UnixTime(b - ending)), bins=4)
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