Esempio n. 1
0
def get_mi_asymptotics(M, R):
    """
    Return a multiline string with some asymptotics.
    @param M: pure mutation rate matrix
    @param R: mutation-selection balance rate matrix
    @return: multiline string
    """
    out = StringIO()
    # get the stationary distributions
    M_v = mrate.R_to_distn(M)
    R_v = mrate.R_to_distn(R)
    # The shannon entropy of the stationary distribution of the process
    # determines the mutual information at small times.
    M_shannon_entropy = -np.dot(np.log(M_v), M_v)
    R_shannon_entropy = -np.dot(np.log(R_v), R_v)
    if not np.allclose(M_shannon_entropy, R_shannon_entropy):
        print >> out, 'At small enough times'
        if R_shannon_entropy < M_shannon_entropy:
            print >> out, '* pure mutation',
        else:
            print >> out, '* mutation-selection balance',
        print >> out, 'will be more informative'
        print >> out, 'because its stationary distribution has greater',
        print >> out, 'Shannon entropy.'
    else:
        print >> out, 'There is not enough difference between the'
        print >> out, 'Shannon entropies of the stationary distributions'
        print >> out, 'to determine which process'
        print >> out, 'is more informative at times near zero'
    print >> out
    # The spectral gap of the process
    # determines the mutual information at large times.
    M_spectral_gap = sorted(abs(w) for w in scipy.linalg.eigvals(M))[1]
    R_spectral_gap = sorted(abs(w) for w in scipy.linalg.eigvals(R))[1]
    M_cheeg_low, M_cheeg_mid, M_cheeg_high = cheeger.get_cheeger_bounds(M, M_v)
    R_cheeg_low, R_cheeg_mid, R_cheeg_high = cheeger.get_cheeger_bounds(R, R_v)
    if not np.allclose(M_spectral_gap, R_spectral_gap):
        print >> out, 'At large enough times'
        if R_spectral_gap < M_spectral_gap:
            print >> out, '* mutation-selection balance',
        else:
            print >> out, '* pure mutation',
        print >> out, 'will be more informative'
        print >> out, 'because it has a smaller spectral gap.'
        if (R_cheeg_high < M_cheeg_low) or (M_cheeg_high < R_cheeg_low):
            print >> out, 'And also because of the isoperimetric bounds.'
    else:
        print >> out, 'There is not enough difference between the'
        print >> out, 'spectral gaps to determine which process'
        print >> out, 'is more informative at times near infinity'
    print >> out
    # return the text
    return out.getvalue().strip()
Esempio n. 2
0
def get_mi_asymptotics(M, R):
    """
    Return a multiline string with some asymptotics.
    @param M: pure mutation rate matrix
    @param R: mutation-selection balance rate matrix
    @return: multiline string
    """
    out = StringIO()
    # get the stationary distributions
    M_v = mrate.R_to_distn(M)
    R_v = mrate.R_to_distn(R)
    # The shannon entropy of the stationary distribution of the process
    # determines the mutual information at small times.
    M_shannon_entropy = -np.dot(np.log(M_v), M_v)
    R_shannon_entropy = -np.dot(np.log(R_v), R_v)
    if not np.allclose(M_shannon_entropy, R_shannon_entropy):
        print >> out, 'At small enough times'
        if R_shannon_entropy < M_shannon_entropy:
            print >> out, '* pure mutation',
        else:
            print >> out, '* mutation-selection balance',
        print >> out, 'will be more informative'
        print >> out, 'because its stationary distribution has greater',
        print >> out, 'Shannon entropy.'
    else:
        print >> out, 'There is not enough difference between the'
        print >> out, 'Shannon entropies of the stationary distributions'
        print >> out, 'to determine which process'
        print >> out, 'is more informative at times near zero'
    print >> out
    # The spectral gap of the process
    # determines the mutual information at large times.
    M_spectral_gap = sorted(abs(w) for w in scipy.linalg.eigvals(M))[1]
    R_spectral_gap = sorted(abs(w) for w in scipy.linalg.eigvals(R))[1]
    M_cheeg_low, M_cheeg_mid, M_cheeg_high = cheeger.get_cheeger_bounds(M, M_v)
    R_cheeg_low, R_cheeg_mid, R_cheeg_high = cheeger.get_cheeger_bounds(R, R_v)
    if not np.allclose(M_spectral_gap, R_spectral_gap):
        print >> out, 'At large enough times'
        if R_spectral_gap < M_spectral_gap:
            print >> out, '* mutation-selection balance',
        else:
            print >> out, '* pure mutation',
        print >> out, 'will be more informative'
        print >> out, 'because it has a smaller spectral gap.'
        if (R_cheeg_high < M_cheeg_low) or (M_cheeg_high < R_cheeg_low):
            print >> out, 'And also because of the isoperimetric bounds.'
    else:
        print >> out, 'There is not enough difference between the'
        print >> out, 'spectral gaps to determine which process'
        print >> out, 'is more informative at times near infinity'
    print >> out
    # return the text
    return out.getvalue().strip()
