def merge_microstates_in_tmatrix(transition_matrix, ms1, ms2, keep_size=False): '''Merge two microstates (ms1 and ms2) in the transition matrix, i.e., returns the transition matrix that we would obtain if the microstates where merged befored the estimation of the transition matrix. The transition matrix is expected to be a square numpy array''' check_tmatrix(transition_matrix) # it is a valid t_matrix? p = pops_from_tmatrix(transition_matrix) size = len(transition_matrix) final_tmatrix = np.copy(transition_matrix) # sum of the columns with indexes ms1 and ms2 # and saved in the index state1. for k in range(size): final_tmatrix[k, ms1] += final_tmatrix[k, ms2] # weighted sum of the rows for k in range(size): if (p[ms1] + p[ms2]) != 0.0: final_tmatrix[ms1, k] = (p[ms1] * final_tmatrix[ms1, k] + p[ms2] * final_tmatrix[ms2, k]) / \ (p[ms1] + p[ms2]) if keep_size: for i in range(size): final_tmatrix[ms2, i] = 0.0 final_tmatrix[i, ms2] = 0.0 else: final_tmatrix = np.delete(final_tmatrix, ms2, axis=1) final_tmatrix = np.delete(final_tmatrix, ms2, axis=0) return final_tmatrix
def fluxBA_distribution_on_A(self): if self.markovian: t_matrix = pseudo_nm_tmatrix(self.markov_tmatrix, self.stateA, self.stateB) else: t_matrix = self.nm_tmatrix distrib_on_A = np.zeros(len(self.stateA)) labeled_pops = pops_from_tmatrix(t_matrix) for i in range(1, 2 * self.n_states + 1, 2): for j in range(2 * self.n_states): if j // 2 in self.stateA: distrib_on_A[self.stateA.index(j // 2)] += \ labeled_pops[i] * t_matrix[i, j] return distrib_on_A
def non_markov_mfpts(nm_transition_matrix, stateA, stateB, lag_time=1): '''Computes the mean first passage times A->B and B->A where from a non-markovian model. The shape of the transition matrix should be (2*n_states, 2*n_states) ''' aux.check_tmatrix(nm_transition_matrix) labeled_pops = aux.pops_from_tmatrix(nm_transition_matrix) n_states = len(labeled_pops) // 2 fluxAB = 0 fluxBA = 0 for i in range(0, 2 * n_states, 2): for j in range(2 * n_states): if int(j / 2) in stateB: fluxAB += labeled_pops[i] * nm_transition_matrix[i, j] for i in range(1, 2 * n_states + 1, 2): for j in range(2 * n_states): if int(j / 2) in stateA: fluxBA += labeled_pops[i] * nm_transition_matrix[i, j] pop_colorA = 0.0 pop_colorB = 0.0 for i in range(0, 2 * n_states, 2): pop_colorA += labeled_pops[i] for i in range(1, 2 * n_states + 1, 2): pop_colorB += labeled_pops[i] if fluxAB == 0: mfptAB = float('inf') else: mfptAB = pop_colorA / fluxAB if fluxBA == 0: mfptBA = float('inf') else: mfptBA = pop_colorB / fluxBA mfptAB *= lag_time mfptBA *= lag_time return dict(mfptAB=mfptAB, mfptBA=mfptBA)
for time in range(1, max_n_lags): Fmatrix = np.dot(tmatrix, prevFmatrix - np.diag(np.diag(prevFmatrix))) list_of_pdfs[istateIndex, time] = \ Fmatrix[ini_state[istateIndex], f_state] prevFmatrix = Fmatrix if __name__ == '__main__': # k= np.array([[1,2],[2,3]]) n_states = 5 T = aux.random_markov_matrix(n_states, seed=1) pops = aux.pops_from_tmatrix(T) print(pops) print(markov_mfpts(T, [0], [4])) print(directional_mfpt(T, [0], [4], [1])) print(mfpts_to_target_microstate(T, 4)) print() print(mfpts_matrix(T)) print() print(min_commute_time(mfpts_matrix(T))) # sequence = [1, 'a', 1, 'b', 2.2, 3] # newseq, m_dict = aux.map_to_integers(sequence, {}) # print(newseq) # print(m_dict)
def fit(self): '''Fits the the markov plus color model from a list of sequences ''' # Non-Markovian count matrix nm_tmatrix = np.zeros((2 * self.n_states, 2 * self.n_states)) # Markovian transition matrix markov_tmatrix = np.zeros((self.n_states, self.n_states)) start = self._lag_time step = 1 lag = self._lag_time hlength = self.hist_length if not self.sliding_window: step = lag # Markov first for traj in self.trajectories: for i in range(start, len(traj), step): markov_tmatrix[traj[i - lag], traj[i]] += 1.0 # counting markov_tmatrix = markov_tmatrix + markov_tmatrix.T markov_tmatrix = normalize_markov_matrix(markov_tmatrix) p_nm_tmatrix = pseudo_nm_tmatrix(markov_tmatrix, self.stateA, self.stateB) pops = pops_from_tmatrix(p_nm_tmatrix) # Pseudo-Markov Flux matrix fmatrix = p_nm_tmatrix for i, _ in enumerate(fmatrix): fmatrix[i] *= pops[i] for traj in self.trajectories: for i in range(start, len(traj), step): # Previous color determination (index i - lag) prev_color = "U" for k in range(i - lag, max(i - lag - hlength, 0) - 1, -1): if traj[k] in self.stateA: prev_color = "A" break elif traj[k] in self.stateB: prev_color = "B" break # Current Color (in index i) if traj[i] in self.stateA: color = "A" elif traj[i] in self.stateB: color = "B" else: color = prev_color if prev_color == "A" and color == "B": nm_tmatrix[2 * traj[i - lag], 2 * traj[i] + 1] += 1.0 elif prev_color == "B" and color == "A": nm_tmatrix[2 * traj[i - lag] + 1, 2 * traj[i]] += 1.0 elif prev_color == "A" and color == "A": nm_tmatrix[2 * traj[i - lag], 2 * traj[i]] += 1.0 elif prev_color == "B" and color == "B": nm_tmatrix[2 * traj[i - lag] + 1, 2 * traj[i] + 1] += 1.0 elif prev_color == "U" and color == "B": temp_sum = fmatrix[2 * traj[i - lag], 2 * traj[i] + 1] +\ fmatrix[2 * traj[i - lag] + 1, 2 * traj[i] + 1] nm_tmatrix[2 * traj[i - lag], 2 * traj[i] + 1] += \ fmatrix[2 * traj[i - lag], 2 * traj[i] + 1] / temp_sum nm_tmatrix[2 * traj[i - lag] + 1, 2 * traj[i] + 1] += \ fmatrix[2 * traj[i - lag] + 1, 2 * traj[i] + 1] /\ temp_sum elif prev_color == "U" and color == "A": temp_sum = (fmatrix[2 * traj[i - lag], 2 * traj[i]] + fmatrix[2 * traj[i - lag] + 1, 2 * traj[i]]) nm_tmatrix[2 * traj[i - lag]][2 * traj[i]] += \ fmatrix[2 * traj[i - lag], 2 * traj[i]] / temp_sum nm_tmatrix[2 * traj[i - lag] + 1][2 * traj[i]] += \ fmatrix[2 * traj[i - lag] + 1, 2 * traj[i]] / temp_sum elif prev_color == "U" and color == "U": temp_sum = fmatrix[2 * traj[i - lag], 2 * traj[i] + 1] +\ fmatrix[2 * traj[i - lag] + 1, 2 * traj[i] + 1] +\ fmatrix[2 * traj[i - lag], 2 * traj[i]] +\ fmatrix[2 * traj[i - lag] + 1, 2 * traj[i]] nm_tmatrix[2 * traj[i - lag], 2 * traj[i] + 1] += \ fmatrix[2 * traj[i - lag], 2 * traj[i] + 1] / temp_sum nm_tmatrix[2 * traj[i - lag] + 1][2 * traj[i] + 1] += \ fmatrix[2 * traj[i - lag] + 1, 2 * traj[i] + 1] /\ temp_sum nm_tmatrix[2 * traj[i - lag]][2 * traj[i]] += \ fmatrix[2 * traj[i - lag], 2 * traj[i]] / temp_sum nm_tmatrix[2 * traj[i - lag] + 1][2 * traj[i]] += \ fmatrix[2 * traj[i - lag] + 1, 2 * traj[i]] / temp_sum self.nm_cmatrix = nm_tmatrix # not normalized, it is like count matrix nm_tmatrix = normalize_markov_matrix(nm_tmatrix) self.nm_tmatrix = nm_tmatrix self.markov_tmatrix = markov_tmatrix
def populations(self): # In this case the results are going to be the same if self.markovian: return pops_from_tmatrix(self.markov_tmatrix) else: return pops_from_nm_tmatrix(self.nm_tmatrix)