Based on: Optimal Dimensionality Reduction of Multistate Kinetic and Markov-State Models
(Hummer and Szabo, 2014, JAPC B) http://pubs.acs.org/doi/pdfplus/10.1021/jp508375q
In [2]:
import numpy as np
import numpy.random as npr
import pylab as pl
%matplotlib inline
Toy example: biased random walk on a bimodal energy landscape
In [22]:
def bimodal_dist(x,dist=1.8):
comp1 = np.exp((-sum((x+dist*0.5)**2)))
comp2 = np.exp((-sum((x-dist*0.5)**2)))
return comp1 + comp2
def metropolis_hastings(density,n_samples=100,step_size=0.1,ndim=2):
""" generates samples given a density function which maps from R^ndim
to R using the defined step_size.
returns (samples, acceptance ratio)"""
x0 = npr.randn(ndim)
d0 = density(x0)
samples = np.zeros((n_samples,ndim))
acceptances = 0
for i in range(n_samples):
x1 = x0 + npr.randn(ndim)*step_size
d1 = density(x1)
if npr.rand() <= (d1/d0):
samples[i] = x1
x0 = x1
d0 = d1
acceptances+=1
else:
samples[i] = x0
return samples,1.0*acceptances/n_samples
In [23]:
step_size = np.sqrt(0.1)
samples, ar = metropolis_hastings(bimodal_dist,100000,step_size)
print("Acceptance ratio: {0:.4}".format(ar))
hist = pl.hist2d(samples[:,0],samples[:,1],bins=100);
In [34]:
def state_decomp(x):
return x[:,1] - x[:,0] < 0
In [36]:
discrete_states = np.array(state_decomp(samples),dtype=int)
1.0*sum(discrete_states)/len(samples)
Out[36]:
In [38]:
pl.plot(discrete_states[20000:20000+100])
Out[38]:
In [105]:
def transition_count_matrix(sequence):
n = len(set(sequence)) # number of states
C = np.zeros((n,n),dtype=int)
for t in range(1,len(sequence)):
i,j = sequence[t-1:t+1]
C[i,j] += 1
return C
def row_normalize(matrix):
for i in xrange(len(matrix)):
matrix[i] /= sum(matrix[i])
return matrix
def trans_mat(sequence):
return row_normalize(transition_count_matrix(sequence))
In [108]:
discrete_states
Out[108]:
In [109]:
T = trans_mat(discrete_states)
In [99]:
T[0] = T[0] / sum(T[0])
T[1] = T[1] / sum(T[1])
In [93]:
np.sum(T,axis=1)
Out[93]:
In [94]:
T = T / np.sum(T,axis=1)
In [102]:
counts
Out[102]:
In [ ]:
np.sum(T,axis=1)
In [68]:
sum(T[0])
Out[68]:
In [58]:
sum(T)
Out[58]:
In [59]:
T[0]
Out[59]:
In [60]:
T[:,0]
Out[60]:
In [ ]: