def test_dtram(self): therm_energies, conf_energies, log_lagrangian_mult, increments, loglikelihoods = \ dtram.estimate( self.count_matrices, self.bias_energies, maxiter=10000, maxerr=1.0E-15) transition_matrices = dtram.estimate_transition_matrices( log_lagrangian_mult, self.bias_energies, conf_energies, self.count_matrices, np.zeros(shape=conf_energies.shape, dtype=np.float64)) maxerr = 1.0E-1 assert_allclose(therm_energies, self.therm_energies, atol=maxerr) assert_allclose(conf_energies, self.conf_energies, atol=maxerr) assert_allclose(transition_matrices, self.transition_matrices, atol=maxerr)
def test_dtram_stop(): T = 5 M = 10 therm_energies, conf_energies, log_lagrangian_mult, increments, loglikelihoods = dtram.estimate( np.ones(shape=(T, M, M), dtype=np.intc), np.zeros(shape=(T, M), dtype=np.float64), maxiter=10, maxerr=-1.0, save_convergence_info=1, callback=generic_callback_stop) assert_allclose(therm_energies, 0.0, atol=1.0E-15) assert_allclose(conf_energies, np.log(M), atol=1.0E-15) assert_allclose(log_lagrangian_mult, np.log(M + dtram.get_prior()), atol=1.0E-15) assert_true(increments.shape[0] == 1) assert_true(loglikelihoods.shape[0] == 1)
def _estimate(self, trajs): # check input assert isinstance(trajs, (tuple, list)) assert len(trajs) == 2 ttrajs = trajs[0] dtrajs = trajs[1] # validate input for ttraj, dtraj in zip(ttrajs, dtrajs): _types.assert_array(ttraj, ndim=1, kind='numeric') _types.assert_array(dtraj, ndim=1, kind='numeric') assert _np.shape(ttraj)[0] == _np.shape(dtraj)[0] # harvest transition counts self.count_matrices_full = _util.count_matrices( ttrajs, dtrajs, self.lag, sliding=self.count_mode, sparse_return=False, nstates=self.nstates_full) # harvest state counts (for WHAM) self.state_counts_full = _util.state_counts(ttrajs, dtrajs, nthermo=self.nthermo, nstates=self.nstates_full) # restrict to connected set C_sum = self.count_matrices_full.sum(axis=0) # TODO: use improved cset cset = _largest_connected_set(C_sum, directed=True) self.active_set = cset # correct counts self.count_matrices = self.count_matrices_full[:, cset[:, _np.newaxis], cset] self.count_matrices = _np.require(self.count_matrices, dtype=_np.intc, requirements=['C', 'A']) # correct bias matrix self.bias_energies = self.bias_energies_full[:, cset] self.bias_energies = _np.require(self.bias_energies, dtype=_np.float64, requirements=['C', 'A']) # correct state counts self.state_counts = self.state_counts_full[:, cset] self.state_counts = _np.require(self.state_counts, dtype=_np.intc, requirements=['C', 'A']) # run initialisation if self.init is not None: if self.init == 'wham': self.therm_energies, self.conf_energies, _increments, _loglikelihoods = \ _wham.estimate( self.state_counts, self.bias_energies, maxiter=self.init_maxiter, maxerr=self.init_maxerr, save_convergence_info=0, therm_energies=self.therm_energies, conf_energies=self.conf_energies, callback=_ConvergenceProgressIndicatorCallBack( self, 'WHAM init.', self.init_maxiter, self.init_maxerr)) self._progress_force_finish(stage='WHAM init.', description='WHAM init.') # run estimator self.therm_energies, self.conf_energies, self.log_lagrangian_mult, \ self.increments, self.loglikelihoods = _dtram.estimate( self.count_matrices, self.bias_energies, maxiter=self.maxiter, maxerr=self.maxerr, log_lagrangian_mult=self.log_lagrangian_mult, conf_energies=self.conf_energies, save_convergence_info=self.save_convergence_info, callback=_ConvergenceProgressIndicatorCallBack( self, 'DTRAM', self.maxiter, self.maxerr)) self._progress_force_finish(stage='DTRAM', description='DTRAM') # compute models fmsms = [ _dtram.estimate_transition_matrix( self.log_lagrangian_mult, self.bias_energies, self.conf_energies, self.count_matrices, _np.zeros(shape=self.conf_energies.shape, dtype=_np.float64), K) for K in range(self.nthermo) ] active_sets = [ _largest_connected_set(msm, directed=False) for msm in fmsms ] fmsms = [ _np.ascontiguousarray((msm[lcc, :])[:, lcc]) for msm, lcc in zip(fmsms, active_sets) ] models = [] for msm, acs in zip(fmsms, active_sets): models.append( _ThermoMSM(msm, self.active_set[acs], self.nstates_full, dt_model=self.timestep_traj.get_scaled(self.lag))) # set model parameters to self self.set_model_params(models=models, f_therm=self.therm_energies, f=self.conf_energies) # done return self
def _estimate(self, trajs): """ Parameters ---------- trajs : ndarray(T, 2) or list of ndarray(T_i, 2) Thermodynamic trajectories. Each trajectory is a (T_i, 2)-array with T_i time steps. The first column is the thermodynamic state index, the second column is the configuration state index. """ # format input if needed if isinstance(trajs, _np.ndarray): trajs = [trajs] # validate input assert _types.is_list(trajs) for ttraj in trajs: _types.assert_array(ttraj, ndim=2, kind='numeric') assert _np.shape(ttraj)[1] >= 2 # harvest transition counts self.count_matrices_full = _util.count_matrices( [_np.ascontiguousarray(t[:, :2]).astype(_np.intc) for t in trajs], self.lag, sliding=self.count_mode, sparse_return=False, nstates=self.nstates_full) # harvest state counts (for WHAM) self.state_counts_full = _util.state_counts(trajs, nthermo=self.nthermo, nstates=self.nstates_full) # restrict to connected set C_sum = self.count_matrices_full.sum(axis=0) # TODO: use improved cset cset = _largest_connected_set(C_sum, directed=True) self.active_set = cset # correct counts self.count_matrices = self.count_matrices_full[:, cset[:, _np.newaxis], cset] self.count_matrices = _np.require(self.count_matrices, dtype=_np.intc, requirements=['C', 'A']) # correct bias matrix self.bias_energies = self.bias_energies_full[:, cset] self.bias_energies = _np.require(self.bias_energies, dtype=_np.float64, requirements=['C', 'A']) # correct state counts self.state_counts = self.state_counts_full[:, cset] self.state_counts = _np.require(self.state_counts, dtype=_np.intc, requirements=['C', 'A']) # run initialisation if self.init is not None: if self.init == 'wham': self.therm_energies, self.conf_energies, _increments, _loglikelihoods = \ _wham.estimate( self.state_counts, self.bias_energies, maxiter=5000, maxerr=1.0E-8, save_convergence_info=0, therm_energies=self.therm_energies, conf_energies=self.conf_energies) # run estimator self.therm_energies, self.conf_energies, self.log_lagrangian_mult, \ self.increments, self.loglikelihoods = _dtram.estimate( self.count_matrices, self.bias_energies, maxiter=self.maxiter, maxerr=self.maxerr, log_lagrangian_mult=self.log_lagrangian_mult, conf_energies=self.conf_energies, save_convergence_info=self.save_convergence_info) # compute models models = [ _dtram.estimate_transition_matrix( self.log_lagrangian_mult, self.bias_energies, self.conf_energies, self.count_matrices, _np.zeros(shape=self.conf_energies.shape, dtype=_np.float64), K) for K in range(self.nthermo) ] self.model_active_set = [ _largest_connected_set(msm, directed=False) for msm in models ] models = [ _np.ascontiguousarray((msm[lcc, :])[:, lcc]) for msm, lcc in zip(models, self.model_active_set) ] # set model parameters to self self.set_model_params(models=[ _MSM(msm, dt_model=self.timestep_traj.get_scaled(self.lag)) for msm in models ], f_therm=self.therm_energies, f=self.conf_energies) # done return self
def _estimate(self, trajs): """ Parameters ---------- X : tuple of (ttrajs, dtrajs) Simulation trajectories. ttrajs contain the indices of the thermodynamic state and dtrajs contains the indices of the configurational states. ttrajs : list of numpy.ndarray(X_i, dtype=int) Every elements is a trajectory (time series). ttrajs[i][t] is the index of the thermodynamic state visited in trajectory i at time step t. dtrajs : list of numpy.ndarray(X_i, dtype=int) dtrajs[i][t] is the index of the configurational state (Markov state) visited in trajectory i at time step t. """ # check input assert isinstance(trajs, (tuple, list)) assert len(trajs) == 2 ttrajs = trajs[0] dtrajs = trajs[1] # validate input for ttraj, dtraj in zip(ttrajs, dtrajs): _types.assert_array(ttraj, ndim=1, kind='numeric') _types.assert_array(dtraj, ndim=1, kind='numeric') assert _np.shape(ttraj)[0] == _np.shape(dtraj)[0] # harvest transition counts self.count_matrices_full = _util.count_matrices( ttrajs, dtrajs, self.lag, sliding=self.count_mode, sparse_return=False, nstates=self.nstates_full) # harvest state counts (for WHAM) self.state_counts_full = _util.state_counts(ttrajs, dtrajs, nthermo=self.nthermo, nstates=self.nstates_full) # restrict to connected set C_sum = self.count_matrices_full.sum(axis=0) # TODO: use improved cset cset = _largest_connected_set(C_sum, directed=True) self.active_set = cset # correct counts self.count_matrices = self.count_matrices_full[:, cset[:, _np.newaxis], cset] self.count_matrices = _np.require(self.count_matrices, dtype=_np.intc, requirements=['C', 'A']) # correct bias matrix self.bias_energies = self.bias_energies_full[:, cset] self.bias_energies = _np.require(self.bias_energies, dtype=_np.float64, requirements=['C', 'A']) # correct state counts self.state_counts = self.state_counts_full[:, cset] self.state_counts = _np.require(self.state_counts, dtype=_np.intc, requirements=['C', 'A']) # run initialisation if self.init is not None: if self.init == 'wham': self.therm_energies, self.conf_energies, _increments, _loglikelihoods = \ _wham.estimate( self.state_counts, self.bias_energies, maxiter=self.init_maxiter, maxerr=self.init_maxerr, save_convergence_info=0, therm_energies=self.therm_energies, conf_energies=self.conf_energies, callback=_ConvergenceProgressIndicatorCallBack( self, 'WHAM init.', self.init_maxiter, self.init_maxerr)) self._progress_force_finish(stage='WHAM init.') # run estimator self.therm_energies, self.conf_energies, self.log_lagrangian_mult, \ self.increments, self.loglikelihoods = _dtram.estimate( self.count_matrices, self.bias_energies, maxiter=self.maxiter, maxerr=self.maxerr, log_lagrangian_mult=self.log_lagrangian_mult, conf_energies=self.conf_energies, save_convergence_info=self.save_convergence_info, callback=_ConvergenceProgressIndicatorCallBack( self, 'DTRAM', self.maxiter, self.maxerr)) self._progress_force_finish(stage='DTRAM') # compute models models = [ _dtram.estimate_transition_matrix( self.log_lagrangian_mult, self.bias_energies, self.conf_energies, self.count_matrices, _np.zeros(shape=self.conf_energies.shape, dtype=_np.float64), K) for K in range(self.nthermo) ] self.model_active_set = [ _largest_connected_set(msm, directed=False) for msm in models ] models = [ _np.ascontiguousarray((msm[lcc, :])[:, lcc]) for msm, lcc in zip(models, self.model_active_set) ] # set model parameters to self self.set_model_params(models=[ _MSM(msm, dt_model=self.timestep_traj.get_scaled(self.lag)) for msm in models ], f_therm=self.therm_energies, f=self.conf_energies) # done return self