import torch


def compute_ce_split_loss(asv_predictions, cm_predictions, targets, is_spoof, args):
    """
    Yer standard cross-entropy loss, but this time targets are split such that
    ASV and CM will still do their own tasks.

    Parameters:
        asv_predictions: Torch tensor of (N, 1), the single value representing
                         probability of passing this trial through ASV
        cm_predictions: Torch tensor of (N, 1), the single representing
                        probability of passing this trial through CM
        targets: Torch tensor of (N, 1), indicating if corresponding trial
                 is truly accept or reject
        args: Argparse arguments

    Return:
        Torch tensor with the loss to be minimized
    """

    is_spoof_bool = is_spoof.bool()

    # ASV only considers non-spoof samples
    asv_loss = torch.nn.functional.binary_cross_entropy(
        asv_predictions[~is_spoof_bool],
        targets[~is_spoof_bool]
    )

    is_spoof_float = is_spoof.float()
    # CM considers all samples, but target is 1.0 - is_spoof
    # (prediction 1 means accept)
    cm_loss = torch.nn.functional.binary_cross_entropy(
        cm_predictions,
        1.0 - is_spoof_float
    )

    total_loss = asv_loss + cm_loss
    return total_loss