# Path: pyglm/utils/theano_func_wrapper.py
# def seval(expr, syms, vals, defaults=None, givens=[]):
#     """
#     Evaluate the symbolic expression which depends on a set of symbolic variables,
#     given a set of variable bindings.
#     expr : Theano variable to be evaluated
#     syms : dictionary of symbolic variables
#     vals : dictionary of values to assign to the symbolic vars in syms
#            key structure should mimic that of syms
#     
#     defaults : an optional dictionary providing backup values for 
#                syms keys not found in vals.
#     """
#     # Look for a function handle corresponding to this expression with these givens
#     hash_value = lambda v: hashlib.sha1(v).hexdigest() if \
#                            isinstance(v, np.ndarray) else v
#     hashable_givens = tuple(map(lambda (k,v): (k, hash_value(v)), givens))
#     hashable_syms = tuple(map(lambda v: hash_value(v), _flatten(syms)))
#     key = (expr, hashable_syms, hashable_givens)
#     if key in _func_cache.keys():
#         #print "DBG: Found key %s in cache" % str(key)
#         f = _func_cache[key]
#         #print "DBG: Calling expr: %s" % str(expr)
#     else:
#         # Create a callable theano function and cache it
#         # print "DBG: Compiling expr: %s" % str(expr)
#         sargs = _flatten(syms)
#         if len(givens) == 0:
#             # print "DBG: Compiling expression %s with no givens" % expr
#             f = theano.function(sargs, expr,
#                                 on_unused_input='ignore')
#         else:
#             # print "DBG: Compiling expression %s with givens: %s" % (expr, str(givens))
#             f = theano.function(sargs, expr,
#                                 givens=givens,
#                                 on_unused_input='ignore')
#         _func_cache[key] = f
#     
#     # Easiest thing to do is call the function with all symbolic variables
#     args = _extract_vals(syms,vals,defaults)
#     return f(*args) 


import numpy as np
import matplotlib.pyplot as plt
from hips.plotting.colormaps import gradient_cmap
from pyglm.utils.theano_func_wrapper import seval
    def plot(self, sample, ax=None):
        """
        Plot the sample or sequence of samples
        """
        pass

class NetworkPlotProvider(PlotProvider):
    """
    Class to plot the connectivity network
    """

    def __init__(self, population):
        super(NetworkPlotProvider, self).__init__(population)

        # TODO: Check that the model has a network?
        # All models should have a network

    def plot(self, xs, ax=None, title=None, vmin=None, vmax=None, cmap=rwb_cmap):

        # Ensure sample is a list
        if not isinstance(xs, list):
            xs = [xs]

        # Get the weight matrix and adjacency matrix
        wvars = self.population.network.weights.get_variables()
        Ws = np.array([seval(self.population.network.weights.W,
                            wvars, x['net']['weights'])
                       for x in xs])

        gvars = self.population.network.graph.get_variables()

# Path: pyglm/utils/theano_func_wrapper.py
# def seval(expr, syms, vals, defaults=None, givens=[]):
#     """
#     Evaluate the symbolic expression which depends on a set of symbolic variables,
#     given a set of variable bindings.
#     expr : Theano variable to be evaluated
#     syms : dictionary of symbolic variables
#     vals : dictionary of values to assign to the symbolic vars in syms
#            key structure should mimic that of syms
#     
#     defaults : an optional dictionary providing backup values for 
#                syms keys not found in vals.
#     """
#     # Look for a function handle corresponding to this expression with these givens
#     hash_value = lambda v: hashlib.sha1(v).hexdigest() if \
#                            isinstance(v, np.ndarray) else v
#     hashable_givens = tuple(map(lambda (k,v): (k, hash_value(v)), givens))
#     hashable_syms = tuple(map(lambda v: hash_value(v), _flatten(syms)))
#     key = (expr, hashable_syms, hashable_givens)
#     if key in _func_cache.keys():
#         #print "DBG: Found key %s in cache" % str(key)
#         f = _func_cache[key]
#         #print "DBG: Calling expr: %s" % str(expr)
#     else:
#         # Create a callable theano function and cache it
#         # print "DBG: Compiling expr: %s" % str(expr)
#         sargs = _flatten(syms)
#         if len(givens) == 0:
#             # print "DBG: Compiling expression %s with no givens" % expr
#             f = theano.function(sargs, expr,
#                                 on_unused_input='ignore')
#         else:
#             # print "DBG: Compiling expression %s with givens: %s" % (expr, str(givens))
#             f = theano.function(sargs, expr,
#                                 givens=givens,
#                                 on_unused_input='ignore')
#         _func_cache[key] = f
#     
#     # Easiest thing to do is call the function with all symbolic variables
#     args = _extract_vals(syms,vals,defaults)
#     return f(*args) 


# Path: pyglm/plotting/plotting.py
import numpy as np
import matplotlib.pyplot as plt
from hips.plotting.colormaps import gradient_cmap
from pyglm.utils.theano_func_wrapper import seval

    def plot(self, sample, ax=None):
        """
        Plot the sample or sequence of samples
        """
        pass

class NetworkPlotProvider(PlotProvider):
    """
    Class to plot the connectivity network
    """

    def __init__(self, population):
        super(NetworkPlotProvider, self).__init__(population)

        # TODO: Check that the model has a network?
        # All models should have a network

    def plot(self, xs, ax=None, title=None, vmin=None, vmax=None, cmap=rwb_cmap):

        # Ensure sample is a list
        if not isinstance(xs, list):
            xs = [xs]

        # Get the weight matrix and adjacency matrix
        wvars = self.population.network.weights.get_variables()
        Ws = np.array([seval(self.population.network.weights.W,
                            wvars, x['net']['weights'])
                       for x in xs])

        gvars = self.population.network.graph.get_variables()

        As = np.array([seval(self.population.network.graph.A,