示例#1
0
文件: msm.py 项目: zzmjohn/PyEMMA
    def _compute_eigendecomposition(self, neig):
        """ Conducts the eigenvalue decomposition and stores k eigenvalues, left and right eigenvectors """
        from msmtools.analysis import rdl_decomposition

        if self.reversible:
            self._R, self._D, self._L = rdl_decomposition(
                self.transition_matrix,
                norm='reversible',
                k=neig,
                ncv=self.ncv)
            # everything must be real-valued
            self._R = self._R.real
            self._D = self._D.real
            self._L = self._L.real
        else:
            self._R, self._D, self._L = rdl_decomposition(
                self.transition_matrix, k=neig, norm='standard', ncv=self.ncv)
            # if the imaginary parts are zero, discard them.
            if _np.all(self._R.imag == 0):
                self._R = _np.real(self._R)
            if _np.all(self._D.imag == 0):
                self._D = _np.real(self._D)
            if _np.all(self._L.imag == 0):
                self._L = _np.real(self._L)

        self._eigenvalues = _np.diag(self._D)
示例#2
0
    def update(self, Tij, Pi=None):
        r""" Updates the transition matrix and recomputes all derived quantities """
        # EMMA imports
        from msmtools import analysis as msmana

        # save a copy of the transition matrix
        self._Tij = np.array(Tij)
        assert msmana.is_transition_matrix(
            self._Tij), 'Given transition matrix is not a stochastic matrix'
        assert self._Tij.shape[
            0] == self._nstates, 'Given transition matrix has unexpected number of states '

        # initial / stationary distribution
        if (Pi is not None):
            assert np.all(
                Pi >= 0
            ), 'Given initial distribution contains negative elements.'
            Pi = np.array(Pi) / np.sum(
                Pi)  # ensure normalization and make a copy

        if (self._stationary):
            pT = msmana.stationary_distribution(self._Tij)
            if Pi is None:  # stationary and no stationary distribution fixed, so computing it from trans. mat.
                self._Pi = pT
            else:  # stationary but stationary distribution is fixed, so the transition matrix must be consistent
                assert np.allclose(Pi, pT), 'Stationary HMM requested, but given distribution is not the ' \
                                            'stationary distribution of the given transition matrix.'
                self._Pi = Pi
        else:
            if Pi is None:  # no initial distribution given, so use stationary distribution anyway
                self._Pi = msmana.stationary_distribution(self._Tij)
            else:
                self._Pi = Pi

        # reversible
        if self._reversible:
            assert msmana.is_reversible(
                Tij
            ), 'Reversible HMM requested, but given transition matrix is not reversible.'

        # try to do eigendecomposition by default, because it's very cheap for hidden transition matrices
        from scipy.linalg import LinAlgError
        try:
            if self._reversible:
                self._R, self._D, self._L = msmana.rdl_decomposition(
                    self._Tij, norm='reversible')
                # everything must be real-valued
                self._R = self._R.real
                self._D = self._D.real
                self._L = self._L.real
            else:
                self._R, self._D, self._L = msmana.rdl_decomposition(
                    self._Tij, norm='standard')
            self._eigenvalues = np.diag(self._D)
            self._spectral_decomp_available = True
        except LinAlgError:
            logger().warn('Eigendecomposition failed for transition matrix\n' +
                          str(self._Tij) +
                          '\nspectral properties will not be available')
            self._spectral_decomp_available = False
示例#3
0
    def test_rdl_decomposition(self):
        P = self.bdc.transition_matrix()
        mu = self.bdc.stationary_distribution()

        """Non-reversible"""

        """k=None"""
        Rn, Dn, Ln = rdl_decomposition(P)
        Xn = np.dot(Ln, Rn)
        """Right-eigenvectors"""
        assert_allclose(np.dot(P, Rn), np.dot(Rn, Dn))
        """Left-eigenvectors"""
        assert_allclose(np.dot(Ln, P), np.dot(Dn, Ln))
        """Orthonormality"""
        assert_allclose(Xn, np.eye(self.dim))
        """Probability vector"""
        assert_allclose(np.sum(Ln[0, :]), 1.0)

        """k is not None"""
        Rn, Dn, Ln = rdl_decomposition(P, k=self.k)
        Xn = np.dot(Ln, Rn)
        """Right-eigenvectors"""
        assert_allclose(np.dot(P, Rn), np.dot(Rn, Dn))
        """Left-eigenvectors"""
        assert_allclose(np.dot(Ln, P), np.dot(Dn, Ln))
        """Orthonormality"""
        assert_allclose(Xn, np.eye(self.k))
        """Probability vector"""
        assert_allclose(np.sum(Ln[0, :]), 1.0)

        """Reversible"""

        """k=None"""
        Rn, Dn, Ln = rdl_decomposition(P, norm='reversible')
        Xn = np.dot(Ln, Rn)
        """Right-eigenvectors"""
        assert_allclose(np.dot(P, Rn), np.dot(Rn, Dn))
        """Left-eigenvectors"""
        assert_allclose(np.dot(Ln, P), np.dot(Dn, Ln))
        """Orthonormality"""
        assert_allclose(Xn, np.eye(self.dim))
        """Probability vector"""
        assert_allclose(np.sum(Ln[0, :]), 1.0)
        """Reversibility"""
        assert_allclose(Ln.transpose(), mu[:, np.newaxis] * Rn)

        """k is not None"""
        Rn, Dn, Ln = rdl_decomposition(P, norm='reversible', k=self.k)
        Xn = np.dot(Ln, Rn)
        """Right-eigenvectors"""
        assert_allclose(np.dot(P, Rn), np.dot(Rn, Dn))
        """Left-eigenvectors"""
        assert_allclose(np.dot(Ln, P), np.dot(Dn, Ln))
        """Orthonormality"""
        assert_allclose(Xn, np.eye(self.k))
        """Probability vector"""
        assert_allclose(np.sum(Ln[0, :]), 1.0)
        """Reversibility"""
        assert_allclose(Ln.transpose(), mu[:, np.newaxis] * Rn)
示例#4
0
    def update(self, Tij, Pi=None):
        r""" Updates the transition matrix and recomputes all derived quantities """
        # EMMA imports
        from msmtools import analysis as msmana

        # save a copy of the transition matrix
        self._Tij = np.array(Tij)
        assert msmana.is_transition_matrix(self._Tij), 'Given transition matrix is not a stochastic matrix'
        assert self._Tij.shape[0] == self._nstates, 'Given transition matrix has unexpected number of states '

        # initial / stationary distribution
        if (Pi is not None):
            assert np.all(Pi >= 0), 'Given initial distribution contains negative elements.'
            Pi = np.array(Pi) / np.sum(Pi) # ensure normalization and make a copy

        if (self._stationary):
            pT = msmana.stationary_distribution(self._Tij)
            if Pi is None: # stationary and no stationary distribution fixed, so computing it from trans. mat.
                self._Pi = pT
            else: # stationary but stationary distribution is fixed, so the transition matrix must be consistent
                assert np.allclose(Pi, pT), 'Stationary HMM requested, but given distribution is not the ' \
                                            'stationary distribution of the given transition matrix.'
                self._Pi = Pi
        else:
            if Pi is None: # no initial distribution given, so use stationary distribution anyway
                self._Pi = msmana.stationary_distribution(self._Tij)
            else:
                self._Pi = Pi

        # reversible
        if self._reversible:
            assert msmana.is_reversible(Tij), 'Reversible HMM requested, but given transition matrix is not reversible.'

        # try to do eigendecomposition by default, because it's very cheap for hidden transition matrices
        from scipy.linalg import LinAlgError
        try:
            if self._reversible:
                self._R, self._D, self._L = msmana.rdl_decomposition(self._Tij, norm='reversible')
                # everything must be real-valued
                self._R = self._R.real
                self._D = self._D.real
                self._L = self._L.real
            else:
                self._R, self._D, self._L = msmana.rdl_decomposition(self._Tij, norm='standard')
            self._eigenvalues = np.diag(self._D)
            self._spectral_decomp_available = True
        except LinAlgError:
            logger().warn('Eigendecomposition failed for transition matrix\n'+str(self._Tij)+
                          '\nspectral properties will not be available')
            self._spectral_decomp_available = False
示例#5
0
    def _compute_eigendecomposition(self, neig):
        """ Conducts the eigenvalue decomposition and stores k eigenvalues, left and right eigenvectors """
        from msmtools.analysis import rdl_decomposition

        if self.reversible:
            self._R, self._D, self._L = rdl_decomposition(self.transition_matrix, norm='reversible',
                                                          k=neig, ncv=self.ncv)
            # everything must be real-valued
            self._R = self._R.real
            self._D = self._D.real
            self._L = self._L.real
        else:
            self._R, self._D, self._L = rdl_decomposition(self.transition_matrix, k=neig, norm='standard', ncv=self.ncv)
        self._eigenvalues = np.diag(self._D)
示例#6
0
    def setUp(self):
        self.k = 4

        p = np.zeros(10)
        q = np.zeros(10)
        p[0:-1] = 0.5
        q[1:] = 0.5
        p[4] = 0.01
        q[6] = 0.1

        self.bdc = BirthDeathChain(q, p)

        self.mu = self.bdc.stationary_distribution()
        self.T = self.bdc.transition_matrix_sparse()
        """Test matrix-vector product against spectral decomposition"""
        R, D, L = rdl_decomposition(self.T, k=self.k)
        self.L = L
        self.R = R
        self.ts = timescales(self.T, k=self.k)
        self.times = np.array([1, 5, 10, 20, 100])

        ev = np.diagonal(D)
        self.ev_t = ev[np.newaxis, :]**self.times[:, np.newaxis]
        """Observable"""
        obs1 = np.zeros(10)
        obs1[0] = 1
        obs1[1] = 1
        self.obs = obs1
        """Initial distribution"""
        w0 = np.zeros(10)
        w0[0:4] = 0.25
        self.p0 = w0
示例#7
0
    def setUp(self):
        self.k = 4

        p = np.zeros(10)
        q = np.zeros(10)
        p[0:-1] = 0.5
        q[1:] = 0.5
        p[4] = 0.01
        q[6] = 0.1

        self.bdc = BirthDeathChain(q, p)

        self.mu = self.bdc.stationary_distribution()
        self.T = self.bdc.transition_matrix_sparse()
        R, D, L = rdl_decomposition(self.T, k=self.k)
        self.L = L
        self.R = R
        self.ts = timescales(self.T, k=self.k)
        self.times = np.array([1, 5, 10, 20, 100])

        ev = np.diagonal(D)
        self.ev_t = ev[np.newaxis, :]**self.times[:, np.newaxis]

        obs1 = np.zeros(10)
        obs1[0] = 1
        obs1[1] = 1
        obs2 = np.zeros(10)
        obs2[8] = 1
        obs2[9] = 1

        self.obs1 = obs1
        self.obs2 = obs2
        self.one_vec = np.ones(10)
