Example #1
0
 def KL_distance(theta1, theta2, N):
     D = theta1.shape[0]
     p1 = transforms.compute_p(theta1)
     eta1 = transforms.compute_eta(p1)
     psi1 = transforms.compute_psi(theta1)
     p2 = transforms.compute_p(theta2)
     eta2 = transforms.compute_eta(p2)
     psi2 = transforms.compute_psi(theta2)
     S1 = energies.compute_entropy(theta1.reshape(1, D), eta1.reshape(1, D),
                                   psi1, 2)
     S2 = energies.compute_entropy(theta2.reshape(1, D), eta2.reshape(1, D),
                                   psi2, 2)
     KL1 = -S1 + psi2 - eta1.dot(theta2)
     KL2 = -S2 + psi1 - eta2.dot(theta1)
     KL = (KL1 + KL2) / 2
     return KL
Example #2
0
def gradient_1sample(n_samples, emd):
    """
    Computes one sample of the expectation inside the equation for the
    gradient of the q function with respect to the network parameters of
    the Ising models of the main fetures.
    :param container .EMData emd:
        All data pertaining to the EM algorithm.
    """
    # Take 1 sample of theta for all time steps
    generated_theta = sample_theta(emd)
    # Compute 1 sample
    sample_value = 0
    for t in range(emd.T):
        theta_mixed = transforms.compute_mixed_theta(generated_theta[t,:], \
                                                     emd.J)
        if emd.exact:
            p = transforms.compute_p(theta_mixed)
            eta_tilde = transforms.compute_eta(p)
        else:
            eta_tilde = bethe_approximation.compute_eta_hybrid(theta_mixed, emd.N)
        a = emd.F_tilde[t,:] - eta_tilde
        # Summation for all time bins
        sample_value += emd.R * numpy.dot(a[:,numpy.newaxis], \
                                          generated_theta[t,numpy.newaxis,:])

    return sample_value
Example #3
0
def newton_raphson(emd, t):
    """
    Computes the MAP estimate of the natural parameters at some timestep, given
    the observed spike patterns at that timestep and the one-step-prediction
    mean and covariance for the same timestep.

    :param container.EMData emd:
        All data pertaining to the EM algorithm.
    :param int t:
        Timestep for which to compute the maximum posterior probability.

    :returns:
        Tuple containing the mean and covariance of the posterior probability
        density, each as a numpy.ndarray.
    """
    # Extract observed patterns and one-step predictions for time t
    y_t = emd.y[t,:]
    theta_o = emd.theta_o[t,:]
    sigma_o = emd.sigma_o[t,:,:]
    R = emd.R
    # Initialise theta_max to the smooth theta value of the previous iteration
    theta_max = emd.theta_s[t,:]
    # Use non-normalised posterior prob. as loop guard
    lpp = -numpy.inf
    lpc = probability.log_likelihood(y_t, theta_max, R) +\
          probability.log_multivariate_normal(theta_max, theta_o, sigma_o)
    iterations = 0
    # Iterate the gradient ascent algorithm until convergence or failure
    while lpc - lpp > GA_CONVERGENCE:
        # Compute the eta of the current theta values
        p = transforms.compute_p(theta_max)
        eta = transforms.compute_eta(p)
        # Compute the inverse of one-step covariance
        sigma_o_i = numpy.linalg.inv(sigma_o)
        # Compute the first derivative of the posterior prob. w.r.t. theta_max
        dllk = R * (y_t - eta)
        dlpr = -numpy.dot(sigma_o_i, theta_max - theta_o)
        dlpo = dllk + dlpr
        # Compute the second derivative of the posterior prob. w.r.t. theta_max
        ddlpo = -R * transforms.compute_fisher_info(p, eta) - sigma_o_i
        # Dot the results to climb the gradient, and accumulate the result
        ddlpo_i = numpy.linalg.inv(ddlpo)
        theta_max -= numpy.dot(ddlpo_i, dlpo)
        # Update previous and current posterior prob.
        lpp = lpc
        lpc = probability.log_likelihood(y_t, theta_max, R) +\
              probability.log_multivariate_normal(theta_max, theta_o, sigma_o)
        # Count iterations
        iterations += 1
        # Check for check for overrun
        if iterations == MAX_GA_ITERATIONS:
            raise Exception('The maximum-a-posterior gradient-ascent '+\
                'algorithm did not converge before reaching the maximum '+\
                'number iterations.')

    return theta_max, -ddlpo_i
def compute_eta(theta, N, O, R=1000):
    """ Computes eta from given theta.

    :param numpy.ndarray theta:
        (t, d) array with natural parameters
    :param int N:
        number of cells
    :param int O:
        order of model
    :param int R:
        trials that should be sampled to estimate eta
    :return numpy.ndarray, list:
        (t, d) array with natural parameters parameters and a list with indices of bins, for which has been sampled

    Details: Tries to estimate eta by solving the forward problem from TAP. However, if it fails we fall back to
    sampling. For networks with less then 15 neurons exact solution is computed and for first order analytical solution
    is used.
    """
    T, D = theta.shape
    eta = numpy.empty(theta.shape)
    bins_to_sample = []
    if O == 1:
        eta = compute_ind_eta(theta[:, :N])
    elif O == 2:
        # if few cells compute exact rates
        if N > 15:
            for i in range(T):
                # try to solve forward problem
                try:
                    eta[i] = mean_field.forward_problem(theta[i], N, 'TAP')
                # if it fails remember bin for sampling
                except Exception:
                    bins_to_sample.append(i)
            if len(bins_to_sample) != 0:
                theta_to_sample = numpy.empty([len(bins_to_sample), D])
                for idx, bin2sampl in enumerate(bins_to_sample):
                    theta_to_sample[idx] = theta[bin2sampl]
                spikes = synthesis.generate_spikes_gibbs_parallel(
                    theta_to_sample, N, O, R, sample_steps=100)
                eta_from_sample = transforms.compute_y(spikes, O, 1)
                for idx, bin2sampl in enumerate(bins_to_sample):
                    eta[bin2sampl] = eta_from_sample[idx]

        # if large ensemble approximate
        else:
            transforms.initialise(N, O)
            for i in range(T):
                p = transforms.compute_p(theta[i])
                eta[i] = transforms.compute_eta(p)

    return eta, bins_to_sample
Example #5
0
def compute_eta(theta, N, O, R=1000):
    """ Computes eta from given theta.

    :param numpy.ndarray theta:
        (t, d) array with natural parameters
    :param int N:
        number of cells
    :param int O:
        order of model
    :param int R:
        trials that should be sampled to estimate eta
    :return numpy.ndarray, list:
        (t, d) array with natural parameters parameters and a list with indices of bins, for which has been sampled

    Details: Tries to estimate eta by solving the forward problem from TAP. However, if it fails we fall back to
    sampling. For networks with less then 15 neurons exact solution is computed and for first order analytical solution
    is used.
    """
    T, D = theta.shape
    eta = numpy.empty(theta.shape)
    bins_to_sample = []
    if O == 1:
        eta = compute_ind_eta(theta[:,:N])
    elif O == 2:
        # if few cells compute exact rates
        if N > 15:
            for i in range(T):
                # try to solve forward problem
                try:
                    eta[i] = mean_field.forward_problem(theta[i], N, 'TAP')
                # if it fails remember bin for sampling
                except Exception:
                    bins_to_sample.append(i)
            if len(bins_to_sample) != 0:
                theta_to_sample = numpy.empty([len(bins_to_sample), D])
                for idx, bin2sampl in enumerate(bins_to_sample):
                    theta_to_sample[idx] = theta[bin2sampl]
                spikes = synthesis.generate_spikes_gibbs_parallel(theta_to_sample, N, O, R, sample_steps=100)
                eta_from_sample = transforms.compute_y(spikes, O, 1)
                for idx, bin2sampl in enumerate(bins_to_sample):
                    eta[bin2sampl] = eta_from_sample[idx]

        # if large ensemble approximate
        else:
            transforms.initialise(N, O)
            for i in range(T):
                p = transforms.compute_p(theta[i])
                eta[i] = transforms.compute_eta(p)

    return eta, bins_to_sample
Example #6
0
def newton_raphson(y_t, X_t, R, theta_0, theta_o, sigma_o, sigma_o_i, *args):
    """
    TODO update comments to elaborate on how this method differs from the others

    :param container.EMData emd:
        All data pertaining to the EM algorithm.
    :param int t:
        Timestep for which to compute the maximum posterior probability.

    :returns:
        Tuple containing the mean and covariance of the posterior probability
        density, each as a numpy.ndarray.
    """
    # Initialise the loop guards
    max_dlpo = numpy.inf
    iterations = 0
    # Initialise theta_max to the smooth theta value of the previous iteration
    theta_max = theta_0
    # Iterate the gradient ascent algorithm until convergence or failure
    while max_dlpo > GA_CONVERGENCE:
        # Compute the eta of the current theta values
        p = transforms.compute_p(theta_max)
        eta = transforms.compute_eta(p)
        # Compute the first derivative of the posterior prob. w.r.t. theta_max
        dllk = R * (y_t - eta)
        dlpr = -numpy.dot(sigma_o_i, theta_max - theta_o)
        dlpo = dllk + dlpr
        # Compute the second derivative of the posterior prob. w.r.t. theta_max
        ddlpo = -R * transforms.compute_fisher_info(p, eta) - sigma_o_i
        # Dot the results to climb the gradient, and accumulate the
        # Small regularization added to avoid singular matrices
        ddlpo_i = numpy.linalg.inv(ddlpo + numpy.finfo(float).eps*\
                                   numpy.identity(eta.shape[0]))
        # Update Theta
        theta_max -= numpy.dot(ddlpo_i, dlpo)
        # Update the look guard
        max_dlpo = numpy.amax(numpy.absolute(dlpo)) / R
        # Count iterations
        iterations += 1
        # Check for check for overrun
        if iterations == MAX_GA_ITERATIONS:
            raise Exception('The maximum-a-posterior gradient-ascent '+\
                'algorithm did not converge before reaching the maximum '+\
                'number iterations.')

    return theta_max, -ddlpo_i
Example #7
0
def newton_raphson(y_t, X_t, R, theta_0, theta_o, sigma_o, sigma_o_i, *args):
    """
    TODO update comments to elaborate on how this method differs from the others

    :param container.EMData emd:
        All data pertaining to the EM algorithm.
    :param int t:
        Timestep for which to compute the maximum posterior probability.

    :returns:
        Tuple containing the mean and covariance of the posterior probability
        density, each as a numpy.ndarray.
    """
    # Initialise the loop guards
    max_dlpo = numpy.inf
    iterations = 0
    # Initialise theta_max to the smooth theta value of the previous iteration
    theta_max = theta_0
    # Iterate the gradient ascent algorithm until convergence or failure
    while max_dlpo > GA_CONVERGENCE:
        # Compute the eta of the current theta values
        p = transforms.compute_p(theta_max)
        eta = transforms.compute_eta(p)
        # Compute the first derivative of the posterior prob. w.r.t. theta_max
        dllk = R * (y_t - eta)
        dlpr = -numpy.dot(sigma_o_i, theta_max - theta_o)
        dlpo = dllk + dlpr
        # Compute the second derivative of the posterior prob. w.r.t. theta_max
        ddlpo = -R * transforms.compute_fisher_info(p, eta) - sigma_o_i
        # Dot the results to climb the gradient, and accumulate the
        # Small regularization added to avoid singular matrices
        ddlpo_i = numpy.linalg.inv(ddlpo + numpy.finfo(float).eps*\
                                   numpy.identity(eta.shape[0]))
        # Update Theta
        theta_max -= numpy.dot(ddlpo_i, dlpo)
        # Update the look guard
        max_dlpo = numpy.amax(numpy.absolute(dlpo)) / R
        # Count iterations
        iterations += 1
        # Check for check for overrun
        if iterations == MAX_GA_ITERATIONS:
            raise Exception('The maximum-a-posterior gradient-ascent '+\
                'algorithm did not converge before reaching the maximum '+\
                'number iterations.')

    return theta_max, -ddlpo_i
Example #8
0
 def run_ssasc(self, theta, N, O):
     # Initialise the library for computing pattern probabilities
     transforms.initialise(N, O)
     # Compute probability from theta values
     p = numpy.zeros((self.T, 2**N))
     for i in xrange(self.T):
         p[i,:] = transforms.compute_p(theta[i,:])
     # Generate spikes according to those probabilities
     spikes = synthesis.generate_spikes(p, self.R, seed=self.spike_seed)
     # Run the algorithm!
     emd = __init__.run(spikes, O)
     # Compute the KL divergence between real and estimated parameters
     kld = klic(theta, emd.theta_s, emd.N)
     # Check that KL divergence is OK
     if numpy.any(kld[50:-50] > .01):
         self.plot(theta, emd.theta_s, emd.sigma_s, emd.y, kld, emd.N, emd.T,
             emd.D)
     self.assertFalse(numpy.any(kld[50:-50] > .01))
Example #9
0
def conjugate_gradient(y_t, X_t, R, theta_0, theta_o, sigma_o, sigma_o_i, *args):
    """ Fits with `Nonlinear Conjugate Gradient Method
    <https://en.wikipedia.org/wiki/Nonlinear_conjugate_gradient_method>`_.

    :param container.EMData emd:
        All data pertaining to the EM algorithm.
    :param int t:
        Timestep for which to compute the maximum posterior probability.

    :returns:
        Tuple containing the mean and covariance of the posterior probability
        density, each as a numpy.ndarray.

    @author: Christian Donner
    """

    # Initialize theta with previous smoothed theta
    theta_max = theta_0
    # Get p and eta values for current theta
    p = transforms.compute_p(theta_max)
    eta = transforms.compute_eta(p)
    # Compute derivative of posterior
    dllk = R*(y_t - eta)
    dlpr = -numpy.dot(sigma_o_i, theta_max - theta_o)
    dlpo = dllk + dlpr
    # Initialize stopping criterion variables
    max_dlpo = 1.
    iterations = 0
    # Get theta gradient
    d_th = dlpo
    # Set initial search direction
    s = dlpo
    # Compute line search
    theta_max, dlpo, p, eta = line_search(theta_max, y_t, R, p, s, dlpo,
                                          theta_o, sigma_o_i)

    # Iterate until convergence or failure
    while max_dlpo > GA_CONVERGENCE:

        # Set current theta gradient to previous
        d_th_prev = d_th
        # The new theta gradient
        d_th = dlpo
        # Calculate beta
        beta = compute_beta(d_th, d_th_prev)
        # New search direction
        s = d_th + beta * s
        # Line search
        theta_max, dlpo, p, eta = line_search(theta_max, y_t, R, p, s, dlpo,
                                              theta_o, sigma_o_i)
        # Get maximal entry of log posterior grad divided by number of trials
        max_dlpo = numpy.amax(numpy.absolute(dlpo)) / R
        # Count iterations
        iterations += 1
        if iterations == MAX_GA_ITERATIONS:
            raise Exception('The maximum-a-posterior conjugate-gradient '+\
                'algorithm did not converge before reaching the maximum '+\
                'number iterations.')

    # Compute final covariance matrix
    ddllk = - R*transforms.compute_fisher_info(p, eta)
    ddlpo = ddllk - sigma_o_i
    ddlpo_i = numpy.linalg.inv(ddlpo)

    return theta_max, -ddlpo_i
Example #10
0
def generate_data_figure1(data_path = '../Data/'):
    N, O, R, T = 15, 2, 200, 500
    mu = numpy.zeros(T)
    x = numpy.arange(1, 401)
    mu[100:] = 1. * (3. / (2. * numpy.pi * (x/400.*3.) ** 3)) ** .5 * \
               numpy.exp(-3. * ((x/400.*3.) - 1.) ** 2 / (2. * (x/400.*3.)))
    theta1 = synthesis.generate_thetas(N, O, T, mu1=-2.)
    theta2 = synthesis.generate_thetas(N, O, T, mu1=-2.)
    theta1[:, :N] += mu[:, numpy.newaxis]
    theta2[:, :N] += mu[:, numpy.newaxis]
    D = transforms.compute_D(N * 2, O)
    theta_all = numpy.empty([T, D])
    theta_all[:, :N] = theta1[:, :N]
    theta_all[:, N:2 * N] = theta2[:, :N]
    triu_idx = numpy.triu_indices(N, k=1)
    triu_idx_all = numpy.triu_indices(2 * N, k=1)
    for t in range(T):
        theta_ij = numpy.zeros([2 * N, 2 * N])
        theta_ij[triu_idx] = theta1[t, N:]
        theta_ij[triu_idx[0] + N, triu_idx[1] + N] = theta2[t, N:]
        theta_all[t, 2 * N:] = theta_ij[triu_idx_all]

    psi1 = numpy.empty([T, 3])
    psi2 = numpy.empty([T, 3])
    eta1 = numpy.empty(theta1.shape)
    eta2 = numpy.empty(theta2.shape)
    alpha = [.999,1.,1.001]
    transforms.initialise(N, O)
    for i in range(T):
        for j, a in enumerate(alpha):
            psi1[i, j] = transforms.compute_psi(a * theta1[i])
        p = transforms.compute_p(theta1[i])
        eta1[i] = transforms.compute_eta(p)
        for j, a in enumerate(alpha):
            psi2[i, j] = transforms.compute_psi(a * theta2[i])
        p = transforms.compute_p(theta2[i])
        eta2[i] = transforms.compute_eta(p)

    psi_all = psi1 + psi2
    S1 = -numpy.sum(eta1 * theta1, axis=1) + psi1[:, 1]
    S1 /= numpy.log(2)
    S2 = -numpy.sum(eta2 * theta2, axis=1) + psi2[:, 1]
    S2 /= numpy.log(2)
    S_all = S1 + S2

    C1 = (psi1[:, 0] - 2. * psi1[:, 1] + psi1[:, 2]) / .001 ** 2
    C1 /= numpy.log(2)
    C2 = (psi2[:, 0] - 2. * psi2[:, 1] + psi2[:, 2]) / .001 ** 2
    C2 /= numpy.log(2)

    C_all = C1 + C2

    spikes = synthesis.generate_spikes_gibbs_parallel(theta_all, 2 * N, O, R,
                                                      sample_steps=10,
                                                      num_proc=4)

    print 'Model and Data generated'

    emd = __init__.run(spikes, O, map_function='cg', param_est='pseudo',
                       param_est_eta='bethe_hybrid', lmbda1=100, lmbda2=200)

    f = h5py.File(data_path + 'figure1data.h5', 'w')
    g_data = f.create_group('data')
    g_data.create_dataset('theta_all', data=theta_all)
    g_data.create_dataset('psi_all', data=psi_all)
    g_data.create_dataset('S_all', data=S_all)
    g_data.create_dataset('C_all', data=C_all)
    g_data.create_dataset('spikes', data=spikes)
    g_data.create_dataset('theta1', data=theta1)
    g_data.create_dataset('theta2', data=theta2)
    g_data.create_dataset('psi1', data=psi1)
    g_data.create_dataset('S1', data=S1)
    g_data.create_dataset('C1', data=C1)
    g_data.create_dataset('psi2', data=psi2)
    g_data.create_dataset('S2', data=S2)
    g_data.create_dataset('C2', data=C2)
    g_fit = f.create_group('fit')
    g_fit.create_dataset('theta_s', data=emd.theta_s)
    g_fit.create_dataset('sigma_s', data=emd.sigma_s)
    g_fit.create_dataset('Q', data=emd.Q)
    f.close()

    print 'Fit and saved'

    f = h5py.File(data_path + 'figure1data.h5', 'r+')
    g_fit = f['fit']
    theta = g_fit['theta_s'].value
    sigma = g_fit['sigma_s'].value

    X = numpy.random.randn(theta.shape[0], theta.shape[1], 100)
    theta_sampled = \
        theta[:, :, numpy.newaxis] + X * numpy.sqrt(sigma)[:, :, numpy.newaxis]

    T = range(theta.shape[0])
    eta_sampled = numpy.empty([theta.shape[0], theta.shape[1], 100])
    psi_sampled = numpy.empty([theta.shape[0], 100, 3])

    func = partial(get_sampled_eta_psi, theta_sampled=theta_sampled, N=2*N)
    pool = multiprocessing.Pool(10)
    results = pool.map(func, T)

    for eta, psi, i in results:
        eta_sampled[i] = eta
        psi_sampled[i] = psi
    S_sampled = \
        -(numpy.sum(eta_sampled*theta_sampled, axis=1) - psi_sampled[:, :, 1])
    S_sampled /= numpy.log(2)
    C_sampled = \
        (psi_sampled[:, :, 0] - 2.*psi_sampled[:, :, 1] +
         psi_sampled[:, :, 2])/.001**2
    C_sampled /= numpy.log(2)
    g_sampled = f.create_group('sampled_results')
    g_sampled.create_dataset('theta_sampled', data=theta_sampled)
    g_sampled.create_dataset('eta_sampled', data=eta_sampled)
    g_sampled.create_dataset('psi_sampled', data=psi_sampled)
    g_sampled.create_dataset('S_sampled', data=S_sampled)
    g_sampled.create_dataset('C_sampled', data=C_sampled)
    f.close()

    print 'Done'
Example #11
0
def conjugate_gradient(y_t, X_t, R, theta_0, theta_o, sigma_o, sigma_o_i,
                       *args):
    """ Fits with `Nonlinear Conjugate Gradient Method
    <https://en.wikipedia.org/wiki/Nonlinear_conjugate_gradient_method>`_.

    :param container.EMData emd:
        All data pertaining to the EM algorithm.
    :param int t:
        Timestep for which to compute the maximum posterior probability.

    :returns:
        Tuple containing the mean and covariance of the posterior probability
        density, each as a numpy.ndarray.

    @author: Christian Donner
    """

    # Initialize theta with previous smoothed theta
    theta_max = theta_0
    # Get p and eta values for current theta
    p = transforms.compute_p(theta_max)
    eta = transforms.compute_eta(p)
    # Compute derivative of posterior
    dllk = R * (y_t - eta)
    dlpr = -numpy.dot(sigma_o_i, theta_max - theta_o)
    dlpo = dllk + dlpr
    # Initialize stopping criterion variables
    max_dlpo = 1.
    iterations = 0
    # Get theta gradient
    d_th = dlpo
    # Set initial search direction
    s = dlpo
    # Compute line search
    theta_max, dlpo, p, eta = line_search(theta_max, y_t, R, p, s, dlpo,
                                          theta_o, sigma_o_i)

    # Iterate until convergence or failure
    while max_dlpo > GA_CONVERGENCE:

        # Set current theta gradient to previous
        d_th_prev = d_th
        # The new theta gradient
        d_th = dlpo
        # Calculate beta
        beta = compute_beta(d_th, d_th_prev)
        # New search direction
        s = d_th + beta * s
        # Line search
        theta_max, dlpo, p, eta = line_search(theta_max, y_t, R, p, s, dlpo,
                                              theta_o, sigma_o_i)
        # Get maximal entry of log posterior grad divided by number of trials
        max_dlpo = numpy.amax(numpy.absolute(dlpo)) / R
        # Count iterations
        iterations += 1
        if iterations == MAX_GA_ITERATIONS:
            raise Exception('The maximum-a-posterior conjugate-gradient '+\
                'algorithm did not converge before reaching the maximum '+\
                'number iterations.')

    # Compute final covariance matrix
    ddllk = -R * transforms.compute_fisher_info(p, eta)
    ddlpo = ddllk - sigma_o_i
    ddlpo_i = numpy.linalg.inv(ddlpo)

    return theta_max, -ddlpo_i
Example #12
0
# Global module
import numpy
# Local modules
import synthesis
import transforms

# Create underlying time-varying theta parameters as Gaussian processes
# Create mean vector
theta = synthesis.generate_thetas(N, O, T)

# Initialise the transforms library in preparation for computing P
transforms.initialise(N, O)
# Compute P for each time step
p = numpy.zeros((T, 2**N))
for i in range(T):
    p[i,:] = transforms.compute_p(theta[i,:])
# Generate spikes!
spikes = synthesis.generate_spikes(p, R, seed=1)


# ----- ALGORITHM EXECUTION -----
# Global module
import numpy
# Local module
import __init__ # From outside this folder, this would be 'import ssll'

# Run the algorithm!
emd = __init__.run(spikes, O, map_function='nr', lmbda1=200, lmbda2=200,)


# ----- PLOTTING -----
Example #13
0
def plot_figure1(data_path='../Data/', plot_path='../Plots/'):

    N, O = 30, 2
    f = h5py.File(data_path + 'figure1data.h5', 'r')
    # Figure A
    fig = pyplot.figure(figsize=(30, 20))

    ax = fig.add_axes([0.07, 0.68, .4, .4])
    ax.imshow(-f['data']['spikes'][:, 0, :].T, cmap='gray', aspect=5,
              interpolation='nearest')
    ax.set_xticks([])
    ax.set_yticks([])
    ax = fig.add_axes([.06, 0.65, .4, .4])
    ax.imshow(-f['data']['spikes'][:, 1, :].T, cmap='gray', aspect=5,
              interpolation='nearest')
    ax.set_xticks([])
    ax.set_yticks([])
    ax = fig.add_axes([.05, 0.62, .4, .4])
    ax.imshow(-f['data']['spikes'][:, 2, :].T, cmap='gray', aspect=5,
              interpolation='nearest')
    ax.set_xticks([])
    ax.set_yticks([])
    ax.set_xlabel('Time [AU]', fontsize=26)
    ax.set_ylabel('Neuron ID', fontsize=26)

    ax = fig.add_axes([.05, 0.5, .4, .2])
    ax.set_frame_on(False)
    ax.plot(numpy.mean(numpy.mean(f['data']['spikes'][:, :, :], axis=1),
                       axis=1), linewidth=4, color='k')
    ymin, ymax = ax.get_yaxis().get_view_interval()
    xmin, xmax = ax.get_xaxis().get_view_interval()
    ax.add_artist(pyplot.Line2D((xmin, xmin), (ymin, ymax), color='black',
                                linewidth=2))
    ax.add_artist(pyplot.Line2D((xmin, xmax), (ymin, ymin), color='black',
                                linewidth=3))
    ax.yaxis.set_ticks_position('left')
    ax.xaxis.set_ticks_position('bottom')
    ax.set_yticks([.1, .2, .3])
    ax.set_xticks([50, 150, 300])
    ax.set_ylabel('Data $p_{\\mathrm{spike}}$', fontsize=26)
    ax.set_xlabel('Time [AU]', fontsize=26)
    ax.tick_params(axis='both', which='major', labelsize=20)

    theta = f['fit']['theta_s'].value
    sigma_s = f['fit']['sigma_s'].value
    bounds = numpy.empty([theta.shape[0], theta.shape[1] - N, 2])
    bounds[:, :, 0] = theta[:, N:] - 2.58 * numpy.sqrt(sigma_s[:, N:])
    bounds[:, :, 1] = theta[:, N:] + 2.58 * numpy.sqrt(sigma_s[:, N:])
    # Figure B (Networks)
    graph_ax = [fig.add_axes([.52, 0.78, .15, .2]),
                fig.add_axes([.67, 0.78, .15, .2]),
                fig.add_axes([.82, 0.78, .15, .2])]
    T = [50, 150, 300]
    for i, t in enumerate(T):
        idx = numpy.where(numpy.logical_or(bounds[t, :, 0] > 0, bounds[t, :, 1]
                                           < 0))[0]
        conn_idx_all = numpy.arange(0, N * (N - 1) / 2)
        conn_idx = conn_idx_all[idx]
        all_conns = itertools.combinations(range(N), 2)
        conns = numpy.array(list(all_conns))[conn_idx]
        G1 = nx.Graph()
        G1.add_nodes_from(range(N))
        # conns = itertools.combinations(range(30),2)
        G1.add_edges_from(conns)
        pos1 = nx.circular_layout(G1)
        net_nodes = \
            nx.draw_networkx_nodes(G1, pos1, ax=graph_ax[i],
                                   node_color=theta[t, :N],
                                   cmap=pyplot.get_cmap('hot'), vmin=-3,
                                   vmax=-1.)
        e1 = nx.draw_networkx_edges(G1, pos1, ax=graph_ax[i],
                                    edge_color=theta[t, conn_idx].tolist(),
                                    edge_cmap=pyplot.get_cmap('seismic'),
                                    edge_vmin=-.7, edge_vmax=.7, width=2)
        graph_ax[i].axis('off')
        x0, x1 = graph_ax[i].get_xlim()
        y0, y1 = graph_ax[i].get_ylim()
        graph_ax[i].set_aspect(abs(x1 - x0) / abs(y1 - y0))
        graph_ax[i].set_title('t=%d' % t, fontsize=24)
    cbar_ax = fig.add_axes([0.62, 0.79, 0.1, 0.01])
    cbar_ax.tick_params(axis='both', which='major', labelsize=20)
    cbar = fig.colorbar(net_nodes, cax=cbar_ax, orientation='horizontal')
    cbar.set_ticks([-3, -2, -1])
    cbar_ax.set_title('$\\theta_{i}$', fontsize=22)
    cbar_ax = fig.add_axes([0.77, 0.79, 0.1, 0.01])
    cbar = fig.colorbar(e1, cax=cbar_ax, orientation='horizontal')
    cbar.set_ticks([-.5, 0., .5])
    cbar_ax.set_title('$\\theta_{ij}$', fontsize=22)
    cbar_ax.tick_params(axis='both', which='major', labelsize=20)

    # Figure B (Thetas)
    theta = f['data']['theta_all'][:, [165, 170, 182]]
    theta_fit = f['fit']['theta_s'][:, [165, 170, 182]]
    sigma_fit = f['fit']['sigma_s'][:, [165, 170, 182]]
    ax1 = fig.add_axes([.55, 0.68, .4, .1])
    ax1.set_frame_on(False)
    ax1.fill_between(range(0, 500), theta_fit[:, 0] - 2.58 *
                     numpy.sqrt(sigma_fit[:, 0]), theta_fit[:, 0] + 2.58 *
                     numpy.sqrt(sigma_fit[:, 0]), color=[.4, .4, .4])
    ax1.plot(range(500), theta[:, 0], linewidth=4, color='k')
    ax1.set_yticks([-1, 0, 1])
    ax1.set_ylim([-1.1, 1.1])
    ymin, ymax = ax1.get_yaxis().get_view_interval()
    xmin, xmax = ax1.get_xaxis().get_view_interval()
    ax1.add_artist(pyplot.Line2D((xmin, xmin), (ymin, ymax), color='black',
                                 linewidth=2))
    ax1.set_xticks([])
    ax1.yaxis.set_ticks_position('left')
    ax1.xaxis.set_ticks_position('bottom')
    ax1.tick_params(axis='both', which='major', labelsize=20)
    ax1 = fig.add_axes([.55, 0.57, .4, .1])
    ax1.set_frame_on(False)
    ax1.fill_between(range(0, 500), theta_fit[:, 1] - 2.58 *
                     numpy.sqrt(sigma_fit[:, 1]),
                     theta_fit[:, 1] + 2.58 * numpy.sqrt(sigma_fit[:, 1]),
                     color=[.5, .5, .5])
    ax1.plot(range(500), theta[:, 1], linewidth=4, color='k')
    ax1.set_yticks([-1, 0, 1])
    ax1.set_ylim([-1.1, 1.5])
    ymin, ymax = ax1.get_yaxis().get_view_interval()
    xmin, xmax = ax1.get_xaxis().get_view_interval()
    ax1.add_artist(pyplot.Line2D((xmin, xmin), (ymin, ymax), color='black',
                                 linewidth=2))
    ax1.set_xticks([])
    ax1.yaxis.set_ticks_position('left')
    ax1.xaxis.set_ticks_position('bottom')
    ax1.set_ylabel('$\\theta_{ij}$', fontsize=26)
    ax1.tick_params(axis='both', which='major', labelsize=20)
    ax1 = fig.add_axes([.55, 0.46, .4, .1])
    ax1.set_frame_on(False)
    ax1.fill_between(range(0, 500),
                     theta_fit[:, 2] - 2.58 * numpy.sqrt(sigma_fit[:, 2]),
                     theta_fit[:, 2] + 2.58 * numpy.sqrt(sigma_fit[:, 2]),
                     color=[.6, .6, .6])
    ax1.plot(range(500), theta[:, 2], linewidth=4, color='k')
    ax1.set_ylim([-1.1, 1.1])
    ymin, ymax = ax1.get_yaxis().get_view_interval()
    xmin, xmax = ax1.get_xaxis().get_view_interval()
    ax1.add_artist(pyplot.Line2D((xmin, xmin), (ymin, ymax), color='black',
                                 linewidth=2))
    ax1.add_artist(pyplot.Line2D((xmin, xmax), (ymin, ymin), color='black',
                                 linewidth=3))
    ax1.set_xticks([50, 150, 300])
    ax1.yaxis.set_ticks_position('left')
    ax1.xaxis.set_ticks_position('bottom')
    ax1.set_xlabel('Time [AU]', fontsize=26)
    ax1.set_yticks([-1, 0, 1])
    ax1.tick_params(axis='both', which='major', labelsize=20)

    # Figure C
    psi_color = numpy.array([51, 153., 255]) / 256.
    eta_color = numpy.array([0, 204., 102]) / 256.
    S_color = numpy.array([255, 162, 0]) / 256.
    C_color = numpy.array([204, 60, 60]) / 256.
    psi_quantiles = mquantiles(f['sampled_results']['psi_sampled'][:, :, 1],
                               prob=[.01, .99], axis=1)
    psi_true = f['data']['psi_all'].value
    eta_quantiles = mquantiles(numpy.mean(
        f['sampled_results']['eta_sampled'][:, :N, :], axis=1), prob=[.01, .99],
                               axis=1)
    C_quantiles = mquantiles(f['sampled_results']['C_sampled'][:, :],
                             prob=[.01, .99], axis=1)
    C_true = f['data']['C_all']
    S_quantiles = mquantiles(f['sampled_results']['S_sampled'][:, :],
                             prob=[.01, .99], axis=1)
    S_true = f['data']['S_all']
    eta1 = numpy.empty(f['data']['theta1'].shape)
    eta2 = numpy.empty(f['data']['theta2'].shape)
    T = eta1.shape[0]
    N1, N2 = 15, 15
    transforms.initialise(N1, O)
    for i in range(T):
        p = transforms.compute_p(f['data']['theta1'][i])
        eta1[i] = transforms.compute_eta(p)
        p = transforms.compute_p(f['data']['theta2'][i])
        eta2[i] = transforms.compute_eta(p)

    ax1 = fig.add_axes([.08, 0.23, .4, .15])
    ax1.set_frame_on(False)
    ax1.fill_between(range(0, 500), eta_quantiles[:, 0], eta_quantiles[:, 1],
                     color=eta_color)
    eta_true = 1. / 2. * (numpy.mean(eta1[:, :N1], axis=1) +
                          numpy.mean(eta2[:, :N2], axis=1))
    ax1.fill_between(range(0, 500), eta_quantiles[:, 0], eta_quantiles[:, 1],
                     color=eta_color)
    ax1.plot(range(500), eta_true, linewidth=4, color=eta_color * .8)

    ax1.set_yticks([.1, .2, .3])
    ax1.set_ylim([.09, .35])
    ymin, ymax = ax1.get_yaxis().get_view_interval()
    xmin, xmax = ax1.get_xaxis().get_view_interval()
    ax1.add_artist(pyplot.Line2D((xmin, xmin), (ymin, ymax), color='black',
                                 linewidth=2))
    ax1.add_artist(pyplot.Line2D((xmin, xmax), (ymin, ymin), color='black',
                                 linewidth=3))
    ax1.set_xticks([50, 150, 300])
    ax1.yaxis.set_ticks_position('left')
    ax1.xaxis.set_ticks_position('bottom')
    ax1.set_ylabel('$p_{\\mathrm{spike}}$', fontsize=26)
    ax1.tick_params(axis='both', which='major', labelsize=20)

    ax1 = fig.add_axes([.08, 0.05, .4, .15])
    ax1.set_frame_on(False)
    ax1.fill_between(range(0, 500), numpy.exp(-psi_quantiles[:, 0]),
                     numpy.exp(-psi_quantiles[:, 1]), color=psi_color)
    ax1.plot(range(500), numpy.exp(-psi_true), linewidth=4, color=psi_color * .8)
    ax1.set_yticks([.0, .01, .02])
    ax1.set_ylim([.0, .025])
    ymin, ymax = ax1.get_yaxis().get_view_interval()
    xmin, xmax = ax1.get_xaxis().get_view_interval()
    ax1.add_artist(pyplot.Line2D((xmin, xmin), (ymin, ymax), color='black',
                                 linewidth=2))
    ax1.add_artist(pyplot.Line2D((xmin, xmax), (ymin, ymin), color='black',
                                 linewidth=3))
    ax1.set_xticks([50, 150, 300])
    ax1.yaxis.set_ticks_position('left')
    ax1.xaxis.set_ticks_position('bottom')
    ax1.set_ylabel('$p_{\\mathrm{silence}}$', fontsize=26)
    ax1.set_xlabel('Time [AU]', fontsize=26)
    ax1.tick_params(axis='both', which='major', labelsize=20)
    # Entropy
    ax2 = fig.add_axes([.52, 0.23, .4, .15])
    ax2.set_frame_on(False)

    ax2.fill_between(range(0, 500), S_quantiles[:, 0] / numpy.log2(numpy.exp(1)),
                     S_quantiles[:, 1] / numpy.log2(numpy.exp(1)), color=S_color)
    ax2.plot(range(500), S_true / numpy.log2(numpy.exp(1)), linewidth=4, color=S_color * .8)
    ax2.set_xticks([50, 150, 300])
    ax2.set_yticks([10, 14, 18])
    ymin, ymax = ax2.get_yaxis().get_view_interval()
    xmin, xmax = ax2.get_xaxis().get_view_interval()
    ax2.add_artist(pyplot.Line2D((xmin, xmin), (ymin, ymax), color='black',
                                 linewidth=2))
    ax2.add_artist(pyplot.Line2D((xmin, xmax), (ymin, ymin), color='black',
                                 linewidth=3))
    ax2.yaxis.set_ticks_position('left')
    ax2.xaxis.set_ticks_position('bottom')
    ax2.set_ylabel('$S$', fontsize=26)
    ax2.tick_params(axis='both', which='major', labelsize=20)
    # Heat capacity
    ax2 = fig.add_axes([.52, 0.05, .4, .15])
    ax2.set_frame_on(False)
    ax2.fill_between(range(0, 500),
                     C_quantiles[:, 0] / numpy.log2(numpy.exp(1)),
                     C_quantiles[:, 1] / numpy.log2(numpy.exp(1)),
                     color=C_color)
    ax2.plot(range(500), C_true / numpy.log2(numpy.exp(1)), linewidth=5,
             color=C_color * .8)
    ymin, ymax = ax2.get_yaxis().get_view_interval()
    xmin, xmax = ax2.get_xaxis().get_view_interval()
    ax2.add_artist(pyplot.Line2D((xmin, xmin), (ymin, ymax), color='black',
                                 linewidth=2))
    ax2.add_artist(pyplot.Line2D((xmin, xmax), (ymin, ymin), color='black',
                                 linewidth=3))
    ax2.set_xticks([50, 150, 300])
    ax2.set_yticks([5, 10])
    ax2.yaxis.set_ticks_position('left')
    ax2.xaxis.set_ticks_position('bottom')
    ax2.set_xlabel('Time [AU]', fontsize=26)
    ax2.set_ylabel('$C$', fontsize=26)
    ax2.tick_params(axis='both', which='major', labelsize=20)
    ax = fig.add_axes([0.03, 0.95, .05, .05], frameon=0)
    ax.set_yticks([])
    ax.set_xticks([])
    ax.text(.0, .0, 'A', fontsize=26, fontweight='bold')
    ax = fig.add_axes([0.52, 0.95, .05, .05], frameon=0)
    ax.set_yticks([])
    ax.set_xticks([])
    ax.text(.0, .0, 'B', fontsize=26, fontweight='bold')
    ax = fig.add_axes([0.05, 0.4, .05, .05], frameon=0)
    ax.set_yticks([])
    ax.set_xticks([])
    ax.text(.0, .0, 'C', fontsize=26, fontweight='bold')
    fig.savefig(plot_path+'fig1.eps')
    pyplot.show()
