Ejemplo n.º 1
0
    def test_with_almost_converged_stat_dist(self):
        """ test for #106 """
        from msmtools.analysis import committor, is_reversible
        from msmtools.flux import tpt, flux_matrix, to_netflux, ReactiveFlux

        T = np.array([[
            0.2576419223095193, 0.2254214623509954, 0.248270708174756,
            0.2686659071647294
        ],
                      [
                          0.2233847186210225, 0.2130434781715344,
                          0.2793477268264001, 0.284224076381043
                      ],
                      [
                          0.2118717275169231, 0.2405661227681972,
                          0.2943396213976011, 0.2532225283172787
                      ],
                      [
                          0.2328617711043517, 0.2485926610067547,
                          0.2571819311236834, 0.2613636367652102
                      ]])
        mu = np.array([
            0.2306979668517676, 0.2328013892993006, 0.2703312416016573,
            0.2661694022472743
        ])
        assert is_reversible(T)
        np.testing.assert_allclose(mu.dot(T), mu)
        np.testing.assert_equal(mu.dot(T), T.T.dot(mu))
        A = [0]
        B = [1]

        # forward committor
        qplus = committor(T, A, B, forward=True, mu=mu)
        # backward committor
        if is_reversible(T, mu=mu):
            qminus = 1.0 - qplus
        else:
            qminus = committor(T, A, B, forward=False, mu=mu)

        tpt_obj = tpt(T, A, B)
        tpt_obj.major_flux(1.0)
        # gross flux
        grossflux = flux_matrix(T, mu, qminus, qplus, netflux=False)
        # net flux
        netflux = to_netflux(grossflux)
        F = ReactiveFlux(A,
                         B,
                         netflux,
                         mu=mu,
                         qminus=qminus,
                         qplus=qplus,
                         gross_flux=grossflux)
        F.pathways(1.0)
Ejemplo n.º 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
Ejemplo n.º 3
0
 def test_transition_matrix(self):
     import msmtools.analysis as msmana
     for P in [
             self.hmsm_lag1.transition_matrix,
             self.hmsm_lag1.transition_matrix
     ]:
         assert msmana.is_transition_matrix(P)
         assert msmana.is_reversible(P)
Ejemplo n.º 4
0
 def test_transition_matrix(self):
     """Test example transition matrices.
     """
     Tij = testsystems.generate_transition_matrix(n_states=3, reversible=False)
     assert not is_reversible(Tij)
     Tij = testsystems.generate_transition_matrix(n_states=3, reversible=True)
     assert Tij.shape == (3, 3)
     assert is_transition_matrix(Tij)
Ejemplo n.º 5
0
 def test_transition_matrix(self):
     import msmtools.analysis as msmana
     for P in [
             self.hmm_lag1.transition_model.transition_matrix,
             self.hmm_lag10.transition_model.transition_matrix
     ]:
         np.testing.assert_(msmana.is_transition_matrix(P))
         np.testing.assert_(msmana.is_reversible(P))
Ejemplo n.º 6
0
 def _transition_matrix_samples(self, msm):
     Psamples = msm.sample_f('transition_matrix')
     # shape
     assert np.array_equal(np.shape(Psamples), (self.nsamples, self.nstates, self.nstates))
     # consistency
     import msmtools.analysis as msmana
     for P in Psamples:
         assert msmana.is_transition_matrix(P)
         assert msmana.is_reversible(P)
Ejemplo n.º 7
0
 def test_transition_matrix_obs(self):
     assert np.array_equal(self.hmsm_lag1.transition_matrix_obs().shape, (self.hmsm_lag1.nstates_obs,self.hmsm_lag1.nstates_obs))
     assert np.array_equal(self.hmsm_lag10.transition_matrix_obs().shape, (self.hmsm_lag10.nstates_obs,self.hmsm_lag10.nstates_obs))
     for T in [self.hmsm_lag1.transition_matrix_obs(),
               self.hmsm_lag1.transition_matrix_obs(k=2),
               self.hmsm_lag10.transition_matrix_obs(),
               self.hmsm_lag10.transition_matrix_obs(k=4)]:
         assert msmana.is_transition_matrix(T)
         assert msmana.is_reversible(T)
Ejemplo n.º 8
0
    def test_3state_prev(self):
        dtraj = np.array([0, 1, 2, 0, 3, 4])
        import msmtools.estimation as msmest
        for rev in [True, False]:
            hmm = initial_guess_discrete_from_data(dtraj, n_hidden_states=3, lagtime=1, reversible=rev)
            assert msmana.is_transition_matrix(hmm.transition_model.transition_matrix)
            if rev:
                assert msmana.is_reversible(hmm.transition_model.transition_matrix)
            assert np.allclose(hmm.output_probabilities.sum(axis=1), 1)

        for rev in [True, False]:
            C = TransitionCountEstimator(lagtime=1, count_mode="sliding").fit(dtraj).fetch_model().count_matrix
            C += msmest.prior_neighbor(C, 0.001)
            hmm = initial_guess_discrete_from_data(dtraj, n_hidden_states=3, lagtime=1, reversible=rev)
            np.testing.assert_(msmana.is_transition_matrix(hmm.transition_model.transition_matrix))
            if rev:
                np.testing.assert_(msmana.is_reversible(hmm.transition_model.transition_matrix))
            np.testing.assert_allclose(hmm.output_model.output_probabilities.sum(axis=1), 1.)
Ejemplo n.º 9
0
 def test_transition_matrix_samples(self):
     Psamples = self.sampled_hmm_lag10.transition_matrix_samples
     # shape
     assert np.array_equal(Psamples.shape, (self.nsamples, self.nstates, self.nstates))
     # consistency
     import msmtools.analysis as msmana
     for P in Psamples:
         assert msmana.is_transition_matrix(P)
         assert msmana.is_reversible(P)
Ejemplo n.º 10
0
 def test_transition_matrix_samples(self):
     Psamples = np.array([m.transition_matrix for m in self.bhmm])
     # shape
     assert np.array_equal(np.shape(Psamples), (self.n_samples, self.n_states, self.n_states))
     # consistency
     import msmtools.analysis as msmana
     for P in Psamples:
         assert msmana.is_transition_matrix(P)
         assert msmana.is_reversible(P)
Ejemplo n.º 11
0
 def test_3state_prev(self):
     import msmtools.analysis as msmana
     dtraj = np.array([0, 1, 2, 0, 3, 4])
     C = msmest.count_matrix(dtraj, 1).toarray()
     for rev in [True, False]:
         hmm = init_discrete_hmm(dtraj, 3, reversible=rev)
         assert msmana.is_transition_matrix(hmm.transition_matrix)
         if rev:
             assert msmana.is_reversible(hmm.transition_matrix)
         assert np.allclose(hmm.output_model.output_probabilities.sum(axis=1), 1)
Ejemplo n.º 12
0
 def test_rdl_decomposition(self):
     P = self.bdc.transition_matrix()
     assert is_reversible(P)
     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')
     assert Dn.dtype in (np.float32, np.float64)
     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)
Ejemplo n.º 13
0
 def test_discrete_6_3(self):
     # 4x4 transition matrix
     nstates = 3
     P = np.array([[0.90, 0.10, 0.00, 0.00, 0.00, 0.00],
                   [0.20, 0.79, 0.01, 0.00, 0.00, 0.00],
                   [0.00, 0.01, 0.84, 0.15, 0.00, 0.00],
                   [0.00, 0.00, 0.05, 0.94, 0.01, 0.00],
                   [0.00, 0.00, 0.00, 0.02, 0.78, 0.20],
                   [0.00, 0.00, 0.00, 0.00, 0.10, 0.90]])
     # generate realization
     import msmtools.generation as msmgen
     T = 10000
     dtrajs = [msmgen.generate_traj(P, T)]
     # estimate initial HMM with 2 states - should be identical to P
     hmm = initdisc.initial_model_discrete(dtrajs, nstates)
     # Test stochasticity and reversibility
     Tij = hmm.transition_matrix
     B = hmm.output_model.output_probabilities
     import msmtools.analysis as msmana
     msmana.is_transition_matrix(Tij)
     msmana.is_reversible(Tij)
     np.allclose(B.sum(axis=1), np.ones(B.shape[0]))
Ejemplo n.º 14
0
    def transition_matrix(self, T):
        # Check transition matrix.
        if mana.is_transition_matrix(T):
            if not mana.is_reversible(T):
                warnings.warn("The transition matrix is not reversible.")
            if not mana.is_connected(T):
                warnings.warn("The transition matrix is not connected.")

            self._transition_matrix = T

        else:
            warnings.warn(
                "Not a transition matrix. Has to be square and rows must sum to one."
            )
Ejemplo n.º 15
0
 def test_discrete_6_3(self):
     # 4x4 transition matrix
     nstates = 3
     P = np.array([[0.90, 0.10, 0.00, 0.00, 0.00, 0.00],
                   [0.20, 0.79, 0.01, 0.00, 0.00, 0.00],
                   [0.00, 0.01, 0.84, 0.15, 0.00, 0.00],
                   [0.00, 0.00, 0.05, 0.94, 0.01, 0.00],
                   [0.00, 0.00, 0.00, 0.02, 0.78, 0.20],
                   [0.00, 0.00, 0.00, 0.00, 0.10, 0.90]])
     # generate realization
     import msmtools.generation as msmgen
     T = 10000
     dtrajs = [msmgen.generate_traj(P, T)]
     C = msmest.count_matrix(dtrajs, 1).toarray()
     # estimate initial HMM with 2 states - should be identical to P
     hmm = init_discrete_hmm(dtrajs, nstates)
     # Test stochasticity and reversibility
     Tij = hmm.transition_matrix
     B = hmm.output_model.output_probabilities
     import msmtools.analysis as msmana
     msmana.is_transition_matrix(Tij)
     msmana.is_reversible(Tij)
     np.allclose(B.sum(axis=1), np.ones(B.shape[0]))
Ejemplo n.º 16
0
    def P(self, value):
        self._P = value
        import msmtools.analysis as msmana
        # check input
        if self._P is not None:
            if not msmana.is_transition_matrix(self._P, tol=1e-8):
                raise ValueError('T is not a transition matrix.')
            # set states
            self.nstates = _np.shape(self._P)[0]
            if self.reversible is None:
                self.reversible = msmana.is_reversible(self._P)

            from scipy.sparse import issparse
            self.sparse = issparse(self._P)
Ejemplo n.º 17
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
Ejemplo n.º 18
0
    def _transition_matrix(self, msm):
        P = msm.transition_matrix
        # should be ndarray by default
        # assert (isinstance(P, np.ndarray))
        assert (isinstance(P, np.ndarray) or isinstance(P, scipy.sparse.csr_matrix))
        # shape
        assert (np.all(P.shape == (msm.n_states, msm.n_states)))
        # test transition matrix properties
        import msmtools.analysis as msmana

        assert (msmana.is_transition_matrix(P))
        assert (msmana.is_connected(P))
        # REVERSIBLE
        if msm.reversible:
            assert (msmana.is_reversible(P))
Ejemplo n.º 19
0
 def _transition_matrix_samples(self, msm, given_pi):
     Psamples = [s.transition_matrix for s in msm.samples]
     # shape
     assert np.array_equal(np.shape(Psamples), (self.nsamples, self.n_states, self.n_states))
     # consistency
     import msmtools.analysis as msmana
     for P in Psamples:
         assert msmana.is_transition_matrix(P)
         try:
             assert msmana.is_reversible(P)
         except AssertionError:
             # re-do calculation msmtools just performed to get details
             from msmtools.analysis import stationary_distribution
             mu = stationary_distribution(P)
             X = mu[:, np.newaxis] * P
             np.testing.assert_allclose(X, np.transpose(X), atol=1e-12,
                                        err_msg="P not reversible, given_pi={}".format(given_pi))