示例#8
0
def rdl_decomposition(P, reversible=True):
    # TODO: this treatment is probably not meaningful for weakly connected matrices.
    import msmtools.estimation as msmest
    import msmtools.analysis as msmana
    # output matrices
    n = np.shape(P)[0]
    if reversible:
        dtype = np.float64
        norm = 'reversible'
    else:
        dtype = complex
        norm = 'standard'
    R = np.zeros((n, n), dtype=dtype)
    D = np.zeros((n, n), dtype=dtype)
    L = np.zeros((n, n), dtype=dtype)
    # treat each strongly connected set separately
    S = msmest.connected_sets(P)
    for s in S:
        indices = np.ix_(s, s)
        if len(s) > 1:
            right_eigvec, eigval_diag, left_eigvec = msmana.rdl_decomposition(
                P[s, :][:, s], norm=norm)
            # write to full
            R[indices] = right_eigvec
            D[indices] = eigval_diag
            L[indices] = left_eigvec
        else:  # just one element. Write 1's
            R[indices] = 1
            D[indices] = 1
            L[indices] = 1
    # done
    return R, D, L
示例#9
0
def rdl_decomposition(P, reversible=True):
    # TODO: this treatment is probably not meaningful for weakly connected matrices.
    import msmtools.estimation as msmest
    import msmtools.analysis as msmana
    # output matrices
    n = np.shape(P)[0]
    if reversible:
        dtype = np.float64
    else:
        dtype = complex
    R = np.zeros((n, n), dtype=dtype)
    D = np.zeros((n, n), dtype=dtype)
    L = np.zeros((n, n), dtype=dtype)
    # treat each strongly connected set separately
    S = msmest.connected_sets(P)
    for s in S:
        I = np.ix_(s, s)
        if len(s) > 1:
            if reversible:
                r, d, l = msmana.rdl_decomposition(P[s, :][:, s],
                                                   norm='reversible')
                # everything must be real-valued - this should rather be handled by msmtools
                R[I] = r.real
                D[I] = d.real
                L[I] = l.real
            else:
                r, d, l = msmana.rdl_decomposition(P[s, :][:, s],
                                                   norm='standard')
                # write to full
                R[I] = r
                D[I] = d
                L[I] = l
        else:  # just one element. Write 1's
            R[I] = 1
            D[I] = 1
            L[I] = 1
    # done
    return R, D, L
示例#10
0
def rdl_decomposition(P, reversible=True):
    # TODO: this treatment is probably not meaningful for weakly connected matrices.
    import msmtools.estimation as msmest
    import msmtools.analysis as msmana
    # output matrices
    n = np.shape(P)[0]
    if reversible:
        dtype = np.float64
    else:
        dtype = complex
    R = np.zeros((n, n), dtype=dtype)
    D = np.zeros((n, n), dtype=dtype)
    L = np.zeros((n, n), dtype=dtype)
    # treat each strongly connected set separately
    S = msmest.connected_sets(P)
    for s in S:
        I = np.ix_(s, s)
        if len(s) > 1:
            if reversible:
                r, d, l = msmana.rdl_decomposition(P[s, :][:, s], norm='reversible')
                # everything must be real-valued - this should rather be handled by msmtools
                R[I] = r.real
                D[I] = d.real
                L[I] = l.real
            else:
                r, d, l = msmana.rdl_decomposition(P[s, :][:, s], norm='standard')
                # write to full
                R[I] = r
                D[I] = d
                L[I] = l
        else:  # just one element. Write 1's
            R[I] = 1
            D[I] = 1
            L[I] = 1
    # done
    return R, D, L
示例#11
0
    def setUp(self):
        self.k = 4

        p = np.zeros(10)
        q = np.zeros(10)
        p[0:-1] = 0.5
        q[1:] = 0.5
        p[4] = 0.01
        q[6] = 0.1

        self.bdc = BirthDeathChain(q, p)

        self.mu = self.bdc.stationary_distribution()
        self.T = self.bdc.transition_matrix_sparse()
        R, D, L = rdl_decomposition(self.T, k=self.k)
        self.L = L
        self.R = R
        self.ts = timescales(self.T, k=self.k)
        self.times = np.array([1, 5, 10, 20])

        ev = np.diagonal(D)
        self.ev_t = ev[np.newaxis, :] ** self.times[:, np.newaxis]

        self.tau = 7.5

        """Observables"""
        obs1 = np.zeros(10)
        obs1[0] = 1
        obs1[1] = 1
        obs2 = np.zeros(10)
        obs2[8] = 1
        obs2[9] = 1

        self.obs1 = obs1
        self.obs2 = obs2

        """Initial vector for relaxation"""
        w0 = np.zeros(10)
        w0[0:4] = 0.25
        self.p0 = w0
