# Path: pysaliency/models.py
# def sample_from_logdensity(log_density, count=None, rst=None):
#     if count is None:
#         real_count = 1
#     else:
#         real_count = count
# 
#     height, width = log_density.shape
#     flat_log_density = log_density.flatten(order='C')
#     samples = sample_from_logprobabilities(flat_log_density, size=real_count, rst=rst)
#     sample_xs = samples % width
#     sample_ys = samples // width
# 
#     if count is None:
#         return sample_xs[0], sample_ys[0]
#     else:
#         return np.asarray(sample_xs), np.asarray(sample_ys)
# 
# Path: pysaliency/tf_utils.py
# @slim.add_arg_scope
# def gauss_blur(inputs, sigma, windowradius=5, mode='NEAREST', scope=None,
#                outputs_collections=None):
#     with tf.name_scope(scope, 'gauss_blur', [inputs, sigma, windowradius]) as sc:
# 
#         outputs = inputs
# 
#         for axis in [0, 1]:
# 
#             outputs = gaussian_convolution_along_axis(outputs,
#                                                       axis=axis,
#                                                       sigma=sigma,
#                                                       windowradius=windowradius,
#                                                       mode=mode)
#         return outputs
# 
#         return slim.utils.collect_named_outputs(outputs_collections, sc, outputs)


from tqdm import tqdm
from scipy.ndimage import gaussian_filter
from scipy.special import logsumexp
from .models import sample_from_logdensity
from .tf_utils import gauss_blur
import numpy as np
import tensorflow as tf

    tf_train_op = opt.apply_gradients(grads_and_vars)

    return tf_train_op


def build_fixation_maps(Ns, Ys, Xs, batch_size, height, width, dtype=tf.float32):
    indices = tf.stack((Ns, Ys, Xs), axis=1)

    fixation_maps = tf.scatter_nd(indices, updates=tf.ones((tf.shape(indices)[0], ), dtype=dtype),
                                  shape=(batch_size, height, width))

    return fixation_maps


def tf_similarity(saliency_map, empirical_saliency_maps):
    normalized_empirical_saliency_maps = empirical_saliency_maps / tf.reduce_sum(empirical_saliency_maps, reduction_indices=[1, 2], keepdims=True)
    normalized_saliency_map = saliency_map / tf.reduce_sum(saliency_map)
    minimums = tf.minimum(normalized_empirical_saliency_maps, tf.expand_dims(normalized_saliency_map, 0))

    similarities = tf.reduce_sum(minimums, reduction_indices=[1, 2])

    return similarities


def build_similarity_graph(saliency_map, ns, ys, xs, batch_size, height, width, kernel_size, truncate_gaussian, dtype=tf.float32):
    window_radius = int(kernel_size * truncate_gaussian)

    fixation_maps = build_fixation_maps(ns, ys, xs, batch_size, height, width, dtype=dtype)


# Path: pysaliency/models.py
# def sample_from_logdensity(log_density, count=None, rst=None):
#     if count is None:
#         real_count = 1
#     else:
#         real_count = count
# 
#     height, width = log_density.shape
#     flat_log_density = log_density.flatten(order='C')
#     samples = sample_from_logprobabilities(flat_log_density, size=real_count, rst=rst)
#     sample_xs = samples % width
#     sample_ys = samples // width
# 
#     if count is None:
#         return sample_xs[0], sample_ys[0]
#     else:
#         return np.asarray(sample_xs), np.asarray(sample_ys)
# 
# Path: pysaliency/tf_utils.py
# @slim.add_arg_scope
# def gauss_blur(inputs, sigma, windowradius=5, mode='NEAREST', scope=None,
#                outputs_collections=None):
#     with tf.name_scope(scope, 'gauss_blur', [inputs, sigma, windowradius]) as sc:
# 
#         outputs = inputs
# 
#         for axis in [0, 1]:
# 
#             outputs = gaussian_convolution_along_axis(outputs,
#                                                       axis=axis,
#                                                       sigma=sigma,
#                                                       windowradius=windowradius,
#                                                       mode=mode)
#         return outputs
# 
#         return slim.utils.collect_named_outputs(outputs_collections, sc, outputs)


# Path: pysaliency/metric_optimization_tf.py
from tqdm import tqdm
from scipy.ndimage import gaussian_filter
from scipy.special import logsumexp
from .models import sample_from_logdensity
from .tf_utils import gauss_blur
import numpy as np
import tensorflow as tf


    tf_train_op = opt.apply_gradients(grads_and_vars)

    return tf_train_op


def build_fixation_maps(Ns, Ys, Xs, batch_size, height, width, dtype=tf.float32):
    indices = tf.stack((Ns, Ys, Xs), axis=1)

    fixation_maps = tf.scatter_nd(indices, updates=tf.ones((tf.shape(indices)[0], ), dtype=dtype),
                                  shape=(batch_size, height, width))

    return fixation_maps


def tf_similarity(saliency_map, empirical_saliency_maps):
    normalized_empirical_saliency_maps = empirical_saliency_maps / tf.reduce_sum(empirical_saliency_maps, reduction_indices=[1, 2], keepdims=True)
    normalized_saliency_map = saliency_map / tf.reduce_sum(saliency_map)
    minimums = tf.minimum(normalized_empirical_saliency_maps, tf.expand_dims(normalized_saliency_map, 0))

    similarities = tf.reduce_sum(minimums, reduction_indices=[1, 2])

    return similarities


def build_similarity_graph(saliency_map, ns, ys, xs, batch_size, height, width, kernel_size, truncate_gaussian, dtype=tf.float32):
    window_radius = int(kernel_size * truncate_gaussian)

    fixation_maps = build_fixation_maps(ns, ys, xs, batch_size, height, width, dtype=dtype)


    empirical_saliency_maps = gauss_blur(