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)
def setUp(self): P = np.array([[0.8, 0.15, 0.05, 0.0, 0.0], [0.1, 0.75, 0.05, 0.05, 0.05], [0.05, 0.1, 0.8, 0.0, 0.05], [0.0, 0.2, 0.0, 0.8, 0.0], [0.0, 0.02, 0.02, 0.0, 0.96]]) P = csr_matrix(P) A = [0] B = [4] mu = stationary_distribution(P) qminus = committor(P, A, B, forward=False, mu=mu) qplus = committor(P, A, B, forward=True, mu=mu) self.A = A self.B = B self.F = flux_matrix(P, mu, qminus, qplus, netflux=True) self.paths = [ np.array([0, 1, 4]), np.array([0, 2, 4]), np.array([0, 1, 2, 4]) ] self.capacities = [ 0.0072033898305084252, 0.0030871670702178975, 0.00051452784503631509 ]
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)
def test_backward_comittor(bdc): P = bdc.transition_matrix un = committor(P, [0, 1], [8, 9], forward=False) u = bdc.committor_backward(1, 8) assert_allclose(un, u)
def test_backward_comittor(self): P = self.bdc.transition_matrix_sparse un = committor(P, list(range(10)), list(range(90, 100)), forward=False) u = self.bdc.committor_backward(9, 90) assert_allclose(un, u)
def test_forward_comittor(self): P = self.bdc.transition_matrix un = committor(P, [0, 1], [8, 9], forward=True) u = self.bdc.committor_forward(1, 8) assert_allclose(un, u)