import torch


def smooth_weights(class_freqs: torch.Tensor,
                   smoothing: float = 0.15,
                   clip: float = 10.0,
                   normalize: bool = True) -> torch.Tensor:
    """Compute smoothed weights starting from class frequencies (pixel counts).

    Args:
        class_freqs (torch.Tensor): tensor with shape (num_classes,)
        smoothing (float, optional): smoothing factor. Defaults to 0.15.
        clip (float, optional): maximum value before clipping. Defaults to 10.0.
        normalize (bool, optional): whether to map them to range [0, 1]. Defaults to True.

    Returns:
        torch.Tensor: weights inversely proportial to frequencies, normalized if required
    """
    # the larger the smooth factor, the bigger the quantities to sum to the remaining counts (additive smoothing)
    freqs = class_freqs.float() + class_freqs.max() * smoothing
    # retrieve the (new) max value, divide by counts, clip to max. value
    weights = torch.clamp(freqs.max() / class_freqs, min=1.0, max=clip)
    if normalize:
        weights /= weights.max()
    return weights