def test_disconnected_dtraj_sanity(mode, reversible): msm1 = MarkovStateModel([[.8, .2], [.3, .7]]) msm2 = MarkovStateModel([[.9, .05, .05], [.3, .6, .1], [.1, .1, .8]]) dtrajs = [msm1.simulate(10000), 2 + msm2.simulate(10000), np.array([5]*100)] init_hmm = init.discrete.random_guess(6, 3) hmm = MaximumLikelihoodHMM(init_hmm, lagtime=1, reversible=reversible) \ .fit(dtrajs).fetch_model() if mode == 'bayesian': BayesianHMM(hmm.submodel_largest(dtrajs=dtrajs), reversible=reversible).fit(dtrajs)
def test_nonreversible_disconnected(): msm1 = MarkovStateModel([[.7, .3], [.3, .7]]) msm2 = MarkovStateModel([[.9, .05, .05], [.3, .6, .1], [.1, .1, .8]]) traj = np.concatenate([msm1.simulate(1000000), 2 + msm2.simulate(1000000)]) counts = TransitionCountEstimator(lagtime=1, count_mode="sliding").fit(traj) msm = MaximumLikelihoodMSM(reversible=True).fit(counts).fetch_model() assert_equal(msm.transition_matrix.shape, (3, 3)) assert_equal(msm.stationary_distribution.shape, (3,)) assert_equal(msm.state_symbols(), [2, 3, 4]) assert_equal(msm.state_symbols(1), [0, 1]) msm.select(1) assert_equal(msm.transition_matrix.shape, (2, 2)) assert_equal(msm.stationary_distribution.shape, (2,)) assert_equal(msm.state_symbols(), [0, 1]) assert_equal(msm.state_symbols(0), [2, 3, 4]) with assert_raises(IndexError): msm.select(2)
class HMMScenario(object): def __init__(self, reversible: bool, init_strategy: str, lagtime: int): self.reversible = reversible self.init_strategy = init_strategy self.lagtime = lagtime self.n_steps = int(1e5) self.msm = MarkovStateModel( np.array([[0.7, 0.2, 0.1], [0.1, 0.8, 0.1], [0.1, 0.2, 0.7]])) self.hidden_stationary_distribution = tools.analysis.stationary_distribution( self.msm.transition_matrix) self.n_hidden = self.msm.n_states n_obs_per_hidden_state = 5 self.n_observable = self.n_hidden * n_obs_per_hidden_state def gaussian(x, mu, sigma): prop = 1 / np.sqrt(2. * np.pi * sigma**2) * np.exp(-(x - mu)**2 / (2 * sigma**2)) return prop / prop.sum() self.observed_alphabet = np.arange(self.n_observable) self.output_probabilities = np.array([ gaussian(self.observed_alphabet, mu, 2.) for mu in np.arange((n_obs_per_hidden_state - 1) // 2, self.n_observable, n_obs_per_hidden_state) ]) self.hidden_state_traj = self.msm.simulate(self.n_steps, 0) self.observable_state_traj = np.zeros_like(self.hidden_state_traj) - 1 for state in range(self.n_hidden): ix = np.where(self.hidden_state_traj == state)[0] self.observable_state_traj[ix] = np.random.choice( self.n_observable, p=self.output_probabilities[state], size=ix.shape[0]) assert -1 not in np.unique(self.observable_state_traj) if init_strategy == 'random': self.init_hmm = deeptime.markov.hmm.init.discrete.random_guess( n_observation_states=self.n_observable, n_hidden_states=self.n_hidden, seed=17) elif init_strategy == 'pcca': self.init_hmm = deeptime.markov.hmm.init.discrete.metastable_from_data( self.observable_state_traj, n_hidden_states=self.n_hidden, lagtime=self.lagtime) else: raise ValueError("unknown init strategy {}".format(init_strategy)) self.hmm = MaximumLikelihoodHMM( self.init_hmm, reversible=self.reversible, lagtime=self.lagtime).fit( self.observable_state_traj).fetch_model()
def sample_trajectories(bias_functions): trajs = np.zeros((len(bias_centers), n_samples), dtype=np.int32) for i, bias in enumerate(bias_functions): biased_energies = (xs - 1)**4 * (xs + 1)**4 - 0.1 * xs + bias(xs) biased_energies /= np.max(biased_energies) transition_matrix = tmatrix_metropolis1d(biased_energies) msm = MarkovStateModel(transition_matrix) trajs[i] = msm.simulate(n_steps=n_samples) return trajs
def sqrt_model(n_samples, seed=None): r""" Sample a hidden state and an sqrt-transformed emission trajectory. We sample a hidden state trajectory and sqrt-masked emissions in two dimensions such that the two metastable states are not linearly separable. .. plot:: datasets/plot_sqrt_model.py Parameters ---------- n_samples : int Number of samples to produce. seed : int, optional, default=None Random seed to use. Defaults to None, which means that the random device will be default-initialized. Returns ------- sequence : (n_samples, ) ndarray The discrete states. trajectory : (n_samples, ) ndarray The observable. Notes ----- First, the hidden discrete-state trajectory is simulated. Its transition matrix is given by .. math:: P = \begin{pmatrix}0.95 & 0.05 \\ 0.05 & 0.95 \end{pmatrix}. The observations are generated via the means are :math:`\mu_0 = (0, 1)^\top` and :math:`\mu_1= (0, -1)`, respectively, as well as the covariance matrix .. math:: C = \begin{pmatrix} 30 & 0 \\ 0 & 0.015 \end{pmatrix}. Afterwards, the trajectory is transformed via .. math:: (x, y) \mapsto (x, y + \sqrt{| x |}). """ from deeptime.markov.msm import MarkovStateModel state = np.random.RandomState(seed) cov = sqrt_model.cov states = sqrt_model.states msm = MarkovStateModel(sqrt_model.transition_matrix) dtraj = msm.simulate(n_samples, seed=seed) traj = states[dtraj, :] + state.multivariate_normal(np.zeros(len(cov)), cov, size=len(dtraj), check_valid='ignore') traj[:, 1] += np.sqrt(np.abs(traj[:, 0])) return dtraj, traj
def swissroll_model(n_samples, seed=None): r""" Sample a hidden state and an swissroll-transformed emission trajectory, so that the states are not linearly separable. .. plot:: import matplotlib.pyplot as plt from matplotlib import animation from deeptime.data import swissroll_model n_samples = 15000 dtraj, traj = swissroll_model(n_samples) fig = plt.figure() ax = fig.add_subplot(111, projection='3d') ax.scatter(*traj.T, marker='o', s=20, c=dtraj, alpha=0.6) Parameters ---------- n_samples : int Number of samples to produce. seed : int, optional, default=None Random seed to use. Defaults to None, which means that the random device will be default-initialized. Returns ------- sequence : (n_samples, ) ndarray The discrete states. trajectory : (n_samples, ) ndarray The observable. Notes ----- First, the hidden discrete-state trajectory is simulated. Its transition matrix is given by .. math:: P = \begin{pmatrix}0.95 & 0.05 & & \\ 0.05 & 0.90 & 0.05 & \\ & 0.05 & 0.90 & 0.05 \\ & & 0.05 & 0.95 \end{pmatrix}. The observations are generated via the means are :math:`\mu_0 = (7.5, 7.5)^\top`, :math:`\mu_1= (7.5, 15)^\top`, :math:`\mu_2 = (15, 15)^\top`, and :math:`\mu_3 = (15, 7.5)^\top`, respectively, as well as the covariance matrix .. math:: C = \begin{pmatrix} 1 & 0 \\ 0 & 1 \end{pmatrix}. Afterwards, the trajectory is transformed via .. math:: (x, y) \mapsto (x \cos (x), y, x \sin (x))^\top. """ from deeptime.markov.msm import MarkovStateModel state = np.random.RandomState(seed) cov = swissroll_model.cov states = swissroll_model.states msm = MarkovStateModel(swissroll_model.transition_matrix) dtraj = msm.simulate(n_samples, seed=seed) traj = states[dtraj, :] + state.multivariate_normal( np.zeros(len(cov)), cov, size=len(dtraj), check_valid='ignore') x = traj[:, 0] return dtraj, np.vstack([x * np.cos(x), traj[:, 1], x * np.sin(x)]).T
r""" Metropolis chain in 1D energy landscape ======================================= Example for :meth:`deeptime.data.tmatrix_metropolis1d`. """ import matplotlib.pyplot as plt import numpy as np from deeptime.data import tmatrix_metropolis1d from deeptime.markov.msm import MarkovStateModel xs = np.linspace(-1.5, 1.5, num=100) energies = 1 / 8 * (xs - 1)**2 * (xs + 1)**2 energies /= np.max(energies) transition_matrix = tmatrix_metropolis1d(energies) msm = MarkovStateModel(transition_matrix) traj = msm.simulate(n_steps=1000000) plt.plot(xs, energies, color='C0', label='Energy') plt.plot(xs, energies, marker='x', color='C0') plt.hist(xs[traj], bins=100, density=True, alpha=.6, color='C1', label='Histogram over visited states') plt.legend() plt.show()
class DoubleWell_Discrete_Data(object): """ MCMC process in a symmetric double well potential, spatially discretized to 100 bins """ def __init__(self): from pkg_resources import resource_filename filename = resource_filename('pyemma.datasets', 'double_well_discrete.npz') datafile = np.load(filename) self._dtraj_T100K_dt10 = datafile['dtraj'] self._P = datafile['P'] self._msm_dt = MarkovStateModel(self._P) self._msm = markov_model(self._P) @property def dtraj_T100K_dt10(self): """ 100K frames trajectory at timestep 10, 100 microstates (not all are populated). """ return self._dtraj_T100K_dt10 @property def dtraj_T100K_dt10_n2good(self): """ 100K frames trajectory at timestep 10, good 2-state discretization (at transition state). """ return self.dtraj_T100K_dt10_n([50]) @property def dtraj_T100K_dt10_n2bad(self): """ 100K frames trajectory at timestep 10, bad 2-state discretization (off transition state). """ return self.dtraj_T100K_dt10_n([40]) def dtraj_T100K_dt10_n2(self, divide): """ 100K frames trajectory at timestep 10, arbitrary 2-state discretization. """ return self.dtraj_T100K_dt10_n([divide]) @property def dtraj_T100K_dt10_n6good(self): """ 100K frames trajectory at timestep 10, good 6-state discretization. """ return self.dtraj_T100K_dt10_n([40, 45, 50, 55, 60]) def dtraj_T100K_dt10_n(self, divides): """ 100K frames trajectory at timestep 10, arbitrary n-state discretization. """ disc = np.zeros(100, dtype=int) divides = np.concatenate([divides, [100]]) for i in range(len(divides) - 1): disc[divides[i]:divides[i + 1]] = i + 1 return disc[self.dtraj_T100K_dt10] @property def transition_matrix(self): """ Exact transition matrix used to generate the data """ return self._P @property def msm(self): """ Returns an MSM object with the exact transition matrix """ return self._msm def generate_traj(self, N, start=None, stop=None, dt=1): """ Generates a random trajectory of length N with time step dt """ return self._msm_dt.simulate(N, start=start, stop=stop, dt=dt) def generate_trajs(self, M, N, start=None, stop=None, dt=1): """ Generates M random trajectories of length N each with time step dt """ return [ self.generate_traj(N, start=start, stop=stop, dt=dt) for _ in range(M) ]