Ejemplo n.º 20
0
    def transition_matrix(self, T):
        """Set transition matrix

        Parameters
        ----------
        T : 2D numpy.ndarray.
            Transition matrix. Should be row stochastic and ergodic.
        """
        # Check transition matrix.
        if mana.is_transition_matrix(T):
            if not mana.is_reversible(T):
                warnings.warn("The transition matrix is not reversible.")
            if not mana.is_connected(T):
                warnings.warn("The transition matrix is not connected.")
        else:
            warnings.warn(
                "Not a transition matrix. Has to be square and rows must sum to one."
            )

        self._transition_matrix = T
Ejemplo n.º 21
0
 def test_discrete_6_3(self):
     # 4x4 transition matrix
     n_states = 3
     P = np.array([[0.90, 0.10, 0.00, 0.00, 0.00, 0.00],
                   [0.20, 0.79, 0.01, 0.00, 0.00, 0.00],
                   [0.00, 0.01, 0.84, 0.15, 0.00, 0.00],
                   [0.00, 0.00, 0.05, 0.94, 0.01, 0.00],
                   [0.00, 0.00, 0.00, 0.02, 0.78, 0.20],
                   [0.00, 0.00, 0.00, 0.00, 0.10, 0.90]])
     # generate realization
     T = 10000
     dtrajs = [MarkovStateModel(P).simulate(T)]
     # estimate initial HMM with 2 states - should be identical to P
     hmm = initial_guess_discrete_from_data(dtrajs, n_states, 1)
     # Test stochasticity and reversibility
     Tij = hmm.transition_model.transition_matrix
     B = hmm.output_model.output_probabilities
     np.testing.assert_(msmana.is_transition_matrix(Tij))
     np.testing.assert_(msmana.is_reversible(Tij))
     np.testing.assert_allclose(B.sum(axis=1), np.ones(B.shape[0]))
Ejemplo n.º 22
0
 def test_is_reversible(self):
     self.assertTrue(is_reversible(self.T, tol=self.tol), 'matrix should be reversible')
Ejemplo n.º 23
0
 def test_transition_matrix(self):
     for P in [self.hmsm_lag1.transition_matrix, self.hmsm_lag1.transition_matrix]:
         assert msmana.is_transition_matrix(P)
         assert msmana.is_reversible(P)
Ejemplo n.º 24
0
def _pcca_connected(P, n, return_rot=False):
    """
    PCCA+ spectral clustering method with optimized memberships [1]_

    Clusters the first n_cluster eigenvectors of a transition matrix in order to cluster the states.
    This function assumes that the transition matrix is fully connected.

    Parameters
    ----------
    P : ndarray (n,n)
        Transition matrix.

    n : int
        Number of clusters to group to.

    Returns
    -------
    chi by default, or (chi,rot) if return_rot = True

    chi : ndarray (n x m)
        A matrix containing the probability or membership of each state to be assigned to each cluster.
        The rows sum to 1.

    rot_mat : ndarray (m x m)
        A rotation matrix that rotates the dominant eigenvectors to yield the PCCA memberships, i.e.:
        chi = np.dot(evec, rot_matrix

    References
    ----------
    [1] S. Roeblitz and M. Weber, Fuzzy spectral clustering by PCCA+:
        application to Markov state models and data classification.
        Adv Data Anal Classif 7, 147-179 (2013).

    """

    # test connectivity
    from msmtools.estimation import connected_sets

    labels = connected_sets(P)
    n_components = len(
        labels
    )  # (n_components, labels) = connected_components(P, connection='strong')
    if (n_components > 1):
        raise ValueError(
            "Transition matrix is disconnected. Cannot use pcca_connected.")

    from msmtools.analysis import stationary_distribution

    pi = stationary_distribution(P)
    # print "statdist = ",pi

    from msmtools.analysis import is_reversible

    if not is_reversible(P, mu=pi):
        raise ValueError(
            "Transition matrix does not fulfill detailed balance. "
            "Make sure to call pcca with a reversible transition matrix estimate"
        )
    # TODO: Susanna mentioned that she has a potential fix for nonreversible matrices by replacing each complex conjugate
    #      pair by the real and imaginary components of one of the two vectors. We could use this but would then need to
    #      orthonormalize all eigenvectors e.g. using Gram-Schmidt orthonormalization. Currently there is no theoretical
    #      foundation for this, so I'll skip it for now.

    # right eigenvectors, ordered
    from msmtools.analysis import eigenvectors

    evecs = eigenvectors(P, n)

    # orthonormalize
    for i in range(n):
        evecs[:, i] /= math.sqrt(np.dot(evecs[:, i] * pi, evecs[:, i]))
    # make first eigenvector positive
    evecs[:, 0] = np.abs(evecs[:, 0])

    # Is there a significant complex component?
    if not np.alltrue(np.isreal(evecs)):
        warnings.warn(
            "The given transition matrix has complex eigenvectors, so it doesn't exactly fulfill detailed balance "
            +
            "forcing eigenvectors to be real and continuing. Be aware that this is not theoretically solid."
        )
    evecs = np.real(evecs)

    # create initial solution using PCCA+. This could have negative memberships
    (chi, rot_matrix) = _pcca_connected_isa(evecs, n)

    #print "initial chi = \n",chi

    # optimize the rotation matrix with PCCA++.
    rot_matrix = _opt_soft(evecs, rot_matrix, n)

    # These memberships should be nonnegative
    memberships = np.dot(evecs[:, :], rot_matrix)

    # We might still have numerical errors. Force memberships to be in [0,1]
    # print "memberships unnormalized: ",memberships
    memberships = np.maximum(0.0, memberships)
    memberships = np.minimum(1.0, memberships)
    # print "memberships unnormalized: ",memberships
    for i in range(0, np.shape(memberships)[0]):
        memberships[i] /= np.sum(memberships[i])

    # print "final chi = \n",chi

    return memberships
