import torch


def evaluate_sce(confidences: torch.Tensor,
                 true_labels: torch.Tensor,
                 n_bins: int = 15) -> float:
    """
    Args:
        confidences (Tensor): a tensor of shape [N, K] of predicted confidences.
        true_labels (Tensor): a tensor of shape [N,] of ground truth labels.
        n_bins (int): the number of bins used by the histrogram binning.
    
    Returns:
        sce (float): static calibration error of predictions.
    """
    ticks = torch.linspace(0, 1, n_bins + 1)
    bin_lowers = ticks[:-1]
    bin_uppers = ticks[ 1:]
    
    n_objects, n_classes = confidences.size()
    sce = torch.zeros(1, device=confidences.device)
    for cur_class in range(n_classes):
        for bin_lower, bin_upper in zip(bin_lowers, bin_uppers):
            cur_class_conf = confidences[:, cur_class]
            in_bin = cur_class_conf.gt(
                bin_lower.item()
            ) * cur_class_conf.le(
                bin_upper.item()
            )

            bin_acc = true_labels[in_bin].eq(cur_class)
            bin_conf = cur_class_conf[in_bin]

            bin_size = torch.sum(in_bin)
            if bin_size > 0:
                avg_confidence_in_bin = torch.mean(bin_conf.float())
                avg_accuracy_in_bin = torch.mean(bin_acc.float())
                delta = torch.abs(avg_confidence_in_bin - avg_accuracy_in_bin)
                sce += delta * bin_size / (n_objects * n_classes)

    return sce.item()