Esempio n. 3
0
 def __init__(self, Q):
     """
     @param Q: rate matrix
     """
     # define intermediate variables
     v = mrate.R_to_distn(Q)
     n = len(v)
     psi = np.sqrt(v)
     c_low, c_mid, c_high = cheeger.get_cheeger_bounds(Q, v)
     # define member variables to summarize the rate matrix
     self.rate_matrix = Q
     self.exch_matrix = Q / v
     if not np.allclose(self.exch_matrix, self.exch_matrix.T):
         print self.exch_matrix
         raise ValueError('expected symmetry')
     self.sim_sym_matrix = np.outer(psi, 1 / psi) * Q
     if not np.allclose(self.sim_sym_matrix, self.sim_sym_matrix.T):
         print self.sim_sym_matrix
         raise ValueError('expected symmetry')
     self.distn = v
     self.distn_shannon_entropy = -ndot(np.log(v), v)
     self.distn_logical_entropy = ndot(v, 1 - v)
     self.expected_rate = -ndot(np.diag(Q), v)
     self.spectrum = scipy.linalg.eigvalsh(self.sim_sym_matrix)
     self.spectral_gap = -self.spectrum[-2]
     self.isoperimetric_low = c_low
     self.isoperimetric_constant = c_mid
     self.isoperimetric_high = c_high
     self.trace_bound_high = -sum(np.diag(Q)) / (n - 1)
Esempio n. 4
0
 def __init__(self, Q):
     """
     @param Q: rate matrix
     """
     # define intermediate variables
     v = mrate.R_to_distn(Q)
     n = len(v)
     psi = np.sqrt(v)
     c_low, c_mid, c_high = cheeger.get_cheeger_bounds(Q, v)
     # define member variables to summarize the rate matrix
     self.rate_matrix = Q
     self.exch_matrix = Q / v
     if not np.allclose(self.exch_matrix, self.exch_matrix.T):
         print self.exch_matrix
         raise ValueError('expected symmetry')
     self.sim_sym_matrix = np.outer(psi, 1/psi) * Q
     if not np.allclose(self.sim_sym_matrix, self.sim_sym_matrix.T):
         print self.sim_sym_matrix
         raise ValueError('expected symmetry')
     self.distn = v
     self.distn_shannon_entropy = -ndot(np.log(v), v)
     self.distn_logical_entropy = ndot(v, 1-v)
     self.expected_rate = -ndot(np.diag(Q), v)
     self.spectrum = scipy.linalg.eigvalsh(self.sim_sym_matrix)
     self.spectral_gap = -self.spectrum[-2]
     self.isoperimetric_low = c_low
     self.isoperimetric_constant = c_mid
     self.isoperimetric_high = c_high
     self.trace_bound_high = -sum(np.diag(Q)) / (n-1)