| | import numpy as np |
| | from scipy.optimize import linear_sum_assignment |
| |
|
| | def temporal_iou(pred_span, gt_span): |
| | """ |
| | Calculate 1D Intersection over Union (IoU) between two temporal spans. |
| | Args: |
| | pred_span (tuple/list): Predicted temporal span (start, end) |
| | gt_span (tuple/list): Ground truth temporal span (start, end) |
| | Returns: |
| | float: IoU score between 0 and 1 |
| | """ |
| | pred_start, pred_end = pred_span |
| | gt_start, gt_end = gt_span |
| | |
| | |
| | if pred_end < pred_start or gt_end < gt_start: |
| | raise ValueError("End time cannot be before start time") |
| | |
| | |
| | intersection_start = max(pred_start, gt_start) |
| | intersection_end = min(pred_end, gt_end) |
| | |
| | if intersection_end <= intersection_start: |
| | return 0.0 |
| | |
| | intersection = intersection_end - intersection_start |
| | |
| | |
| | pred_duration = pred_end - pred_start |
| | gt_duration = gt_end - gt_start |
| | union = pred_duration + gt_duration - intersection |
| | |
| | |
| | iou = intersection / union |
| | |
| | return float(iou) |
| |
|
| | def match_temporal_iou(preds, gts): |
| | """ |
| | Find optimal matching between predicted and ground truth temporal spans using Hungarian algorithm. |
| | |
| | Args: |
| | preds (list): List of predicted temporal spans, each span is [start, end] |
| | gts (list): List of ground truth temporal spans, each span is [start, end] |
| | |
| | Returns: |
| | tuple: (matched_indices, total_iou) |
| | - matched_indices: List of (pred_idx, gt_idx) pairs |
| | - total_iou: Sum of IoUs for the matched pairs |
| | """ |
| | if not preds or not gts: |
| | return [], 0.0 |
| | |
| | |
| | cost_matrix = np.zeros((len(preds), len(gts))) |
| | for i, pred in enumerate(preds): |
| | for j, gt in enumerate(gts): |
| | cost_matrix[i, j] = -temporal_iou(pred, gt) |
| | |
| | |
| | pred_indices, gt_indices = linear_sum_assignment(cost_matrix) |
| | |
| | |
| | matched_pairs = list(zip(pred_indices, gt_indices)) |
| | total_iou = -cost_matrix[pred_indices, gt_indices].sum() |
| | avg_iou = total_iou / len(gts) |
| | |
| | return matched_pairs, avg_iou |
| | ''' |
| | # Example usage: |
| | if __name__ == "__main__": |
| | # Example predictions and ground truths |
| | predictions = [[10, 20], [25, 35], [40, 50], [50, 55]] |
| | ground_truths = [[15, 25], [30, 40], [45, 55]] |
| | |
| | # Find optimal matching |
| | matches, avg_iou = match_temporal_iou(predictions, ground_truths) |
| | |
| | print("Matched pairs (pred_idx, gt_idx):", matches) |
| | print("Avg IoU:", avg_iou) |
| | |
| | # Print individual IoUs for matched pairs |
| | print("\nIndividual IoUs:") |
| | for pred_idx, gt_idx in matches: |
| | iou = temporal_iou(predictions[pred_idx], ground_truths[gt_idx]) |
| | print(f"Pred {pred_idx} - GT {gt_idx}: {iou:.3f}") |
| | ''' |
| |
|
| |
|
| | def find_difference_range(s1, s2): |
| | |
| | s1_mid = s1[1:-1] |
| | s2_mid = s2[1:-1] |
| | |
| | n = len(s1_mid) |
| | if n != len(s2_mid): |
| | return None |
| | |
| | |
| | start = 0 |
| | while start < n and s1_mid[start] == s2_mid[start]: |
| | start += 1 |
| | |
| | |
| | end = n - 1 |
| | while end >= start and s1_mid[end] == s2_mid[end]: |
| | end -= 1 |
| | |
| | |
| | return [start + 1, end + 1] if start <= end else None |
| |
|
| | ''' |
| | # Test with your example |
| | s1 = "GIBJBIGCHEHCGIBFAD-" |
| | s2 = "GIBJBIGCHED----FADG" |
| | result = find_difference_range(s1, s2) |
| | print(f"Different substrings: '{s1[result[0]:result[1]+1]}' and '{s2[result[0]:result[1]+1]}'") |
| | ''' |
| |
|
| |
|
| |
|
| | def get_overlapping_substring(s1, s2, best_offset, max_matches): |
| | len1 = len(s1) |
| | len2 = len(s2) |
| | start_index_s1 = -1 |
| | start_index_s2 = -1 |
| |
|
| | for i in range(len1): |
| | j = i - best_offset |
| | if 0 <= j < len2 and s1[i] == s2[j]: |
| | start_index_s1 = i |
| | start_index_s2 = j |
| | break |
| |
|
| | if start_index_s1 != -1: |
| | return s1[start_index_s1 : start_index_s1 + max_matches] |
| | else: |
| | return "" |
| |
|
| | ''' |
| | string1 = 'JBHKHBJGCEID' |
| | string2 = 'BJGCEIDIALFKCGJ' |
| | best_offset, max_matches = align_strings(string1, string2) |
| | overlapping_part = get_overlapping_substring(string1, string2, best_offset, max_matches) |
| | print("String 1:", string1) |
| | print("String 2:", string2) |
| | print("\nOverlapping part:", overlapping_part) |
| | ''' |
| |
|
| |
|
| | def find_difference_range(s1, s2): |
| | |
| | s1_mid = s1[1:-1] |
| | s2_mid = s2[1:-1] |
| | |
| | n = len(s1_mid) |
| | if n != len(s2_mid): |
| | return None |
| | |
| | |
| | start = 0 |
| | while start < n and s1_mid[start] == s2_mid[start]: |
| | start += 1 |
| | |
| | |
| | end = n - 1 |
| | while end >= start and s1_mid[end] == s2_mid[end]: |
| | end -= 1 |
| | |
| | |
| | return [start + 1, end + 1] if start <= end else None |
| | ''' |
| | # Test with your example |
| | s1 = "GIBJBIGCHEHCGIBFAD-" |
| | s2 = "GIBJBIGCHED----FADG" |
| | result = find_difference_range(s1, s2) |
| | print(f"Different substrings: '{s1[result[0]:result[1]+1]}' and '{s2[result[0]:result[1]+1]}'") |
| | print(f"Range index: {result}") |
| | ''' |