Example #14
0
# Sample images from underlying and fitted models
import transforms
import synthesis

if exact:
    transforms.initialise(N, 2)

gen_images = list()
sampled_images = list()
seed = numpy.random.seed(1)

for t in range(-1, T1 + int(T1 / 4) - 1, int(T1 / 4)):
    # generative image
    mixed_theta = transforms.compute_mixed_theta(theta_gen[t, :], J_gen)
    if exact:
        p = transforms.compute_p(mixed_theta.reshape(dim, 1)).reshape(1, 2**N)
        gen_images.append(synthesis.generate_spikes(p, 1, seed=seed))
    else:
        gen_images.append(synthesis.generate_spikes_gibbs(mixed_theta.reshape(1,dim), N, \
                                                 2, 1, seed=seed))
    # sampled images
    mixed_theta = transforms.compute_mixed_theta(theta_fit[t, :],
                                                 -J_list[T - T1 + t])
    if exact:
        p = transforms.compute_p(mixed_theta.reshape(dim, 1)).reshape(1, 2**N)
        sampled_images.append(synthesis.generate_spikes(p, 1, seed=seed))
    else:
        sampled_images.append(synthesis.generate_spikes_gibbs(mixed_theta.reshape(1,dim), N, \
                                                 2, 1, seed=seed))
