import torch


def trainGenerator(netG, netD, optimiserG, inputs, targets, loss_func, device, lambdapar):
    """
    This function trains the generator
    :param netG:       The generator network
    :param netD:       The discriminator network
    :param optimiserG: The optimiser for the generator
    :param inputs:     The low resolution input signal for training
    :param targets:    The high resolution target signal for training
    :param loss_func:  The non-adversarial loss function used
    :param device:     The device the model is training on
    :param lambdapar:  The hyperparameter altering the proportion of the loss that is adversarial
    :return: The generator loss
    """

    optimiserG.zero_grad()
    fake_waves = netG(inputs.clone()).to(device)
    fake_validity = netD(fake_waves.clone())
    normal_loss = loss_func(fake_waves.clone(), targets.clone())
    g_loss = normal_loss - lambdapar * torch.mean(fake_validity)
    g_loss.backward()
    optimiserG.step()
    return g_loss