示例#12
0
    def test_rdl_decomposition_rev(self):
        P = self.bdc.transition_matrix_sparse()
        mu = self.bdc.stationary_distribution()
        """Non-reversible"""
        """k=None"""
        with self.assertRaises(ValueError):
            Rn, Dn, Ln = rdl_decomposition(P, reversible=True)
        """norm='standard'"""
        Rn, Dn, Ln = rdl_decomposition(P,
                                       k=self.k,
                                       reversible=True,
                                       norm='standard')
        Xn = np.dot(Ln, Rn)
        """Right-eigenvectors"""
        assert_allclose(P.dot(Rn), np.dot(Rn, Dn))
        """Left-eigenvectors"""
        assert_allclose(P.transpose().dot(Ln.transpose()).transpose(),
                        np.dot(Dn, Ln))
        """Orthonormality"""
        assert_allclose(Xn, np.eye(self.k))
        """Probability vector"""
        assert_allclose(np.sum(Ln[0, :]), 1.0)
        """Standard l2-normalization of right eigenvectors except dominant one"""
        Yn = np.dot(Rn.T, Rn)
        assert_allclose(np.diag(Yn)[1:], 1.0)
        """ncv is not None"""
        Rn, Dn, Ln = rdl_decomposition(P,
                                       k=self.k,
                                       reversible=True,
                                       norm='standard',
                                       ncv=self.ncv)
        Xn = np.dot(Ln, Rn)
        """Right-eigenvectors"""
        assert_allclose(P.dot(Rn), np.dot(Rn, Dn))
        """Left-eigenvectors"""
        assert_allclose(P.transpose().dot(Ln.transpose()).transpose(),
                        np.dot(Dn, Ln))
        """Orthonormality"""
        assert_allclose(Xn, np.eye(self.k))
        """Probability vector"""
        assert_allclose(np.sum(Ln[0, :]), 1.0)
        """Standard l2-normalization of right eigenvectors except dominant one"""
        Yn = np.dot(Rn.T, Rn)
        assert_allclose(np.diag(Yn)[1:], 1.0)
        """norm='reversible'"""
        Rn, Dn, Ln = rdl_decomposition(P,
                                       reversible=True,
                                       norm='reversible',
                                       k=self.k)
        Xn = np.dot(Ln, Rn)
        """Right-eigenvectors"""
        assert_allclose(P.dot(Rn), np.dot(Rn, Dn))
        """Left-eigenvectors"""
        assert_allclose(P.transpose().dot(Ln.transpose()).transpose(),
                        np.dot(Dn, Ln))
        """Orthonormality"""
        assert_allclose(Xn, np.eye(self.k))
        """Probability vector"""
        assert_allclose(np.sum(Ln[0, :]), 1.0)
        """Reversibility"""
        assert_allclose(Ln.transpose(), mu[:, np.newaxis] * Rn)

        Rn, Dn, Ln = rdl_decomposition(P,
                                       reversible=True,
                                       norm='reversible',
                                       k=self.k,
                                       ncv=self.ncv)
        Xn = np.dot(Ln, Rn)
        """Right-eigenvectors"""
        assert_allclose(P.dot(Rn), np.dot(Rn, Dn))
        """Left-eigenvectors"""
        assert_allclose(P.transpose().dot(Ln.transpose()).transpose(),
                        np.dot(Dn, Ln))
        """Orthonormality"""
        assert_allclose(Xn, np.eye(self.k))
        """Probability vector"""
        assert_allclose(np.sum(Ln[0, :]), 1.0)
        """Reversibility"""
        assert_allclose(Ln.transpose(), mu[:, np.newaxis] * Rn)
        """mu is not None"""
        """norm='standard'"""
        Rn, Dn, Ln = rdl_decomposition(P,
                                       k=self.k,
                                       reversible=True,
                                       norm='standard',
                                       mu=mu)
        Xn = np.dot(Ln, Rn)
        """Right-eigenvectors"""
        assert_allclose(P.dot(Rn), np.dot(Rn, Dn))
        """Left-eigenvectors"""
        assert_allclose(P.transpose().dot(Ln.transpose()).transpose(),
                        np.dot(Dn, Ln))
        """Orthonormality"""
        assert_allclose(Xn, np.eye(self.k))
        """Probability vector"""
        assert_allclose(np.sum(Ln[0, :]), 1.0)
        """Standard l2-normalization of right eigenvectors except dominant one"""
        Yn = np.dot(Rn.T, Rn)
        assert_allclose(np.diag(Yn)[1:], 1.0)
        """ncv is not None"""
        Rn, Dn, Ln = rdl_decomposition(P,
                                       k=self.k,
                                       reversible=True,
                                       norm='standard',
                                       ncv=self.ncv,
                                       mu=mu)
        Xn = np.dot(Ln, Rn)
        """Right-eigenvectors"""
        assert_allclose(P.dot(Rn), np.dot(Rn, Dn))
        """Left-eigenvectors"""
        assert_allclose(P.transpose().dot(Ln.transpose()).transpose(),
                        np.dot(Dn, Ln))
        """Orthonormality"""
        assert_allclose(Xn, np.eye(self.k))
        """Probability vector"""
        assert_allclose(np.sum(Ln[0, :]), 1.0)
        """Standard l2-normalization of right eigenvectors except dominant one"""
        Yn = np.dot(Rn.T, Rn)
        assert_allclose(np.diag(Yn)[1:], 1.0)
        """norm='reversible'"""
        Rn, Dn, Ln = rdl_decomposition(P,
                                       reversible=True,
                                       norm='reversible',
                                       k=self.k,
                                       mu=mu)
        Xn = np.dot(Ln, Rn)
        """Right-eigenvectors"""
        assert_allclose(P.dot(Rn), np.dot(Rn, Dn))
        """Left-eigenvectors"""
        assert_allclose(P.transpose().dot(Ln.transpose()).transpose(),
                        np.dot(Dn, Ln))
        """Orthonormality"""
        assert_allclose(Xn, np.eye(self.k))
        """Probability vector"""
        assert_allclose(np.sum(Ln[0, :]), 1.0)
        """Reversibility"""
        assert_allclose(Ln.transpose(), mu[:, np.newaxis] * Rn)

        Rn, Dn, Ln = rdl_decomposition(P,
                                       reversible=True,
                                       norm='reversible',
                                       k=self.k,
                                       ncv=self.ncv,
                                       mu=mu)
        Xn = np.dot(Ln, Rn)
        """Right-eigenvectors"""
        assert_allclose(P.dot(Rn), np.dot(Rn, Dn))
        """Left-eigenvectors"""
        assert_allclose(P.transpose().dot(Ln.transpose()).transpose(),
                        np.dot(Dn, Ln))
        """Orthonormality"""
        assert_allclose(Xn, np.eye(self.k))
        """Probability vector"""
        assert_allclose(np.sum(Ln[0, :]), 1.0)
        """Reversibility"""
        assert_allclose(Ln.transpose(), mu[:, np.newaxis] * Rn)
