import torch


def bb_iou(bb1, bb2):
    """Given a single bounding box and a set of bounding boxes,
    this will return the ious between every pair.

    Parameters
    ----------
        bb1 : Tensor
            A single bounding box.
        bb2 : Tensor
            Multiple bounding boxes.

    Returns
    -------
    Tensor

    """
    bb1_x1, bb1_y1, bb1_x2, bb1_y2 = bb1[..., :4].split(1, dim=-1)
    bb2_x1, bb2_y1, bb2_x2, bb2_y2 = bb2[..., :4].split(1, dim=-1)

    intersection_x1 = torch.max(bb1_x1, bb2_x1)
    intersection_y1 = torch.max(bb1_y1, bb2_y1)
    intersection_x2 = torch.min(bb1_x2, bb2_x2)
    intersection_y2 = torch.min(bb1_y2, bb2_y2)

    interection_width = torch.clamp(intersection_x2 - intersection_x1 + 1, 0)
    interection_height = torch.clamp(intersection_y2 - intersection_y1 + 1, 0)
    intersection_area = interection_width * interection_height
    bb1_area = (bb1_x2 - bb1_x1 + 1) * (bb1_y2 - bb1_y1 + 1)
    bb2_area = (bb2_x2 - bb2_x1 + 1) * (bb2_y2 - bb2_y1 + 1)

    iou = intersection_area / (bb1_area + bb2_area - intersection_area)
    return iou