import torch


def BCELoss_labels_weighted(P: torch.Tensor, Y: torch.Tensor, W: torch.Tensor) \
        -> torch.Tensor:
    """
    Binary cross entropy loss which allows for different weights for different labels.

    Parameters
    ----------
    P : torch.Tensor
        The predicted labels.
    Y : torch.Tensor
        The true labels.
    W : torch.Tensor
        The weights per label.

    Returns
    -------
    loss : torch.Tensor
        Tensor object of size (1,1) containing the loss value.
    """
    P = torch.clamp(P, min=1e-7, max=1 - 1e-7)
    bce = W * (- Y * torch.log(P) - (1 - Y) * torch.log(1 - P))
    loss = torch.mean(bce)
    return loss