# J correlation
d1 = list()
Example #15
0
def bfgs(y_t, X_t, R, theta_0, theta_o, sigma_o, sigma_o_i, *args):
    """ Fits due to `Broyden-Fletcher-Goldfarb-Shanno algorithm
    <https://en.wikipedia.org/wiki/Broyden%E2%80%93Fletcher%E2%80%93Goldfarb%E2%
    80%93Shanno_algorithm>`_.

    :param container.EMData emd:
        All data pertaining to the EM algorithm.
    :param int t:
        Timestep for which to compute the maximum posterior probability.

    :returns:
        Tuple containing the mean and covariance of the posterior probability
        density, each as a numpy.ndarray.

    @author: Christian Donner
    """

    # # Initialize theta with previous smoothed theta
    theta_max = theta_0
    # Get p and eta values for current theta
    p = transforms.compute_p(theta_max)
    eta = transforms.compute_eta(p)
    # Initialize the estimate of the inverse fisher info
    ddlpo_i_e = numpy.identity(theta_max.shape[0])
    # Compute derivative of posterior
    dllk = R * (y_t - eta)
    dlpr = -numpy.dot(sigma_o_i, theta_max - theta_o)
    dlpo = dllk + dlpr
    # Initialize stopping criterion variables
    max_dlpo = 1.
    iterations = 0

    # Iterate until convergence or failure
    while max_dlpo > GA_CONVERGENCE:
        # Compute direction for line search
        s_dir = numpy.dot(dlpo, ddlpo_i_e)
        # Set theta to old theta
        theta_prev = numpy.copy(theta_max)
        # Set current log posterior gradient to previous
        dlpo_prev = dlpo
        # Perform line search
        theta_max, dlpo, p, eta = line_search(theta_max, y_t, R, p, s_dir,
                                              dlpo, theta_o, sigma_o_i)
        # Get the difference between old and new theta
        d_theta = theta_max - theta_prev
        # Difference in log posterior gradients
        dlpo_diff = dlpo_prev - dlpo
        # Project gradient change on theta change
        dlpo_diff_dth = numpy.inner(dlpo_diff, d_theta)
        # Compute estimate of covariance matrix with Sherman-Morrison Formula
        a = (dlpo_diff_dth + \
             numpy.dot(dlpo_diff, numpy.dot(ddlpo_i_e, dlpo_diff.T)))*\
            numpy.outer(d_theta, d_theta)
        b = numpy.inner(d_theta, dlpo_diff)**2
        c = numpy.dot(ddlpo_i_e, numpy.outer(dlpo_diff, d_theta)) + \
            numpy.outer(d_theta, numpy.inner(dlpo_diff, ddlpo_i_e))
        d = dlpo_diff_dth
        ddlpo_i_e += (a / b - c / d)
        # Get maximal entry of log posterior grad divided by number of trials
        max_dlpo = numpy.amax(numpy.absolute(dlpo)) / R
        # Count iterations
        iterations += 1
        if iterations == MAX_GA_ITERATIONS:
            raise Exception('The maximum-a-posterior bfgs-gradient '+\
                'algorithm did not converge before reaching the maximum '+\
                'number iterations.')

    # Compute final covariance matrix
    ddllk = -R * transforms.compute_fisher_info(p, eta)
    ddlpo = ddllk - sigma_o_i
    ddlpo_i = numpy.linalg.inv(ddlpo)

    return theta_max, -ddlpo_i
Example #16
0
def bfgs(y_t, X_t, R, theta_0, theta_o, sigma_o, sigma_o_i, *args):
    """ Fits due to `Broyden-Fletcher-Goldfarb-Shanno algorithm
    <https://en.wikipedia.org/wiki/Broyden%E2%80%93Fletcher%E2%80%93Goldfarb%E2%
    80%93Shanno_algorithm>`_.

    :param container.EMData emd:
        All data pertaining to the EM algorithm.
    :param int t:
        Timestep for which to compute the maximum posterior probability.

    :returns:
        Tuple containing the mean and covariance of the posterior probability
        density, each as a numpy.ndarray.

    @author: Christian Donner
    """

    # # Initialize theta with previous smoothed theta
    theta_max = theta_0
    # Get p and eta values for current theta
    p = transforms.compute_p(theta_max)
    eta = transforms.compute_eta(p)
    # Initialize the estimate of the inverse fisher info
    ddlpo_i_e = numpy.identity(theta_max.shape[0])
    # Compute derivative of posterior
    dllk = R*(y_t - eta)
    dlpr = -numpy.dot(sigma_o_i, theta_max - theta_o)
    dlpo = dllk + dlpr
    # Initialize stopping criterion variables
    max_dlpo = 1.
    iterations = 0

    # Iterate until convergence or failure
    while max_dlpo > GA_CONVERGENCE:
        # Compute direction for line search
        s_dir = numpy.dot(dlpo, ddlpo_i_e)
        # Set theta to old theta
        theta_prev = numpy.copy(theta_max)
        # Set current log posterior gradient to previous
        dlpo_prev = dlpo
        # Perform line search
        theta_max, dlpo, p, eta = line_search(theta_max, y_t, R, p, s_dir, dlpo,
                                              theta_o, sigma_o_i)
        # Get the difference between old and new theta
        d_theta = theta_max - theta_prev
        # Difference in log posterior gradients
        dlpo_diff = dlpo_prev - dlpo
        # Project gradient change on theta change
        dlpo_diff_dth = numpy.inner(dlpo_diff, d_theta)
        # Compute estimate of covariance matrix with Sherman-Morrison Formula
        a = (dlpo_diff_dth + \
             numpy.dot(dlpo_diff, numpy.dot(ddlpo_i_e, dlpo_diff.T)))*\
            numpy.outer(d_theta, d_theta)
        b = numpy.inner(d_theta, dlpo_diff)**2
        c = numpy.dot(ddlpo_i_e, numpy.outer(dlpo_diff, d_theta)) + \
            numpy.outer(d_theta, numpy.inner(dlpo_diff, ddlpo_i_e))
        d = dlpo_diff_dth
        ddlpo_i_e += (a/b - c/d)
        # Get maximal entry of log posterior grad divided by number of trials
        max_dlpo = numpy.amax(numpy.absolute(dlpo)) / R
        # Count iterations
        iterations += 1
        if iterations == MAX_GA_ITERATIONS:
            raise Exception('The maximum-a-posterior bfgs-gradient '+\
                'algorithm did not converge before reaching the maximum '+\
                'number iterations.')

    # Compute final covariance matrix
    ddllk = -R*transforms.compute_fisher_info(p, eta)
    ddlpo = ddllk - sigma_o_i
    ddlpo_i = numpy.linalg.inv(ddlpo)

    return theta_max, -ddlpo_i