示例#13
0
 def test_rdl_decomposition(self):
     P = self.bdc.transition_matrix_sparse()
     mu = self.bdc.stationary_distribution()
     """Non-reversible"""
     """k=None"""
     with self.assertRaises(ValueError):
         Rn, Dn, Ln = rdl_decomposition(P)
     """k is not None"""
     Rn, Dn, Ln = rdl_decomposition(P, k=self.k)
     Xn = np.dot(Ln, Rn)
     """Right-eigenvectors"""
     assert_allclose(P.dot(Rn), np.dot(Rn, Dn))
     """Left-eigenvectors"""
     assert_allclose(P.transpose().dot(Ln.transpose()).transpose(),
                     np.dot(Dn, Ln))
     """Orthonormality"""
     assert_allclose(Xn, np.eye(self.k))
     """Probability vector"""
     assert_allclose(np.sum(Ln[0, :]), 1.0)
     """k is not None, ncv is not None"""
     Rn, Dn, Ln = rdl_decomposition(P, k=self.k, ncv=self.ncv)
     Xn = np.dot(Ln, Rn)
     """Right-eigenvectors"""
     assert_allclose(P.dot(Rn), np.dot(Rn, Dn))
     """Left-eigenvectors"""
     assert_allclose(P.transpose().dot(Ln.transpose()).transpose(),
                     np.dot(Dn, Ln))
     """Orthonormality"""
     assert_allclose(Xn, np.eye(self.k))
     """Probability vector"""
     assert_allclose(np.sum(Ln[0, :]), 1.0)
     """Reversible"""
     """k=None"""
     with self.assertRaises(ValueError):
         Rn, Dn, Ln = rdl_decomposition(P, norm='reversible')
     """k is not None"""
     Rn, Dn, Ln = rdl_decomposition(P, k=self.k, norm='reversible')
     Xn = np.dot(Ln, Rn)
     """Right-eigenvectors"""
     assert_allclose(P.dot(Rn), np.dot(Rn, Dn))
     """Left-eigenvectors"""
     assert_allclose(P.transpose().dot(Ln.transpose()).transpose(),
                     np.dot(Dn, Ln))
     """Orthonormality"""
     assert_allclose(Xn, np.eye(self.k))
     """Probability vector"""
     assert_allclose(np.sum(Ln[0, :]), 1.0)
     """Reversibility"""
     assert_allclose(Ln.transpose(), mu[:, np.newaxis] * Rn)
     """k is not None ncv is not None"""
     Rn, Dn, Ln = rdl_decomposition(P,
                                    k=self.k,
                                    norm='reversible',
                                    ncv=self.ncv)
     Xn = np.dot(Ln, Rn)
     """Right-eigenvectors"""
     assert_allclose(P.dot(Rn), np.dot(Rn, Dn))
     """Left-eigenvectors"""
     assert_allclose(P.transpose().dot(Ln.transpose()).transpose(),
                     np.dot(Dn, Ln))
     """Orthonormality"""
     assert_allclose(Xn, np.eye(self.k))
     """Probability vector"""
     assert_allclose(np.sum(Ln[0, :]), 1.0)
     """Reversibility"""
     assert_allclose(Ln.transpose(), mu[:, np.newaxis] * Rn)
示例#14
0
    def test_rdl_decomposition_rev(self):
        P = self.bdc.transition_matrix()
        mu = self.bdc.stationary_distribution()
        """norm='standard'"""
        """k=None"""
        Rn, Dn, Ln = rdl_decomposition(P, reversible=True, norm='standard')
        Xn = np.dot(Ln, Rn)
        """Right-eigenvectors"""
        assert_allclose(np.dot(P, Rn), np.dot(Rn, Dn))
        """Left-eigenvectors"""
        assert_allclose(np.dot(Ln, P), np.dot(Dn, Ln))
        """Orthonormality"""
        assert_allclose(Xn, np.eye(self.dim))
        """Probability vector"""
        assert_allclose(np.sum(Ln[0, :]), 1.0)
        """Standard l2-normalization of right eigenvectors except dominant one"""
        Yn = np.dot(Rn.T, Rn)
        assert_allclose(np.diag(Yn)[1:], 1.0)
        """k is not None"""
        Rn, Dn, Ln = rdl_decomposition(P,
                                       k=self.k,
                                       reversible=True,
                                       norm='standard')
        Xn = np.dot(Ln, Rn)
        """Right-eigenvectors"""
        assert_allclose(np.dot(P, Rn), np.dot(Rn, Dn))
        """Left-eigenvectors"""
        assert_allclose(np.dot(Ln, P), np.dot(Dn, Ln))
        """Orthonormality"""
        assert_allclose(Xn, np.eye(self.k))
        """Probability vector"""
        assert_allclose(np.sum(Ln[0, :]), 1.0)
        """Standard l2-normalization of right eigenvectors except dominant one"""
        Yn = np.dot(Rn.T, Rn)
        assert_allclose(np.diag(Yn)[1:], 1.0)
        """norm='reversible'"""
        """k=None"""
        Rn, Dn, Ln = rdl_decomposition(P, reversible=True, norm='reversible')

        Xn = np.dot(Ln, Rn)
        """Right-eigenvectors"""
        assert_allclose(np.dot(P, Rn), np.dot(Rn, Dn))
        """Left-eigenvectors"""
        assert_allclose(np.dot(Ln, P), np.dot(Dn, Ln))
        """Orthonormality"""
        assert_allclose(Xn, np.eye(self.dim))
        """Probability vector"""
        assert_allclose(np.sum(Ln[0, :]), 1.0)
        """Reversibility"""
        assert_allclose(Ln.transpose(), mu[:, np.newaxis] * Rn)
        """k is not None"""
        Rn, Dn, Ln = rdl_decomposition(P,
                                       reversible=True,
                                       norm='reversible',
                                       k=self.k)
        Xn = np.dot(Ln, Rn)
        """Right-eigenvectors"""
        assert_allclose(np.dot(P, Rn), np.dot(Rn, Dn))
        """Left-eigenvectors"""
        assert_allclose(np.dot(Ln, P), np.dot(Dn, Ln))
        """Orthonormality"""
        assert_allclose(Xn, np.eye(self.k))
        """Probability vector"""
        assert_allclose(np.sum(Ln[0, :]), 1.0)
        """Reversibility"""
        assert_allclose(Ln.transpose(), mu[:, np.newaxis] * Rn)
