import torch


def smooth_dice_beta_loss(pred: torch.Tensor, target: torch.Tensor,
                          beta: float=1., smooth: float=1., eps: float=1e-6) -> torch.Tensor:
    """
    Smoothed dice beta loss. Computes
    1 - (((1 + beta**2) * tp + smooth) / ((1 + beta**2) * tp + beta**2 * fn + fp + smooth + eps))

    :param pred: (torch.Tensor) predictions, logits
    :param target: (torch.Tensor) target, logits or binray
    :param beta: (float) weight to emphasize recall
    :param smooth: (float) smoothing value
    :param eps: (eps) epsilon for numerical stability

    :returns dice_loss: (torch.Tensor) the dice loss
    """

    pred = torch.sigmoid(pred)
    target = (target > 0).float()

    tp = (pred.reshape(-1) * target.reshape(-1)).sum()
    fp = pred.reshape(-1).sum() - tp
    tn = ((1 - pred).reshape(-1) * (1-target).reshape(-1)).sum()
    fn = (1 - pred).reshape(-1).sum() - tn

    return 1 - (((1 + beta ** 2) * tp + smooth) / \
           ((1 + beta ** 2) * tp + beta ** 2 * fn + fp + smooth + eps))