# Path: cortex/built_ins/models/gan.py
# def raise_measure_error(measure):
# def get_positive_expectation(p_samples, measure, average=True):
# def get_negative_expectation(q_samples, measure, average=True):
# def get_boundary(samples, measure):
# def get_weight(samples, measure):
# def generator_loss(q_samples, measure, loss_type=None):
#     def routine(self, inputs, penalty_type: str='contractive',
#                 penalty_amount: float=0.5):
#     def _get_gradient(inp, output):
#     def contractive_penalty(self, network, input, penalty_amount=0.5):
#     def interpolate_penalty(self, network, input, penalty_amount=0.5):
#     def build(self, discriminator_type: str='convnet', discriminator_args={}):
#     def routine(self, real, fake, measure: str='GAN'):
#     def score(self, X_P, X_Q, measure):
#     def visualize(self, real, fake, measure=None):
#     def build(self, dim_in: int=None, discriminator_args=dict(dim_h=[200, 200])):
#     def build(self, dim_z=64, generator_type: str='convnet',
#               generator_args=dict(output_nonlinearity='tanh')):
#     def routine(self, Z, measure: str=None, loss_type: str='non-saturating'):
#     def generate(self, Z):
#     def visualize(self, Z):
#     def __init__(self):
#     def build(self, noise_type='normal', dim_z=64):
#     def train_step(self, generator_updates=1, discriminator_updates=1):
#     def eval_step(self):
#     def visualize(self, images, Z):
# class GradientPenalty(ModelPlugin):
# class Discriminator(ModelPlugin):
# class SimpleDiscriminator(Discriminator):
# class Generator(ModelPlugin):
# class GAN(ModelPlugin):
#         X_P = real
#         X_Q = fake
#         X_P = real
#         X_Q = fake
#         X_Q = generator(Z)
#         X_Q = self.generate(Z)


import logging
import math
import torch
import torch.nn.functional as F
from torch.autograd import Variable
from .gan import apply_penalty, f_divergence
from .modules.conv_decoders import MNISTDeConv as Generator
from .modules.convnets import MNISTConv as Discriminator
                g_loss = -((w_tilde * log_g).view(M * B)).sum(0).mean()
            else:
                g_loss = -(w_tilde * log_g).sum(0).mean()

    results = dict(g_loss=g_loss.data[0], distance=-d_loss.data[0], boundary=torch.mean(b).data[0],
                   real=torch.mean(r).data[0], fake=torch.mean(f).data[0],
                   gen_out=g_output.mean().data[0], w_tilde=w_tilde.mean().data[0],
                   real_out=real_out.mean().data[0], fake_out=fake_out.mean().data[0])

    if measure != 'w' and not use_sm:
        results.update(alpha=alpha.mean().data[0], log_alpha=log_alpha.mean().data[0],
                       beta=beta.mean().data[0], log_beta=log_beta.mean().data[0])
        results.update(ess=(1. / (w_tilde ** 2).sum(0)).mean().data[0])

    if test_mode or measure == 'w' or use_sm:
        fake_out_sm = discriminator(Variable(g_output.data.cuda(), volatile=True))
        S_th = Variable((g_output >= 0.5).float().data.cuda(), volatile=True)
        fake_out_sam = Variable(fake_out.data.cuda(), volatile=True)
        fake_out_th = discriminator(S_th)
        dist_th = -f_divergence(measure, real_out, fake_out_th)[0]
        dist_sam = -f_divergence(measure, real_out, fake_out_sam)[0]
        dist_sm = -f_divergence(measure, real_out, fake_out_sm)[0]
        results.update(distance_th=dist_th.data[0], distance_sam=dist_sam.data[0],
                       distance_sm=dist_sm.data[0])

    samples = dict(images=dict(generated=gen_out.data,
                               prob=g_output.data,
                               real=X.data))

    if penalty:

# Path: cortex/built_ins/models/gan.py
# def raise_measure_error(measure):
# def get_positive_expectation(p_samples, measure, average=True):
# def get_negative_expectation(q_samples, measure, average=True):
# def get_boundary(samples, measure):
# def get_weight(samples, measure):
# def generator_loss(q_samples, measure, loss_type=None):
#     def routine(self, inputs, penalty_type: str='contractive',
#                 penalty_amount: float=0.5):
#     def _get_gradient(inp, output):
#     def contractive_penalty(self, network, input, penalty_amount=0.5):
#     def interpolate_penalty(self, network, input, penalty_amount=0.5):
#     def build(self, discriminator_type: str='convnet', discriminator_args={}):
#     def routine(self, real, fake, measure: str='GAN'):
#     def score(self, X_P, X_Q, measure):
#     def visualize(self, real, fake, measure=None):
#     def build(self, dim_in: int=None, discriminator_args=dict(dim_h=[200, 200])):
#     def build(self, dim_z=64, generator_type: str='convnet',
#               generator_args=dict(output_nonlinearity='tanh')):
#     def routine(self, Z, measure: str=None, loss_type: str='non-saturating'):
#     def generate(self, Z):
#     def visualize(self, Z):
#     def __init__(self):
#     def build(self, noise_type='normal', dim_z=64):
#     def train_step(self, generator_updates=1, discriminator_updates=1):
#     def eval_step(self):
#     def visualize(self, images, Z):
# class GradientPenalty(ModelPlugin):
# class Discriminator(ModelPlugin):
# class SimpleDiscriminator(Discriminator):
# class Generator(ModelPlugin):
# class GAN(ModelPlugin):
#         X_P = real
#         X_Q = fake
#         X_P = real
#         X_Q = fake
#         X_Q = generator(Z)
#         X_Q = self.generate(Z)


# Path: cortex/built_ins/models/discrete_gan.py
import logging
import math
import torch
import torch.nn.functional as F
from torch.autograd import Variable
from .gan import apply_penalty, f_divergence
from .modules.conv_decoders import MNISTDeConv as Generator
from .modules.convnets import MNISTConv as Discriminator

                g_loss = -((w_tilde * log_g).view(M * B)).sum(0).mean()
            else:
                g_loss = -(w_tilde * log_g).sum(0).mean()

    results = dict(g_loss=g_loss.data[0], distance=-d_loss.data[0], boundary=torch.mean(b).data[0],
                   real=torch.mean(r).data[0], fake=torch.mean(f).data[0],
                   gen_out=g_output.mean().data[0], w_tilde=w_tilde.mean().data[0],
                   real_out=real_out.mean().data[0], fake_out=fake_out.mean().data[0])

    if measure != 'w' and not use_sm:
        results.update(alpha=alpha.mean().data[0], log_alpha=log_alpha.mean().data[0],
                       beta=beta.mean().data[0], log_beta=log_beta.mean().data[0])
        results.update(ess=(1. / (w_tilde ** 2).sum(0)).mean().data[0])

    if test_mode or measure == 'w' or use_sm:
        fake_out_sm = discriminator(Variable(g_output.data.cuda(), volatile=True))
        S_th = Variable((g_output >= 0.5).float().data.cuda(), volatile=True)
        fake_out_sam = Variable(fake_out.data.cuda(), volatile=True)
        fake_out_th = discriminator(S_th)
        dist_th = -f_divergence(measure, real_out, fake_out_th)[0]
        dist_sam = -f_divergence(measure, real_out, fake_out_sam)[0]
        dist_sm = -f_divergence(measure, real_out, fake_out_sm)[0]
        results.update(distance_th=dist_th.data[0], distance_sam=dist_sam.data[0],
                       distance_sm=dist_sm.data[0])

    samples = dict(images=dict(generated=gen_out.data,
                               prob=g_output.data,
                               real=X.data))

    if penalty:

        p_term = apply_penalty(inputs, discriminator, X, g_output,