@@ -108,18 +108,35 @@ def to_intervalindex(coords: np.ndarray, resolution: float) -> pd.IntervalIndex:
108108 )
109109
110110
111- def overlaps (a : pd .Interval , b : pd .Interval ):
112- """Return the overlap (fraction) between two Pandas intervals."""
113- return max (
114- min (a .right , b .right ) - max (a .left , b .left ),
115- 0
111+ def overlap (a : pd .IntervalIndex , b : pd .IntervalIndex ) -> np .ndarray :
112+ """Calculate the overlap between two sets of intervals.
113+
114+ Args:
115+ a: Pandas IntervalIndex containing the first set of intervals.
116+ b: Pandas IntervalIndex containing the second set of intervals.
117+
118+ Returns:
119+ 2D numpy array containing overlap (as a fraction) between the intervals of a
120+ and b. If there is no overlap, the value will be 0.
121+ """
122+ # TODO: newaxis on B and transpose is MUCH faster on benchmark.
123+ # likely due to it being the bigger dimension.
124+ # size(a) > size(b) leads to better perf than size(b) > size(a)
125+ mins = np .minimum (
126+ a .right .to_numpy (),
127+ b .right .to_numpy ()[:, np .newaxis ]
128+ )
129+ maxs = np .maximum (
130+ a .left .to_numpy (),
131+ b .left .to_numpy ()[:, np .newaxis ]
116132 )
133+ return np .maximum (mins - maxs , 0 ).T
117134
118135
119136def normalize_overlap (overlap : np .ndarray ) -> np .ndarray :
120137 """Normalize overlap values so they sum up to 1.0 along the first axis."""
121138 overlap_sum = overlap .sum (axis = 0 )
122- overlap_sum [overlap_sum == 0 ] = 1e-6 # Avoid dividing by 0
139+ overlap_sum [overlap_sum == 0 ] = 1e-12 # Avoid dividing by 0.
123140 return (overlap / overlap_sum )
124141
125142
0 commit comments