def test_connected_count_matrix(self): """Directed""" C_cc = largest_connected_submatrix(self.C) assert_allclose(C_cc, self.C_cc_directed) """Undirected""" C_cc = largest_connected_submatrix(self.C, directed=False) assert_allclose(C_cc, self.C_cc_undirected)
def test_connected_count_matrix(self): """Directed""" C_cc = largest_connected_submatrix(self.C) assert_allclose(C_cc.toarray(), self.C_cc_directed) """Directed with user specified lcc""" C_cc = largest_connected_submatrix(self.C, lcc=np.array([0, 1])) assert_allclose(C_cc.toarray(), self.C_cc_directed[0:2, 0:2]) """Undirected""" C_cc = largest_connected_submatrix(self.C, directed=False) assert_allclose(C_cc.toarray(), self.C_cc_undirected) """Undirected with user specified lcc""" C_cc = largest_connected_submatrix(self.C, lcc=np.array([0, 1]), directed=False) assert_allclose(C_cc.toarray(), self.C_cc_undirected[0:2, 0:2])
def setUp(self): """Store state of the rng""" self.state = np.random.mtrand.get_state() """Reseed the rng to enforce 'deterministic' behavior""" np.random.mtrand.seed(42) """Meta-stable birth-death chain""" b = 2 q = np.zeros(7) p = np.zeros(7) q[1:] = 0.5 p[0:-1] = 0.5 q[2] = 1.0 - 10**(-b) q[4] = 10**(-b) p[2] = 10**(-b) p[4] = 1.0 - 10**(-b) bdc = BirthDeathChain(q, p) P = bdc.transition_matrix() self.dtraj = generate_traj(P, 10000, start=0) self.tau = 1 """Estimate MSM""" self.C_MSM = count_matrix(self.dtraj, self.tau, sliding=True) self.lcc_MSM = largest_connected_set(self.C_MSM) self.Ccc_MSM = largest_connected_submatrix(self.C_MSM, lcc=self.lcc_MSM) self.P_MSM = transition_matrix(self.Ccc_MSM, reversible=True) self.mu_MSM = stationary_distribution(self.P_MSM) self.k = 3 self.ts = timescales(self.P_MSM, k=self.k, tau=self.tau)
def setUpClass(cls) -> None: """Store state of the rng""" cls.state = np.random.mtrand.get_state() """Reseed the rng to enforce 'deterministic' behavior""" np.random.mtrand.seed(42) """Meta-stable birth-death chain""" b = 2 q = np.zeros(7) p = np.zeros(7) q[1:] = 0.5 p[0:-1] = 0.5 q[2] = 1.0 - 10 ** (-b) q[4] = 10 ** (-b) p[2] = 10 ** (-b) p[4] = 1.0 - 10 ** (-b) bdc = BirthDeathChain(q, p) P = bdc.transition_matrix() cls.dtraj = generate_traj(P, 10000, start=0) cls.tau = 1 """Estimate MSM""" import inspect argspec = inspect.getfullargspec(MaximumLikelihoodMSM) default_maxerr = argspec.defaults[argspec.args.index('maxerr') - 1] cls.C_MSM = msmest.count_matrix(cls.dtraj, cls.tau, sliding=True) cls.lcc_MSM = msmest.largest_connected_set(cls.C_MSM) cls.Ccc_MSM = msmest.largest_connected_submatrix(cls.C_MSM, lcc=cls.lcc_MSM) cls.P_MSM = msmest.transition_matrix(cls.Ccc_MSM, reversible=True, maxerr=default_maxerr) cls.mu_MSM = msmana.stationary_distribution(cls.P_MSM) cls.k = 3 cls.ts = msmana.timescales(cls.P_MSM, k=cls.k, tau=cls.tau)
def equilibrium_transition_matrix(Xi, omega, sigma, reversible=True, return_lcc=True): """ Compute equilibrium transition matrix from OOM components: Parameters ---------- Xi : ndarray(M, N, M) matrix of set-observable operators omega: ndarray(M,) information state vector of OOM sigma : ndarray(M,) evaluator of OOM reversible : bool, optional, default=True symmetrize corrected count matrix in order to obtain a reversible transition matrix. return_lcc: bool, optional, default=True return indices of largest connected set. Returns ------- Tt_Eq : ndarray(N, N) equilibrium transition matrix lcc : ndarray(M,) the largest connected set of the transition matrix. """ import msmtools.estimation as me # Compute equilibrium transition matrix: Ct_Eq = np.einsum('j,jkl,lmn,n->km', omega, Xi, Xi, sigma) # Remove negative entries: Ct_Eq[Ct_Eq < 0.0] = 0.0 # Compute transition matrix after symmetrization: pi_r = np.sum(Ct_Eq, axis=1) if reversible: pi_c = np.sum(Ct_Eq, axis=0) pi_sym = pi_r + pi_c # Avoid zero row-sums. States with zero row-sums will be eliminated by active set update. ind0 = np.where(pi_sym == 0.0)[0] pi_sym[ind0] = 1.0 Tt_Eq = (Ct_Eq + Ct_Eq.T) / pi_sym[:, None] else: # Avoid zero row-sums. States with zero row-sums will be eliminated by active set update. ind0 = np.where(pi_r == 0.0)[0] pi_r[ind0] = 1.0 Tt_Eq = Ct_Eq / pi_r[:, None] # Perform active set update: lcc = me.largest_connected_set(Tt_Eq) Tt_Eq = me.largest_connected_submatrix(Tt_Eq, lcc=lcc) if return_lcc: return Tt_Eq, lcc else: return Tt_Eq
def trim_Cmat( Cmat, lcc, ID ): minsamp = ID.trimfrac * np.sum(Cmat, dtype=float) / float(lcc.size) nrem = 0 for i in range(0,lcc.size): shift = i - nrem if ( np.sum(Cmat[shift], dtype=float) < minsamp ): # trim from matrix and bins Cmat = np.delete(Cmat, (shift), axis=0) Cmat = np.delete(Cmat, (shift), axis=1) lcc = np.delete(lcc, (shift)) nrem += 1 # reensure that the trimmed matrix is connected! lcc_tmp = largest_connected_set(Cmat, directed=True) Cmat_cc = largest_connected_submatrix(Cmat, directed=True, lcc=lcc_tmp) lcc = lcc[lcc_tmp] return Cmat_cc, lcc
def oom_components(Ct, C2t, rank_ind=None, lcc=None, tol_one=1e-2): """ Compute OOM components and eigenvalues from count matrices: Parameters ---------- Ct : ndarray(N, N) count matrix from data C2t : sparse csc-matrix (N*N, N) two-step count matrix from data for all states, columns enumerate intermediate steps. rank_ind : ndarray(N, dtype=bool), optional, default=None indicates which singular values are accepted. By default, all non- zero singular values are accepted. lcc : ndarray(N,), optional, default=None largest connected set of the count-matrix. Two step count matrix will be reduced to this set. tol_one : float, optional, default=1e-2 keep eigenvalues of absolute value less or equal 1+tol_one. Returns ------- Xi : ndarray(M, N, M) matrix of set-observable operators omega: ndarray(M,) information state vector of OOM sigma : ndarray(M,) evaluator of OOM l : ndarray(M,) eigenvalues from OOM """ # Decompose count matrix by SVD: if lcc is not None: Ct_svd = me.largest_connected_submatrix(Ct, lcc=lcc) N1 = Ct.shape[0] else: Ct_svd = Ct V, s, W = scl.svd(Ct_svd, full_matrices=False) # Make rank decision: if rank_ind is None: ind = (s >= np.finfo(float).eps) V = V[:, rank_ind] s = s[rank_ind] W = W[rank_ind, :].T # Compute transformations: F1 = np.dot(V, np.diag(s**-0.5)) F2 = np.dot(W, np.diag(s**-0.5)) # Apply the transformations to C2t: N = Ct_svd.shape[0] M = F1.shape[1] Xi = np.zeros((M, N, M)) for n in range(N): if lcc is not None: C2t_n = C2t[:, lcc[n]] C2t_n = _reshape_sparse(C2t_n, (N1, N1)) C2t_n = me.largest_connected_submatrix(C2t_n, lcc=lcc) else: C2t_n = C2t[:, n] C2t_n = _reshape_sparse(C2t_n, (N, N)) Xi[:, n, :] = np.dot(F1.T, C2t_n.dot(F2)) # Compute sigma: c = np.sum(Ct_svd, axis=1) sigma = np.dot(F1.T, c) # Compute eigenvalues: Xi_S = np.sum(Xi, axis=1) l, R = scl.eig(Xi_S.T) # Restrict eigenvalues to reasonable range: ind = np.where( np.logical_and(np.abs(l) <= (1 + tol_one), np.real(l) >= 0.0))[0] l = l[ind] R = R[:, ind] # Sort and extract omega l, R = _sort_by_norm(l, R) omega = np.real(R[:, 0]) omega = omega / np.dot(omega, sigma) return Xi, omega, sigma, l
def setUp(self): """Store state of the rng""" self.state = np.random.mtrand.get_state() """Reseed the rng to enforce 'deterministic' behavior""" np.random.mtrand.seed(42) """Meta-stable birth-death chain""" b = 2 q = np.zeros(7) p = np.zeros(7) q[1:] = 0.5 p[0:-1] = 0.5 q[2] = 1.0 - 10 ** (-b) q[4] = 10 ** (-b) p[2] = 10 ** (-b) p[4] = 1.0 - 10 ** (-b) bdc = BirthDeathChain(q, p) P = bdc.transition_matrix() dtraj = generate_traj(P, 10000, start=0) tau = 1 """Estimate MSM""" MSM = estimate_markov_model(dtraj, tau) C_MSM = MSM.count_matrix_full lcc_MSM = MSM.largest_connected_set Ccc_MSM = MSM.count_matrix_active P_MSM = MSM.transition_matrix mu_MSM = MSM.stationary_distribution """Meta-stable sets""" A = [0, 1, 2] B = [4, 5, 6] w_MSM = np.zeros((2, mu_MSM.shape[0])) w_MSM[0, A] = mu_MSM[A] / mu_MSM[A].sum() w_MSM[1, B] = mu_MSM[B] / mu_MSM[B].sum() K = 10 P_MSM_dense = P_MSM p_MSM = np.zeros((K, 2)) w_MSM_k = 1.0 * w_MSM for k in range(1, K): w_MSM_k = np.dot(w_MSM_k, P_MSM_dense) p_MSM[k, 0] = w_MSM_k[0, A].sum() p_MSM[k, 1] = w_MSM_k[1, B].sum() """Assume that sets are equal, A(\tau)=A(k \tau) for all k""" w_MD = 1.0 * w_MSM p_MD = np.zeros((K, 2)) eps_MD = np.zeros((K, 2)) p_MSM[0, :] = 1.0 p_MD[0, :] = 1.0 eps_MD[0, :] = 0.0 for k in range(1, K): """Build MSM at lagtime k*tau""" C_MD = count_matrix(dtraj, k * tau, sliding=True) / (k * tau) lcc_MD = largest_connected_set(C_MD) Ccc_MD = largest_connected_submatrix(C_MD, lcc=lcc_MD) c_MD = Ccc_MD.sum(axis=1) P_MD = transition_matrix(Ccc_MD).toarray() w_MD_k = np.dot(w_MD, P_MD) """Set A""" prob_MD = w_MD_k[0, A].sum() c = c_MD[A].sum() p_MD[k, 0] = prob_MD eps_MD[k, 0] = np.sqrt(k * (prob_MD - prob_MD ** 2) / c) """Set B""" prob_MD = w_MD_k[1, B].sum() c = c_MD[B].sum() p_MD[k, 1] = prob_MD eps_MD[k, 1] = np.sqrt(k * (prob_MD - prob_MD ** 2) / c) """Input""" self.MSM = MSM self.K = K self.A = A self.B = B """Expected results""" self.p_MSM = p_MSM self.p_MD = p_MD self.eps_MD = eps_MD