Ejemplo n.º 25
0
    def set_model_params(self,
                         P=None,
                         pi=None,
                         reversible=None,
                         dt_model='1 step',
                         neig=None):
        """ Call to set all basic model parameters.

        Sets or updates given model parameters. This argument list of this
        method must contain the full list of essential, or independent model
        parameters. It can additionally contain derived parameters, e.g. in
        order to save computational costs of re-computing them.

        Parameters
        ----------
        P : ndarray(n,n)
            transition matrix

        pi : ndarray(n), optional, default=None
            stationary distribution. Can be optionally given in case if it was
            already computed, e.g. by the estimator.

        reversible : bool, optional, default=None
            whether P is reversible with respect to its stationary distribution.
            If None (default), will be determined from P

        dt_model : str, optional, default='1 step'
            Description of the physical time corresponding to the model time
            step.  May be used by analysis algorithms such as plotting tools to
            pretty-print the axes. By default '1 step', i.e. there is no
            physical time unit. Specify by a number, whitespace and unit.
            Permitted units are (* is an arbitrary string):

            |  'fs',  'femtosecond*'
            |  'ps',  'picosecond*'
            |  'ns',  'nanosecond*'
            |  'us',  'microsecond*'
            |  'ms',  'millisecond*'
            |  's',   'second*'

        neig : int or None
            The number of eigenvalues / eigenvectors to be kept. If set to
            None, defaults will be used. For a dense MSM the default is all
            eigenvalues. For a sparse MSM the default is 10.

        Notes
        -----
        Explicitly define all independent model parameters in the argument
        list of this function (by mandatory or keyword arguments)

        """
        import msmtools.analysis as msmana
        # check input
        if P is not None:
            if not msmana.is_transition_matrix(P, tol=1e-8):
                raise ValueError('T is not a transition matrix.')

        # update all parameters
        self.update_model_params(P=P,
                                 pi=pi,
                                 reversible=reversible,
                                 dt_model=dt_model,
                                 neig=neig)
        # set ncv for consistency
        if not hasattr(self, 'ncv'):
            self.ncv = None
        # update derived quantities
        from pyemma.util.units import TimeUnit
        self._timeunit_model = TimeUnit(self.dt_model)

        # set P and derived quantities if available
        if P is not None:
            from scipy.sparse import issparse
            # set states
            self._nstates = np.shape(P)[0]
            if self.reversible is None:
                self.reversible = msmana.is_reversible(P)
            self.sparse = issparse(P)

            # set or correct eig param
            if neig is None:
                if self.sparse:
                    self.neig = 10
                else:
                    self.neig = self._nstates
