Example #1
0
def get_sampled_eta_psi(i, theta_sampled, N):
    print i
    psi = numpy.empty([100,3])
    eta = numpy.empty([int(N + N*(N-1)/2),100])
    alpha = [.999,1.,1.001]
    for j in range(100):
        for k, a in enumerate(alpha):
            if k == 1:
                eta[:,j], psi[j,k] = bethe_approximation.compute_eta_hybrid(
                    a*theta_sampled[i,:,j], int(N), return_psi=True)
            else:
                psi[j,k] = bethe_approximation.compute_eta_hybrid(
                    a*theta_sampled[i,:,j], int(N), return_psi=True)[1]
    return eta, psi, i
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 log_likelihood(f_t, theta_f_t, J, R, N, exact):
    """
    Computes the likelihood of observed pattern rates given the natural
    parameters, all for a single timestep.
    :param numpy.ndarray y_t:
        Frequency of observed patterns for one timestep.
    :param numpy.ndarray theta_f_t:
        Natural parameters of observed patterns for one timestep.
    :param numpy.ndarray J:
        Fitted graphs matrix
    :param int R:
        Number of trials over which patterns were observed.
    :param int N:
        Number of cells in the `spikes' train to analyze.
    :param boolean exact
        Whether to use exact solution (True) or Bethe approximation (False)
        for the computation of eta, psi and fisher info
    :returns:
        Log likelhood of the observed patterns given the natural parameters,
        as a float.
    """
    theta_mixed = transforms.compute_mixed_theta(theta_f_t, J)
    if exact:
        psi = transforms.compute_psi(theta_mixed)
    else:
        psi = bethe_approximation.compute_eta_hybrid(theta_mixed,
                                                     N,
                                                     return_psi=True)[1]
    log_p = R * (numpy.dot(f_t, theta_f_t) - psi)

    return log_p
Example #4
0
 def KL_distance(theta1, theta2, N):
     D = theta1.shape[0]
     eta1, psi1 = bethe_approximation.compute_eta_hybrid(theta1,
                                                         N,
                                                         return_psi=True)
     eta2, psi2 = bethe_approximation.compute_eta_hybrid(theta1,
                                                         N,
                                                         return_psi=True)
     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 #5
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 #6
0
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]
            tmp2 = bethe_approximation.compute_eta_hybrid(theta_m[k, t, :] *
                                                          (1 - epsilon),
                                                          N,
                                                          return_psi=True)[1]
            c = tmp1 - 2 * psi[k, t] + tmp2
            d = epsilon**2
            C[k, t] = c / d
    p_silence[k, :] = numpy.exp(-psi[k, :])
    p_spike[k, :] = numpy.sum(eta[k, :, :N], axis=1) / N
    S2[k, :] = energies.compute_entropy(theta_m[k, :, :], eta[k, :, :],
                                        psi[k, :], 2)
Example #7
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 #8
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()
 # 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, ))
 if exact:
     for t in range(T):
         tmp1[t] = transforms.compute_psi(theta_sampled[t, :] *
                                          (1 + epsilon))
         tmp2[t] = transforms.compute_psi(theta_sampled[t, :] *
                                          (1 - epsilon))
 else:
     for t in range(T):
         tmp1[t] = bethe_approximation.compute_eta_hybrid(
             theta_sampled[t, :] * (1 + epsilon), N, return_psi=True)[1]
         tmp2[t] = bethe_approximation.compute_eta_hybrid(
             theta_sampled[t, :] * (1 - epsilon), N, return_psi=True)[1]
 c = tmp1 - 2 * psi + tmp2
 d = epsilon**2
 C = c / d
 # Entropy (1st order)
 eta_ind = eta[:, :N]
 theta_ind = energies.compute_ind_theta(eta_ind)
 psi_ind = energies.compute_ind_psi(theta_ind)
 S1 = energies.compute_entropy(theta_ind, eta_ind, psi_ind, 1)
 # Entropy ratio
 ratio = (S1 - S2) / (S0 - S2)
 # Record results
 physics_matrix[n, 2, :] = p_spike
 physics_matrix[n, 3, :] = p_silence