//  [python]
def compute_likelihood(testset, model, device, configs):
    """
    Compute the approximated log-likelihood calculated using 1000 importance-weighted samples.

    Parameters
    ----------
    testset: torch.utils.data.Dataset
        The test dataset
    model: models.model.TreeVAE
        The trained TreeVAE model
    device: torch.device
        The device in which to validate the model
    configs: dict
        The config setting for training and validating TreeVAE defined in configs or in the command line
    """
    ESTIMATION_SAMPLES = 1000
    gen_test = get_gen(testset, configs, validation=True, shuffle=False)
    print('\nComputing the log likelihood.... it might take a while.')
    if configs['training']['activation'] == 'sigmoid':
        elbo = np.zeros((len(testset), ESTIMATION_SAMPLES))
        for j in tqdm(range(ESTIMATION_SAMPLES)):
            elbo[:, j] = predict(gen_test, model, device, 'elbo')
            _ = gc.collect()
        elbo_new = elbo[:, :ESTIMATION_SAMPLES]
        log_likel = np.log(1 / ESTIMATION_SAMPLES) + scipy.special.logsumexp(-elbo_new, axis=1)
        marginal_log_likelihood = np.sum(log_likel) / len(testset)
        wandb.log({"test log-likelihood": marginal_log_likelihood})
        print("Test log-likelihood", marginal_log_likelihood)
        output_elbo, output_rec_loss = predict(gen_test, model, device, 'elbo', 'rec_loss')
        print('Test ELBO:', -torch.mean(output_elbo))
        print('Test Reconstruction Loss:', torch.mean(output_rec_loss))

    elif configs['training']['activation'] == 'mse':
        # Correct calculation of ELBO and Loglikelihood for 3channel images without assuming diagonal gaussian for
        # reconstruction
        old_loss = model.loss
        model.loss = loss_reconstruction_cov_mse_eval
        # Note that for comparability to other papers, one might want to add Uniform(0,1) noise to the input images
        # (in 0,255), to go from the discrete to the assumed continuous inputs
        #    x_test_elbo = x_test * 255
        #    x_test_elbo = (x_test_elbo + tfd.Uniform().sample(x_test_elbo.shape)) / 256
        output_elbo, output_rec_loss = predict(gen_test, model, device, 'elbo', 'rec_loss')
        nelbo = torch.mean(output_elbo)
        nelbo_bpd = nelbo / (torch.log(torch.tensor(2)) * configs['training']['inp_shape']) + 8  # Add 8 to account normalizing of inputs
        model.loss = old_loss
        elbo = np.zeros((len(testset), ESTIMATION_SAMPLES))
        for j in range(ESTIMATION_SAMPLES):
            # x_test_elbo = x_test * 255
            # x_test_elbo = (x_test_elbo + tfd.Uniform().sample(x_test_elbo.shape)) / 256
            output_elbo = predict(gen_test, model, device, 'elbo')
            elbo[:, j] = output_elbo
        # Change to bpd
        elbo_new = elbo[:, :ESTIMATION_SAMPLES]
        log_likel = np.log(1 / ESTIMATION_SAMPLES) + scipy.special.logsumexp(-elbo_new, axis=1)
        marginal_log_likelihood = np.sum(log_likel) / len(testset)
        marginal_log_likelihood = marginal_log_likelihood / (
                torch.log(torch.tensor(2)) * configs['training']['inp_shape']) - 8
        wandb.log({"test log-likelihood": marginal_log_likelihood})
        print('Test Log-Likelihood Bound:', marginal_log_likelihood)
        print('Test ELBO:', -nelbo_bpd)
        print('Test Reconstruction Loss:',
              torch.mean(output_rec_loss) / (torch.log(torch.tensor(2)) * configs['training']['inp_shape']) + 8)
        model.loss = old_loss
    else:
        raise NotImplementedError
    return