Ejemplo n.º 1
0
def test_with_almost_converged_stat_dist(sparse_mode):
    """ test for https://github.com/markovmodel/msmtools/issues/106 """
    from deeptime.markov.tools.analysis import committor, is_reversible
    from deeptime.markov.tools.flux import flux_matrix, to_netflux
    from deeptime.markov import reactive_flux, 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
                  ]])
    if sparse_mode:
        T = csr_matrix(T)
    mu = np.array([
        0.2306979668517676, 0.2328013892993006, 0.2703312416016573,
        0.2661694022472743
    ])
    assert is_reversible(T)
    np.testing.assert_allclose(T.T.dot(mu).T, mu)
    np.testing.assert_equal(T.T.dot(mu).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 = reactive_flux(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,
                     stationary_distribution=mu,
                     qminus=qminus,
                     qplus=qplus,
                     gross_flux=grossflux)
    F.pathways(1.0)
Ejemplo n.º 2
0
    def coarse_grain(self, user_sets):
        """Coarse-grains the flux onto user-defined sets.

        Parameters
        ----------
        user_sets : list of int-iterables
            sets of states that shall be distinguished in the coarse-grained flux.

        Returns
        -------
        (sets, tpt) : (list of int-iterables, ReactiveFlux)
            sets contains the sets tpt is computed on. The tpt states of the new
            tpt object correspond to these sets of states in this order. Sets might
            be identical, if the user has already provided a complete partition that
            respects the boundary between A, B and the intermediates. If not, Sets
            will have more members than provided by the user, containing the
            "remainder" states and reflecting the splitting at the A and B
            boundaries.
            tpt contains a new tpt object for the coarse-grained flux. All its
            quantities (gross_flux, net_flux, A, B, committor, backward_committor)
            are coarse-grained to sets.

        Notes
        -----
        All user-specified sets will be split (if necessary) to
        preserve the boundary between A, B and the intermediate
        states.

        """
        # coarse-grain sets
        tpt_sets, source_indices, target_indices = self._compute_coarse_sets(user_sets)
        nnew = len(tpt_sets)

        # coarse-grain flux
        # Here we should branch between sparse and dense implementations, but currently there is only a dense version.
        flux_coarse = coarsegrain(self._gross_flux, tpt_sets)
        net_flux_coarse = to_netflux(flux_coarse)

        # coarse-grain stationary probability and committors - this can be done all dense
        pstat_coarse = np.zeros(nnew)
        forward_committor_coarse = np.zeros(nnew)
        backward_committor_coarse = np.zeros(nnew)
        for i in range(0, nnew):
            I = list(tpt_sets[i])
            statdist_subselection = self._stationary_distribution[I]
            pstat_coarse[i] = np.sum(statdist_subselection)
            # normalized stationary probability over I
            statdist_subselection_prob = statdist_subselection / pstat_coarse[i]
            forward_committor_coarse[i] = np.dot(statdist_subselection_prob, self._qplus[I])
            backward_committor_coarse[i] = np.dot(statdist_subselection_prob, self._qminus[I])

        res = ReactiveFlux(source_indices, target_indices, net_flux=net_flux_coarse,
                           stationary_distribution=pstat_coarse, qminus=backward_committor_coarse,
                           qplus=forward_committor_coarse, gross_flux=flux_coarse)
        return tpt_sets, res
Ejemplo n.º 3
0
    def netflux(self, a, b):
        r"""The netflux network for the reaction from
        A=[0,...,a] => B=[b,...,M].

        Parameters
        ----------
        a : int
            State index
        b : int
            State index

        Returns
        -------
        netflux : (M, M) ndarray
            Matrix of flux values between pairs of states.

        """
        flux = self.flux(a, b)
        from deeptime.markov.tools.flux import to_netflux
        return to_netflux(flux)
Ejemplo n.º 4
0
def compute_reactive_flux(
        transition_matrix: np.ndarray,
        source_states: Iterable[int],
        target_states: Iterable[int],
        stationary_distribution=None,
        qminus=None,
        qplus=None,
        transition_matrix_tolerance: Optional[float] = None) -> ReactiveFlux:
    r""" Computes the A->B reactive flux using transition path theory (TPT).

    Parameters
    ----------
    transition_matrix : (M, M) ndarray or scipy.sparse matrix
        The transition matrix.
    source_states : array_like
        List of integer state labels for set A
    target_states : array_like
        List of integer state labels for set B
    stationary_distribution : (M,) ndarray, optional, default=None
        Stationary vector. If None is computed from the transition matrix internally.
    qminus : (M,) ndarray (optional)
        Backward committor for A->B reaction
    qplus : (M,) ndarray (optional)
        Forward committor for A-> B reaction
    transition_matrix_tolerance : float, optional, default=None
        Tolerance with which is checked whether the input is actually a transition matrix. If None (default),
        no check is performed.

    Returns
    -------
    tpt: deeptime.markov.tools.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 :footcite:`weinan2006towards`) for continous systems has a
    discrete version outlined in :footcite:`metzner2009transition`. Here, we use the transition
    matrix formulation described in :footcite:`noe2009constructing`.

    See also
    --------
    ReactiveFlux

    References
    ----------
    .. footbibliography::
    """
    import deeptime.markov.tools.analysis as msmana

    source_states = ensure_array(source_states, dtype=int)
    target_states = ensure_array(target_states, dtype=int)

    if len(source_states) == 0 or len(target_states) == 0:
        raise ValueError('set A or B is empty')

    n_states = transition_matrix.shape[0]
    if len(source_states) > n_states or len(target_states) > n_states \
            or max(source_states) > n_states or max(target_states) > n_states:
        raise ValueError(
            'set A or B defines more states than the given transition matrix.')

    if transition_matrix_tolerance is not None and \
            msmana.is_transition_matrix(transition_matrix, tol=transition_matrix_tolerance):
        raise ValueError('given matrix T is not a transition matrix')

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

    # construct flux object
    return ReactiveFlux(source_states,
                        target_states,
                        net_flux=netflux,
                        stationary_distribution=stationary_distribution,
                        qminus=qminus,
                        qplus=qplus,
                        gross_flux=grossflux)