File size: 2,888 Bytes
3133b5e e7eaeed |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 |
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,
)
|