Example #17
0
def generate_data_figure2(data_path='../Data/', max_network_size=60):
    N, O, R, T = 10, 2, 200, 500
    num_of_networks = max_network_size/N
    mu = numpy.zeros(T)
    x = numpy.arange(1, 401)
    mu[100:] = 1. * (3. / (2. * numpy.pi * (x / 400. * 3.) ** 3)) ** .5 * \
               numpy.exp(-3. * ((x / 400. * 3.) - 1.) ** 2 /
                         (2. * (x / 400. * 3.)))

    D = transforms.compute_D(N, O)
    thetas = numpy.empty([num_of_networks, T, D])
    etas = numpy.empty([num_of_networks, T, D])
    psi = numpy.empty([num_of_networks, T])
    S = numpy.empty([num_of_networks, T])
    C = numpy.empty([num_of_networks, T])
    transforms.initialise(N, O)
    for i in range(num_of_networks):
        thetas[i] = synthesis.generate_thetas(N, O, T, mu1=-2.)
        thetas[i, :, :N] += mu[:, numpy.newaxis]
        for t in range(T):
            p = transforms.compute_p(thetas[i, t])
            etas[i, t] = transforms.compute_eta(p)
            psi[i, t] = transforms.compute_psi(thetas[i, t])
            psi1 = transforms.compute_psi(.999 * thetas[i, t])
            psi2 = transforms.compute_psi(1.001 * thetas[i, t])
            C[i, t] = (psi1 - 2. * psi[i, t] + psi2) / .001 ** 2
            S[i, t] = -(numpy.sum(etas[i, t] * thetas[i, t]) - psi[i, t])
    C /= numpy.log(2)
    S /= numpy.log(2)
    f = h5py.File(data_path + 'figure2data.h5', 'w')
    g1 = f.create_group('data')
    g1.create_dataset('thetas', data=thetas)
    g1.create_dataset('etas', data=etas)
    g1.create_dataset('psi', data=psi)
    g1.create_dataset('S', data=S)
    g1.create_dataset('C', data=C)
    g2 = f.create_group('error')
    g2.create_dataset('MISE_thetas', shape=[num_of_networks])
    g2.create_dataset('MISE_population_rate', shape=[num_of_networks])
    g2.create_dataset('MISE_psi', shape=[num_of_networks])
    g2.create_dataset('MISE_S', shape=[num_of_networks])
    g2.create_dataset('MISE_C', shape=[num_of_networks])
    g2.create_dataset('population_rate', shape=[num_of_networks, T])
    g2.create_dataset('psi', shape=[num_of_networks, T])
    g2.create_dataset('S', shape=[num_of_networks, T])
    g2.create_dataset('C', shape=[num_of_networks, T])
    f.close()
    for i in range(num_of_networks):
        print 'N=%d' % ((i + 1) * N)
        D = transforms.compute_D((i + 1) * N, O)
        theta_all = numpy.empty([T, D])
        triu_idx = numpy.triu_indices(N, k=1)
        triu_idx_all = numpy.triu_indices((i + 1) * N, k=1)
        for j in range(i + 1):
            theta_all[:, N * j:(j + 1) * N] = thetas[j, :, :N]
            for t in range(T):
                theta_ij = numpy.zeros([(i + 1) * N, (i + 1) * N])
                for j in range(i + 1):
                    theta_ij[triu_idx[0] + j * N, triu_idx[1] + j * N] = \
                        thetas[j, t, N:]

            theta_all[t, (i + 1) * N:] = theta_ij[triu_idx_all]

        spikes = synthesis.generate_spikes_gibbs_parallel(theta_all
                                                          , (i + 1) * N, O, R,
                                                          sample_steps=10,
                                                          num_proc=4)
        emd = __init__.run(spikes, O, map_function='cg', param_est='pseudo',
                           param_est_eta='bethe_hybrid', lmbda1=100,
                           lmbda2=200)

        eta_est = numpy.empty(emd.theta_s.shape)
        psi_est = numpy.empty(T)
        S_est = numpy.empty(T)
        C_est = numpy.empty(T)
        for t in range(T):
            eta_est[t], psi_est[t] = bethe_approximation.compute_eta_hybrid(
                emd.theta_s[t], (i + 1) * N, return_psi=1)
            psi1 = bethe_approximation.compute_eta_hybrid(
                .999 * emd.theta_s[t], (i + 1) * N, return_psi=1)[1]
            psi2 = bethe_approximation.compute_eta_hybrid(
                1.001 * emd.theta_s[t], (i + 1) * N, return_psi=1)[1]
            S_est[t] = -(numpy.sum(eta_est[t] * emd.theta_s[t]) - psi_est[t])
            C_est[t] = (psi1 - 2. * psi_est[t] + psi2) / .001 ** 2
        S_est /= numpy.log(2)
        C_est /= numpy.log(2)
        population_rate = numpy.mean(numpy.mean(etas[:i + 1, :, :N], axis=0),
                                     axis=1)
        population_rate_est = numpy.mean(eta_est[:, :(i + 1) * N], axis=1)
        psi_true = numpy.sum(psi[:(i + 1), :], axis=0)
        S_true = numpy.sum(S[:(i + 1), :], axis=0)
        C_true = numpy.sum(C[:(i + 1), :], axis=0)

        f = h5py.File(data_path + 'figure2data.h5', 'r+')
        f['error']['MISE_thetas'][i] = numpy.mean(
            (theta_all - emd.theta_s) ** 2)
        f['error']['MISE_population_rate'][i] = numpy.mean(
            (population_rate - population_rate_est) ** 2)
        f['error']['MISE_psi'][i] = numpy.mean((psi_est - psi_true) ** 2)
        f['error']['MISE_S'][i] = numpy.mean((S_est - S_true) ** 2)
        f['error']['MISE_C'][i] = numpy.mean((C_est - C_true) ** 2)
        f['error']['population_rate'][i] = population_rate_est
        f['error']['psi'][i] = psi_est
        f['error']['S'][i] = S_est
        f['error']['C'][i] = C_est
        f.close()

    f = h5py.File(data_path + 'figure2data.h5', 'r+')
    thetas = f['data']['thetas'].value
    etas = f['data']['etas'].value
    psi = f['data']['psi'].value
    S = f['data']['S'].value
    C = f['data']['C'].value

    g2 = f.create_group('error500')
    g2.create_dataset('population_rate', shape=[num_of_networks, T])
    g2.create_dataset('psi', shape=[num_of_networks, T])
    g2.create_dataset('S', shape=[num_of_networks, T])
    g2.create_dataset('C', shape=[num_of_networks, T])
    g2.create_dataset('MISE_thetas', shape=[num_of_networks])
    g2.create_dataset('MISE_population_rate', shape=[num_of_networks])
    g2.create_dataset('MISE_psi', shape=[num_of_networks])
    g2.create_dataset('MISE_S', shape=[num_of_networks])
    g2.create_dataset('MISE_C', shape=[num_of_networks])
    f.close()

    R = 500

    for i in range(num_of_networks):
        print 'N=%d' % ((i + 1) * N)
        D = transforms.compute_D((i + 1) * N, O)
        theta_all = numpy.empty([T, D])
        triu_idx = numpy.triu_indices(N, k=1)
        triu_idx_all = numpy.triu_indices((i + 1) * N, k=1)

        for j in range(i + 1):
            theta_all[:, N * j:(j + 1) * N] = thetas[j, :, :N]

        for t in range(T):
            theta_ij = numpy.zeros([(i + 1) * N, (i + 1) * N])
            for j in range(i + 1):
                theta_ij[triu_idx[0] + j * N, triu_idx[1] + j * N] = \
                    thetas[j, t, N:]

            theta_all[t, (i + 1) * N:] = theta_ij[triu_idx_all]

        spikes = synthesis.generate_spikes_gibbs_parallel(theta_all,
                                                          (i + 1) * N, O, R,
                                                          sample_steps=10,
                                                          num_proc=4)
        emd = __init__.run(spikes, O, map_function='cg', param_est='pseudo',
                           param_est_eta='bethe_hybrid', lmbda1=100,
                           lmbda2=200)

        eta_est = numpy.empty(emd.theta_s.shape)
        psi_est = numpy.empty(T)
        S_est = numpy.empty(T)
        C_est = numpy.empty(T)

        for t in range(T):
            eta_est[t], psi_est[t] = \
                bethe_approximation.compute_eta_hybrid(emd.theta_s[t],
                                                       (i + 1) * N,
                                                       return_psi=1)
            psi1 = bethe_approximation.compute_eta_hybrid(.999 * emd.theta_s[t],
                                                          (i + 1) * N,
                                                          return_psi=1)[1]
            psi2 = bethe_approximation.compute_eta_hybrid(
                1.001 * emd.theta_s[t], (i + 1) * N, return_psi=1)[1]
            S_est[t] = -(numpy.sum(eta_est[t] * emd.theta_s[t]) - psi_est[t])
            C_est[t] = (psi1 - 2. * psi_est[t] + psi2) / .001 ** 2
        S_est /= numpy.log(2)
        C_est /= numpy.log(2)
        population_rate = numpy.mean(numpy.mean(etas[:i + 1, :, :N], axis=0),
                                     axis=1)
        population_rate_est = numpy.mean(eta_est[:, :(i + 1) * N], axis=1)
        psi_true = numpy.sum(psi[:(i + 1), :], axis=0)
        S_true = numpy.sum(S[:(i + 1), :], axis=0)
        C_true = numpy.sum(C[:(i + 1), :], axis=0)

        f = h5py.File(data_path + 'figure2data.h5', 'r+')
        f['error500']['MISE_thetas'][i] = numpy.mean(
            (theta_all - emd.theta_s) ** 2)
        f['error500']['MISE_population_rate'][i] = numpy.mean(
            (population_rate - population_rate_est) ** 2)
        f['error500']['MISE_psi'][i] = numpy.mean((psi_est - psi_true) ** 2)
        f['error500']['MISE_S'][i] = numpy.mean((S_est - S_true) ** 2)
        f['error500']['MISE_C'][i] = numpy.mean((C_est - C_true) ** 2)
        f['error500']['population_rate'][i] = population_rate_est
        f['error500']['psi'][i] = psi_est
        f['error500']['S'][i] = S_est
        f['error500']['C'][i] = C_est
        f.close()
