from __future__ import division import math import numpy as np
def JC69_Q(): a = 0.01/3 Q = np.asarray( [ -3*a, a, a, a, a, -3*a, a, a, a, a, -3*a, a, a, a, a, -3*a ]) Q.shape = (4,4) return Q def TN93_values(): pi = [0.2,0.3,0.2,0.3] T,C,A,G = pi Y = T + C R = A + G a1 = 2 # Y transitions a2 = 1 # R transitions b = 0.2 # transversions return T,C,A,G,Y,R,a1,a2,b def TN93_Q(): T,C,A,G,Y,R,a1,a2,b = TN93_values() Q = np.asarray( [ -(a1*C + b*R), a1*C, b*A, b*G, a1*T, -(a1*T + b*R), b*A, b*G, b*T, b*C, -(a2*G + b*Y), a2*G, b*T, b*C, a2*A, -(a2*A + b*Y) ]) Q.shape = (4,4) return Q def TN93_P(t): # order TCAG T,C,A,G,Y,R,a1,a2,b = TN93_values() e2 = math.e**(-b*t) e3 = math.e**(-(R*a2 + Y*b)*t) e4 = math.e**(-(Y*a1 + R*b)*t)
TY,CY,AR,GR = T/Y,C/Y,A/R,G/R M = [ T + TY*R*e2 + CY*e4, C + CY*R*e2 - CY*e4, A*(1 - e2), G*(1 - e2), T + TY*R*e2 - TY*e4, C + CY*R*e2 + TY*e4, A*(1 - e2), G*(1 - e2), T*(1 - e2), C*(1 - e2), A + AR*Y*e2 + GR*e3, G + GR*Y*e2 - GR*e3, T*(1 - e2), C*(1 - e2), A + AR*Y*e2 - AR*e3, G + GR*Y*e2 + AR*e3 ] P = np.array(M) P.shape = (4,4) return P def convert(Q,t,debug=False): if debug: print 'Q', '\n', Q evals, evecs = np.linalg.eig(Q) if debug: print 'evals', '\n', evals L = np.diag([math.e**(k*t) for k in evals]) if debug: print 'L', '\n', L U = evecs if debug: print 'U', '\n', U iU = np.linalg.inv(U) if debug: print 'iU', '\n', iU P = np.dot(U,np.dot(L,iU)) if debug: print 'P', '\n', P return P def long_time(P,N=5000): M = P for i in range(N): M = np.dot(P,M) return M if __name__ == '__main__': #Q = JC69_Q() Q = TN93_Q() t = 0.1 P = convert(Q,t,debug=True) print 'converges to:' print long_time(P) print 'explicit P:' print TN93_P(t) |