Ejemplo n.º 26
0
def tpt(T, A, B, mu=None, qminus=None, qplus=None, rate_matrix=False):
    r""" Computes the A->B reactive flux using transition path theory (TPT)

    Parameters
    ----------
    T : (M, M) ndarray or scipy.sparse matrix
        Transition matrix (default) or Rate matrix (if rate_matrix=True)
    A : array_like
        List of integer state labels for set A
    B : array_like
        List of integer state labels for set B
    mu : (M,) ndarray (optional)
        Stationary vector
    qminus : (M,) ndarray (optional)
        Backward committor for A->B reaction
    qplus : (M,) ndarray (optional)
        Forward committor for A-> B reaction
    rate_matrix = False : boolean
        By default (False), T is a transition matrix.
        If set to True, T is a rate matrix.

    Returns
    -------
    tpt: msmtools.flux.ReactiveFlux object
        A python object containing the reactive A->B flux network
        and several additional quantities, such as stationary probability,
        committors and set definitions.

    Notes
    -----
    The central object used in transition path theory is
    the forward and backward comittor function.

    TPT (originally introduced in [1]) for continous systems has a
    discrete version outlined in [2]. Here, we use the transition
    matrix formulation described in [3].

    See also
    --------
    msmtools.analysis.committor, ReactiveFlux

    References
    ----------
    .. [1] W. E and E. Vanden-Eijnden.
        Towards a theory of transition paths.
        J. Stat. Phys. 123: 503-523 (2006)
    .. [2] P. Metzner, C. Schuette and E. Vanden-Eijnden.
        Transition Path Theory for Markov Jump Processes.
        Multiscale Model Simul 7: 1192-1219 (2009)
    .. [3] F. Noe, Ch. Schuette, E. Vanden-Eijnden, L. Reich and T. Weikl:
        Constructing the Full Ensemble of Folding Pathways from Short Off-Equilibrium Simulations.
        Proc. Natl. Acad. Sci. USA, 106, 19011-19016 (2009)

    """
    import msmtools.analysis as msmana

    if len(A) == 0 or len(B) == 0:
        raise ValueError('set A or B is empty')
    n = T.shape[0]
    if len(A) > n or len(B) > n or max(A) > n or max(B) > n:
        raise ValueError(
            'set A or B defines more states, than given transition matrix.')
    if (rate_matrix is False) and (not msmana.is_transition_matrix(T)):
        raise ValueError('given matrix T is not a transition matrix')
    if (rate_matrix is True):
        raise NotImplementedError(
            'TPT with rate matrix is not yet implemented - But it is very simple, so feel free to do it.'
        )

    # we can compute the following properties from either dense or sparse T
    # stationary dist
    if mu is None:
        mu = msmana.stationary_distribution(T)
    # forward committor
    if qplus is None:
        qplus = msmana.committor(T, A, B, forward=True)
    # backward committor
    if qminus is None:
        if msmana.is_reversible(T, mu=mu):
            qminus = 1.0 - qplus
        else:
            qminus = msmana.committor(T, A, B, forward=False, mu=mu)
    # gross flux
    grossflux = flux_matrix(T, mu, qminus, qplus, netflux=False)
    # net flux
    netflux = to_netflux(grossflux)

    # construct flux object
    from .reactive_flux import ReactiveFlux

    F = ReactiveFlux(A,
                     B,
                     netflux,
                     mu=mu,
                     qminus=qminus,
                     qplus=qplus,
                     gross_flux=grossflux)
    # done
    return F
Ejemplo n.º 27
0
 def test_transition_matrix(self):
     import msmtools.analysis as msmana
     for P in [self.hmm_lag1.transition_matrix, self.hmm_lag1.transition_matrix]:
         assert msmana.is_transition_matrix(P)
         assert msmana.is_reversible(P)
Ejemplo n.º 28
0
 def test_IsReversible(self):
     # create a reversible matrix
     self.assertTrue(is_reversible(self.T, self.mu),
                     "T should be reversible")