Example #18
0
def generate_data_figure3and4(data_path = '../Data/', num_of_iterations=10):
    R, T, N, O = 200, 500, 15, 2
    f = h5py.File(data_path + 'figure1data.h5', 'r')
    theta = f['data']['theta1'].value
    f.close()

    transforms.initialise(N, O)
    psi_true = numpy.empty(T)
    for i in range(T):
        psi_true[i] = transforms.compute_psi(theta[i])
    p = numpy.zeros((T, 2 ** N))
    for i in range(T):
        p[i, :] = transforms.compute_p(theta[i, :])
    fitting_methods = ['exact', 'bethe_hybrid', 'mf']

    f = h5py.File(data_path + 'figure2and3data.h5', 'w')
    f.create_dataset('psi_true', data=psi_true)
    f.create_dataset('theta_true', data=theta)
    for fit in fitting_methods:
        g = f.create_group(fit)
        g.create_dataset('MISE_theta', shape=[num_of_iterations])
        g.create_dataset('MISE_psi', shape=[num_of_iterations])
        g.create_dataset('psi', shape=[num_of_iterations, T])
    f.close()

    for iteration in range(num_of_iterations):
        print 'Iteration %d' % iteration
        spikes = synthesis.generate_spikes(p, R, seed=None)

        for fit in fitting_methods:
            if fit == 'exact':
                emd = __init__.run(spikes, O, map_function='cg',
                                   param_est='exact', param_est_eta='exact')
            else:
                emd = __init__.run(spikes, O, map_function='cg',
                                   param_est='pseudo', param_est_eta=fit)

            psi = numpy.empty(T)

            if fit == 'exact':
                for i in range(T):
                    psi[i] = transforms.compute_psi(emd.theta_s[i])
            elif fit == 'bethe_hybrid':
                for i in range(T):
                    psi[i] = bethe_approximation.compute_eta_hybrid(
                        emd.theta_s[i], N, return_psi=1)[1]
            elif fit == 'mf':
                for i in range(T):
                    eta_mf = mean_field.forward_problem(emd.theta_s[i], N,
                                                        'TAP')
                    psi[i] = mean_field.compute_psi(emd.theta_s[i], eta_mf, N)

            mise_theta = numpy.mean((theta - emd.theta_s) ** 2)
            mise_psi = numpy.mean((psi_true - psi) ** 2)
            f = h5py.File(data_path + 'figure2and3data.h5', 'r+')
            g = f[fit]
            g['MISE_theta'][iteration] = mise_theta
            g['MISE_psi'][iteration] = mise_psi
            if iteration == 0:
                g.create_dataset('theta', data=emd.theta_s)
                g.create_dataset('sigma', data=emd.sigma_s)
            g['psi'][iteration] = psi
            f.close()
            print 'Fitted with %s' % fit
Example #19
0
def newton_raphson(emd, t):
    """
    Computes the MAP estimate of the natural parameters at some timestep, given
    the observed spike patterns at that timestep and the one-step-prediction
    mean and covariance for the same timestep.
    :param container.EMData emd:
        All data pertaining to the EM algorithm.
    :param int t:
        Timestep for which to compute the maximum posterior probability.
    :returns:
        Tuple containing the mean and covariance of the posterior probability
        density, each as a numpy.ndarray.
    """
    # Extract one-step predictions for time t
    theta_o = emd.theta_o[t, :]
    sigma_o = emd.sigma_o[t, :, :]
    R = emd.R
    N = emd.N
    exact = emd.exact
    # Extract the feature vector for time t
    f_t = emd.f[t, :]
    # Extract the fitted parameters of the original Ising models
    J = emd.J
    # Initialise theta_max to the smooth theta value of the previous iteration
    theta_max = emd.theta_s[t, :]
    # Use non-normalised posterior prob. as loop guard
    lpp = -numpy.inf
    lpc = probability.log_likelihood(f_t, theta_max, J, R, N, exact) +\
          probability.log_multivariate_normal(theta_max, theta_o, sigma_o)
    iterations = 0
    # Iterate the gradient ascent algorithm until convergence or failure
    while lpc - lpp > GA_CONVERGENCE:
        # Compute mixed theta
        theta_mixed = transforms.compute_mixed_theta(theta_max, J)
        # Compute the eta of the current theta values
        if exact:
            p = transforms.compute_p(theta_mixed)
            eta_tilde = transforms.compute_eta(p)
        else:
            eta_tilde = bethe_approximation.compute_eta_hybrid(theta_mixed, N)
        eta = transforms.compute_eta_LD(eta_tilde, J)
        # Compute the inverse of one-step covariance
        sigma_o_i = numpy.linalg.inv(sigma_o)
        # Compute the first derivative of the posterior prob. w.r.t. theta_max
        dllk = R * (f_t - eta)
        dlpr = -numpy.dot(sigma_o_i, theta_max - theta_o)
        dlpo = dllk + dlpr
        # Compute the second derivative of the posterior prob. w.r.t. theta_max
        if exact:
            fisher_tilde = transforms.compute_fisher_info(p, eta_tilde)
        else:
            fisher_tilde = numpy.diag(
                bethe_approximation.construct_fisher_diag(eta_tilde, N))
        fisher = transforms.compute_fisher_info_LD(fisher_tilde, J)
        ddlpo = -R * fisher - sigma_o_i
        # Dot the results to climb the gradient, and accumulate the result
        ddlpo_i = numpy.linalg.inv(ddlpo)
        theta_max -= numpy.dot(ddlpo_i, dlpo)

        # Update previous and current posterior prob.
        lpp = lpc
        lpc = probability.log_likelihood(f_t, theta_max, J, R, N, exact)\
              + probability.log_multivariate_normal(theta_max, theta_o, sigma_o)
        # Count iterations
        iterations += 1
        # Check for check for overrun
        if iterations == MAX_GA_ITERATIONS:
            raise Exception('The maximum-a-posterior gradient-ascent '+\
                'algorithm did not converge before reaching the maximum '+\
                'number iterations.')

    return theta_max, -ddlpo_i
Example #20
0
############# Computation of macroscopic properties #############
eta = numpy.zeros((12, T, D))
psi = numpy.zeros((12, T))
epsilon = 1e-3
C = numpy.zeros((12, T))
p_silence = numpy.zeros((12, T))
p_spike = numpy.zeros((12, T))
S2 = numpy.zeros((12, T))
theta_ind = numpy.zeros((12, T, N))
eta_ind = numpy.zeros((12, T, N))
psi_ind = numpy.zeros((12, T))
S1 = numpy.zeros((12, T))
for k in range(12):
    if emd.marg_llk == probability.log_marginal:  # If exact:
        for t in range(T):
            p = transforms.compute_p(theta_m[k, t, :])
            psi[k, t] = transforms.compute_psi(theta_m[k, t, :])
            eta[k, t, :] = transforms.compute_eta(p)
            tmp1 = transforms.compute_psi(theta_m[k, t, :] * (1 + epsilon))
            tmp2 = transforms.compute_psi(theta_m[k, t, :] * (1 - epsilon))
            c = tmp1 - 2 * psi[k, t] + tmp2
            d = epsilon**2
            C[k, t] = c / d
    else:  # If approximations
        for t in range(T):
            eta[k, t, :], psi[k, t] = bethe_approximation.compute_eta_hybrid(
                theta_m[k, t, :], N, return_psi=True)
            tmp1 = bethe_approximation.compute_eta_hybrid(theta_m[k, t, :] *
                                                          (1 + epsilon),
                                                          N,
                                                          return_psi=True)[1]
Example #21
0
theta_gen = numpy.zeros((T1, D))
frequency = numpy.array([1, 1])
amplitude = numpy.array([0.5, -0.5])
baseline = numpy.array([0.5, 0.5])
for t in range(T1):
    theta_gen[t, :] = amplitude * numpy.sin(
        2 * numpy.pi * frequency * t / T1) + baseline

# Mixed theta
mixed_theta = transforms.compute_mixed_theta(theta_gen, J_gen)  # (T1, dim)

# Probability vector
if exact:
    p = numpy.zeros((T1, 2**N))
    for t in range(T1):
        p[t, :] = transforms.compute_p(mixed_theta[t, :])

##### Fitted model #####

# First estimate of the fitted J Matrix
J = numpy.random.normal(0, 1, (dim, D_fit))

# Mean and covariance of weights at the last fitted epoch
theta_fit = numpy.zeros((T1, D_fit))
sigma = numpy.zeros((T1, D_fit))
# Marginal log-likelihood at the end of every epoch
lm = numpy.zeros((T1))
lm_rep = list()
# J matrix at every time step
J_list = list()
J_list.append(J)
 epsilon = 1e-3
 for n in range(n_samples):
     # Sample theta
     theta_sampled = numpy.zeros((T, D))
     for t in range(T):
         theta_sampled[t] = numpy.random.multivariate_normal(
             theta[t, :], sigma[t], 1).reshape(D)
     physics_matrix[n, 0, :] = numpy.mean(theta_sampled[:, :N], axis=1).T
     physics_matrix[n, 1, :] = numpy.mean(theta_sampled[:, N:], axis=1).T
     print(n)
     # Obtain eta and psi
     eta = numpy.zeros((T, D))
     psi = numpy.zeros((T, ))
     if exact:
         for t in range(T):
             p = transforms.compute_p(theta_sampled[t, :])
             eta[t, :] = transforms.compute_eta(p)
             psi[t] = transforms.compute_psi(theta_sampled[t, :])
     else:
         for t in range(T):
             eta[t,:], psi[t] = bethe_approximation.compute_eta_hybrid\
                        (theta_sampled[t,:], N, return_psi=True)
     # Entropy (2nd order)
     S2 = energies.compute_entropy(theta_sampled[:, :], eta, psi, 2)
     # p_silence
     p_silence = numpy.exp(-psi)
     # p_spike
     p_spike = numpy.mean(eta[:, :N], axis=1)
     # Heat capacity
     tmp1 = numpy.zeros((T, ))
     tmp2 = numpy.zeros((T, ))