| from typing import Tuple | |
| def get_overlap_len(indices_1: Tuple[int, int], indices_2: Tuple[int, int]) -> int: | |
| if indices_1[0] > indices_2[0]: | |
| tmp = indices_1 | |
| indices_1 = indices_2 | |
| indices_2 = tmp | |
| if indices_1[1] <= indices_2[0]: | |
| return 0 | |
| return min(indices_1[1] - indices_2[0], indices_2[1] - indices_2[0]) | |
| def have_overlap(start_end: Tuple[int, int], other_start_end: Tuple[int, int]) -> bool: | |
| other_start_overlaps = start_end[0] <= other_start_end[0] < start_end[1] | |
| other_end_overlaps = start_end[0] < other_start_end[1] <= start_end[1] | |
| start_overlaps_other = other_start_end[0] <= start_end[0] < other_start_end[1] | |
| end_overlaps_other = other_start_end[0] < start_end[1] <= other_start_end[1] | |
| return other_start_overlaps or other_end_overlaps or start_overlaps_other or end_overlaps_other | |
| def is_contained_in(start_end: Tuple[int, int], other_start_end: Tuple[int, int]) -> bool: | |
| return other_start_end[0] <= start_end[0] and start_end[1] <= other_start_end[1] | |
| def distance_center(start_end: Tuple[int, int], other_start_end: Tuple[int, int]) -> float: | |
| center = (start_end[0] + start_end[1]) / 2 | |
| center_other = (other_start_end[0] + other_start_end[1]) / 2 | |
| return abs(center - center_other) | |
| def distance_outer(start_end: Tuple[int, int], other_start_end: Tuple[int, int]) -> float: | |
| _max = max(start_end[0], start_end[1], other_start_end[0], other_start_end[1]) | |
| _min = min(start_end[0], start_end[1], other_start_end[0], other_start_end[1]) | |
| return float(_max - _min) | |
| def distance_inner(start_end: Tuple[int, int], other_start_end: Tuple[int, int]) -> float: | |
| dist_start_other_end = abs(start_end[0] - other_start_end[1]) | |
| dist_end_other_start = abs(start_end[1] - other_start_end[0]) | |
| dist = float(min(dist_start_other_end, dist_end_other_start)) | |
| if not have_overlap(start_end, other_start_end): | |
| return dist | |
| else: | |
| return -dist | |
| def distance( | |
| start_end: Tuple[int, int], other_start_end: Tuple[int, int], distance_type: str | |
| ) -> float: | |
| if distance_type == "center": | |
| return distance_center(start_end, other_start_end) | |
| elif distance_type == "inner": | |
| return distance_inner(start_end, other_start_end) | |
| elif distance_type == "outer": | |
| return distance_outer(start_end, other_start_end) | |
| else: | |
| raise ValueError( | |
| f"unknown distance_type={distance_type}. use one of: center, inner, outer" | |
| ) | |
| def distance_slices( | |
| slices: Tuple[Tuple[int, int], ...], | |
| other_slices: Tuple[Tuple[int, int], ...], | |
| distance_type: str, | |
| ) -> float: | |
| starts, ends = zip(*slices) | |
| other_starts, other_ends = zip(*other_slices) | |
| return distance( | |
| start_end=(min(starts), max(ends)), | |
| other_start_end=(min(other_starts), max(other_ends)), | |
| distance_type=distance_type, | |
| ) | |