示例#15
0
def main(nEigenvectors,
         nRuns,
         m,
         outputFolder,
         plotEigenvectors,
         plotGMRQ,
         plotPMF,
         clusters,
         lagtimes,
         native,
         save_plots,
         showPlots,
         filtered,
         destFolder,
         resname,
         plotTransitions=True):
    minPos = get_min_Pos(native, resname)
    if save_plots and outputFolder is None:
        outputFolder = "plots_MSM"
    eigenPlots = os.path.join(outputFolder, "eigenvector_plots")
    GMRQPlots = os.path.join(outputFolder, "GMRQ_plots")
    PMFPlots = os.path.join(outputFolder, "PMF_plots")
    TransitionPlots = os.path.join(outputFolder, "transitions")
    if save_plots and not os.path.exists(outputFolder):
        os.makedirs(outputFolder)
    if filtered is not None:
        filter_str = "_filtered"
    else:
        filter_str = ""
    if plotEigenvectors and save_plots and not os.path.exists(eigenPlots):
        os.makedirs(eigenPlots)
    if plotGMRQ and save_plots and not os.path.exists(GMRQPlots):
        os.makedirs(GMRQPlots)
    if plotPMF and save_plots and not os.path.exists(PMFPlots):
        os.makedirs(PMFPlots)
    if plotTransitions and save_plots and not os.path.exists(TransitionPlots):
        os.makedirs(TransitionPlots)
    minPos = np.array(minPos)
    GMRQValues = {}
    print("Running from " + destFolder)
    if plotGMRQ:
        GMRQValues = []

    if not os.path.exists(os.path.join(destFolder, "eigenvectors")):
        os.makedirs(os.path.join(destFolder, "eigenvectors"))
    for i in range(nRuns):
        titleVar = "%s, run %d" % (destFolder, i)
        if plotGMRQ or plotEigenvectors:
            msm_object = utilities.readClusteringObject(
                os.path.join(destFolder, "MSM_object_%d.pkl" % i))
        if plotGMRQ:
            GMRQValues.append(np.sum(msm_object.eigenvalues()[:m]))
        if plotEigenvectors or plotPMF:
            clusters = np.loadtxt(
                os.path.join(destFolder, "clusterCenters_%d.dat" % i))
            distance = np.linalg.norm(clusters - minPos, axis=1)
            volume = np.loadtxt(
                os.path.join(destFolder, "volumeOfClusters_%d.dat" % i))
            print("Total volume for system %s , run %d" % (destFolder, i),
                  volume.sum())
            if filtered is not None:
                volume = volume[filtered]
                clusters = clusters[filtered]
                distance = distance[filtered]
        if plotEigenvectors:
            if clusters.size != msm_object.stationary_distribution.size:
                mat = computeDeltaG.reestimate_transition_matrix(
                    msm_object.count_matrix_full)
            else:
                mat = msm_object.transition_matrix
            _, _, L = rdl_decomposition(mat)
            figures = []
            axes = []
            for _ in range((nEigenvectors - 1) // 4 + 1):
                f, axarr = plt.subplots(2, 2, figsize=(12, 12))
                f.suptitle(titleVar)
                figures.append(f)
                axes.append(axarr)

            for j, row in enumerate(L[:nEigenvectors]):
                pdb_filename = os.path.join(destFolder, "eigenvectors",
                                            "eigen_%d_run_%d.pdb" % (j + 1, i))
                if j:
                    atomnames = utilities.getAtomNames(
                        utilities.sign(row, tol=1e-3))
                    utilities.write_PDB_clusters(clusters,
                                                 use_beta=False,
                                                 elements=atomnames,
                                                 title=pdb_filename)
                else:
                    utilities.write_PDB_clusters(np.vstack(
                        (clusters.T, row)).T,
                                                 use_beta=True,
                                                 elements=None,
                                                 title=pdb_filename)
                if filtered is not None:
                    row = row[filtered]
                np.savetxt(
                    os.path.join(
                        destFolder, "eigenvectors",
                        "eigen_%d_run_%d%s.dat" % (j + 1, i, filter_str)), row)
                axes[j // 4][(j // 2) % 2, j % 2].scatter(distance, row)
                axes[j // 4][(j // 2) % 2,
                             j % 2].set_xlabel("Distance to minimum")
                axes[j // 4][(j // 2) % 2,
                             j % 2].set_ylabel("Eigenvector %d" % (j + 1))
            if save_plots:
                for j, fg in enumerate(figures):
                    fg.savefig(
                        os.path.join(
                            eigenPlots, "eigenvector_%d_run_%d%s.png" %
                            (j + 1, i, filter_str)))
                plt.figure()
                plt.scatter(distance, L[0])
                plt.xlabel("Distance to minimum")
                plt.ylabel("Eigenvector 1")
                plt.savefig(
                    os.path.join(
                        eigenPlots,
                        "eigenvector_1_alone_run_%d%s.png" % (i, filter_str)))
        if plotPMF:
            data = np.loadtxt(os.path.join(destFolder, "pmf_xyzg_%d.dat" % i))
            g = data[:, -1]
            if filtered is not None:
                g = g[filtered]
            print("Clusters with less than 2 PMF:")
            print(" ".join(map(str, np.where(g < 2)[0])))
            print("")
            plt.figure()
            plt.title("%s" % (destFolder))
            plt.scatter(distance, g)
            plt.xlabel("Distance to minima")
            plt.ylabel("PMF")
            if save_plots:
                plt.savefig(
                    os.path.join(PMFPlots,
                                 "pmf_run_%d%s.png" % (i, filter_str)))
    if plotGMRQ:
        for t in GMRQValues:
            plt.figure()
            plt.title("%s" % (destFolder))
            plt.xlabel("Number of states")
            plt.ylabel("GMRQ")
            plt.boxplot(GMRQValues)
            if save_plots:
                plt.savefig(os.path.join(GMRQPlots, "GMRQ.png" % t))
    if plotTransitions:
        sasas = []
        for file in glob.glob("*/repor*"):
            sasas.extend(
                pd.read_csv(file, sep='    ',
                            engine='python')["sasaLig"].values)
        sasas = np.array(sasas)
        plt.figure()
        plt.title("%s" % (destFolder))
        plt.xlabel("SASA")
        plt.ylabel("Transition Counts")
        plt.hist(sasas, 50, alpha=0.75)
        if save_plots:
            plt.savefig(os.path.join(TransitionPlots, "transition_hist.png"))
    if showPlots and (plotEigenvectors or plotGMRQ or plotPMF):
        plt.show()
示例#16
0
def main(nEigenvectors, nRuns, m, outputFolder, plotEigenvectors, plotGMRQ,
         plotPMF, clusters, lagtimes, minPos, save_plots, showPlots, filtered,
         destFolder, sasa_col, path_to_report):
    if save_plots and outputFolder is None:
        outputFolder = "plots_MSM"
    if outputFolder is not None:
        eigenPlots = os.path.join(outputFolder, "eigenvector_plots")
        GMRQPlots = os.path.join(outputFolder, "GMRQ_plots")
        PMFPlots = os.path.join(outputFolder, "PMF_plots")
        if save_plots and not os.path.exists(outputFolder):
            os.makedirs(outputFolder)
    if filtered is not None:
        filter_str = "_filtered"
    else:
        filter_str = ""
    if plotEigenvectors and save_plots and not os.path.exists(eigenPlots):
        os.makedirs(eigenPlots)
    if plotGMRQ and save_plots and not os.path.exists(GMRQPlots):
        os.makedirs(GMRQPlots)
    if plotPMF and save_plots and not os.path.exists(PMFPlots):
        os.makedirs(PMFPlots)
    minPos = np.array(minPos)
    GMRQValues = {}
    print("Running from", destFolder)
    if plotGMRQ:
        GMRQValues = []

    if not os.path.exists(os.path.join(destFolder, "eigenvectors")):
        os.makedirs(os.path.join(destFolder, "eigenvectors"))
    for i in range(nRuns):
        if sasa_col is not None:
            representatives_files = os.path.join(
                destFolder,
                "representative_structures/representative_structures_%d.dat" %
                i)
            sasa = getSASAvalues(representatives_files, sasa_col,
                                 path_to_report)

        titleVar = "%s, run %d" % (destFolder, i)
        if plotGMRQ or plotEigenvectors:
            msm_object = utilities.readClusteringObject(
                os.path.join(destFolder, "MSM_object_%d.pkl" % i))
        if plotGMRQ:
            GMRQValues.append(np.sum(msm_object.eigenvalues()[:m]))
        if plotEigenvectors or plotPMF:
            clusters = np.loadtxt(
                os.path.join(destFolder, "clusterCenters_%d.dat" % i))
            distance = np.linalg.norm(clusters - minPos, axis=1)
            volume = np.loadtxt(
                os.path.join(destFolder, "volumeOfClusters_%d.dat" % i))
            print("Total volume for system %s , run %d" % (destFolder, i),
                  volume.sum())
            if filtered is not None:
                volume = volume[filtered]
                clusters = clusters[filtered]
                distance = distance[filtered]
                if sasa_col is not None:
                    sasa = sasa[filtered]
        if plotEigenvectors:
            if clusters.size != msm_object.stationary_distribution.size:
                mat = computeDeltaG.reestimate_transition_matrix(
                    msm_object.count_matrix_full)
            else:
                mat = msm_object.transition_matrix
            _, _, L = rdl_decomposition(mat)
            figures = []
            axes = []
            for _ in range((nEigenvectors - 1) // 4 + 1):
                f, axarr = plt.subplots(2, 2, figsize=(12, 12))
                f.suptitle(titleVar)
                figures.append(f)
                axes.append(axarr)

            for j, row in enumerate(L[:nEigenvectors]):
                pdb_filename = os.path.join(destFolder, "eigenvectors",
                                            "eigen_%d_run_%d.pdb" % (j + 1, i))
                if j:
                    atomnames = utilities.getAtomNames(
                        utilities.sign(row, tol=1e-3))
                    utilities.write_PDB_clusters(clusters,
                                                 use_beta=False,
                                                 elements=atomnames,
                                                 title=pdb_filename)
                else:
                    utilities.write_PDB_clusters(np.vstack(
                        (clusters.T, row)).T,
                                                 use_beta=True,
                                                 elements=None,
                                                 title=pdb_filename)
                if filtered is not None:
                    row = row[filtered]
                np.savetxt(
                    os.path.join(
                        destFolder, "eigenvectors",
                        "eigen_%d_run_%d%s.dat" % (j + 1, i, filter_str)), row)
                axes[j // 4][(j // 2) % 2, j % 2].scatter(distance, row)
                axes[j // 4][(j // 2) % 2,
                             j % 2].set_xlabel("Distance to minimum")
                axes[j // 4][(j // 2) % 2,
                             j % 2].set_ylabel("Eigenvector %d" % (j + 1))
            Q = msm_object.count_matrix_full.diagonal(
            ) / msm_object.count_matrix_full.sum()
            plt.figure()
            plt.scatter(distance, Q)
            plt.xlabel("Distance to minimum")
            plt.ylabel("Metastability")
            if save_plots:
                plt.savefig(
                    os.path.join(eigenPlots,
                                 "Q_run_%d%s.png" % (i, filter_str)))
            if save_plots:
                for j, fg in enumerate(figures):
                    fg.savefig(
                        os.path.join(
                            eigenPlots, "eigenvector_%d_run_%d%s.png" %
                            (j + 1, i, filter_str)))
                plt.figure()
                plt.scatter(distance, L[0])
                plt.xlabel("Distance to minimum")
                plt.ylabel("Eigenvector 1")
                plt.savefig(
                    os.path.join(
                        eigenPlots,
                        "eigenvector_1_alone_run_%d%s.png" % (i, filter_str)))
        if plotPMF:
            data = np.loadtxt(os.path.join(destFolder, "pmf_xyzg_%d.dat" % i))
            g = data[:, -1]
            annotations = ["Cluster %d" % i for i in range(g.size)]
            if filtered is not None:
                g = g[filtered]
                annotations = np.array(annotations)[filtered].tolist()
            print("Clusters with less than 2 PMF:")
            print(" ".join(map(str, np.where(g < 2)[0])))
            print("")
            fig_pmf, axarr = plt.subplots(2, 2, figsize=(12, 12))
            fig_pmf.suptitle(titleVar)
            sc1 = axarr[1, 0].scatter(distance, g)
            sc2 = axarr[0, 1].scatter(distance, volume)
            sc3 = axarr[0, 0].scatter(g, volume)
            axes = [axarr[0, 1], axarr[1, 0], axarr[0, 0]]
            scs = [sc2, sc1, sc3]
            if sasa_col is not None:
                axarr[1, 1].scatter(sasa, g)
            axarr[1, 0].set_xlabel("Distance to minima")
            axarr[1, 0].set_ylabel("PMF")
            axarr[0, 1].set_xlabel("Distance to minima")
            axarr[0, 1].set_ylabel("Volume")
            axarr[0, 0].set_xlabel("PMF")
            axarr[0, 0].set_ylabel("Volume")
            annot1 = axarr[1, 0].annotate("",
                                          xy=(0, 0),
                                          xytext=(20, 20),
                                          textcoords="offset points",
                                          bbox=dict(boxstyle="round", fc="w"),
                                          arrowprops=dict(arrowstyle="->"))
            annot1.set_visible(False)
            annot2 = axarr[0, 1].annotate("",
                                          xy=(0, 0),
                                          xytext=(20, 20),
                                          textcoords="offset points",
                                          bbox=dict(boxstyle="round", fc="w"),
                                          arrowprops=dict(arrowstyle="->"))
            annot2.set_visible(False)
            annot3 = axarr[0, 0].annotate("",
                                          xy=(0, 0),
                                          xytext=(20, 20),
                                          textcoords="offset points",
                                          bbox=dict(boxstyle="round", fc="w"),
                                          arrowprops=dict(arrowstyle="->"))
            annot3.set_visible(False)
            annot_list = [annot2, annot1, annot3]
            if sasa_col is not None:
                axarr[1, 1].set_xlabel("SASA")
                axarr[1, 1].set_ylabel("PMF")
            if save_plots:
                fig_pmf.savefig(
                    os.path.join(PMFPlots,
                                 "pmf_run_%d%s.png" % (i, filter_str)))
    if plotGMRQ:
        for t in GMRQValues:
            plt.figure()
            plt.title("%s" % (destFolder))
            plt.xlabel("Number of states")
            plt.ylabel("GMRQ")
            plt.boxplot(GMRQValues)
            if save_plots:
                plt.savefig(os.path.join(GMRQPlots, "GMRQ.png" % t))
    if showPlots and (plotEigenvectors or plotGMRQ or plotPMF):
        if plotPMFs:

            def update_annot(ind, sc, annot):
                """Update the information box of the selected point"""
                pos = sc.get_offsets()[ind["ind"][0]]
                annot.xy = pos
                annot.set_text(annotations[int(ind["ind"][0])])
                # annot.get_bbox_patch().set_facecolor(cmap(norm( z_values[ind["ind"][0]])))

            def hover(event):
                """Action to perform when hovering the mouse on a point"""
                # vis = any([annot.get_visible() for annot in annot_list])
                for i, ax_comp in enumerate(axes):
                    vis = annot_list[i].get_visible()
                    if event.inaxes == ax_comp:
                        for j in range(len(axes)):
                            if j != i:
                                annot_list[j].set_visible(False)
                        cont, ind = scs[i].contains(event)
                        if cont:
                            update_annot(ind, scs[i], annot_list[i])
                            annot_list[i].set_visible(True)
                            fig_pmf.canvas.draw_idle()
                        else:
                            if vis:
                                annot_list[i].set_visible(False)
                                fig_pmf.canvas.draw_idle()

            fig_pmf.canvas.mpl_connect("motion_notify_event", hover)
        plt.show()