Permalink
Cannot retrieve contributors at this time
#!/usr/bin/env python3 | |
# -*- coding: utf-8 -*- | |
""" | |
trirep.py | |
Created on Thu May 9 16:23:30 2019 | |
@author: nolte | |
Introduction to Modern Dynamics, 2nd edition (Oxford University Press, 2019) | |
Population dynamics | |
""" | |
import numpy as np | |
from scipy import integrate | |
from matplotlib import pyplot as plt | |
plt.close('all') | |
def tripartite(x,y,z): | |
sm = x + y + z | |
xp = x/sm | |
yp = y/sm | |
f = np.sqrt(3)/2 | |
y0 = f*xp | |
x0 = -0.5*xp - yp + 1; | |
plt.figure(2) | |
lines = plt.plot(x0,y0) | |
plt.setp(lines, linewidth=0.5) | |
plt.plot([0, 1],[0, 0],'k',linewidth=1) | |
plt.plot([0, 0.5],[0, f],'k',linewidth=1) | |
plt.plot([1, 0.5],[0, f],'k',linewidth=1) | |
plt.show() | |
def solve_flow(y,tspan): | |
def flow_deriv(y, t0): | |
#"""Compute the time-derivative .""" | |
f = np.zeros(shape=(N,)) | |
for iloop in range(N): | |
ftemp = 0 | |
for jloop in range(N): | |
ftemp = ftemp + A[iloop,jloop]*y[jloop] | |
f[iloop] = ftemp | |
phitemp = phi0 # Can adjust this from 0 to 1 to stabilize (but Nth population is no longer independent) | |
for loop in range(N): | |
phitemp = phitemp + f[loop]*y[loop] | |
phi = phitemp | |
yd = np.zeros(shape=(N,)) | |
for loop in range(N-1): | |
yd[loop] = y[loop]*(f[loop] - phi); | |
if np.abs(phi0) < 0.01: # average fitness maintained at zero | |
yd[N-1] = y[N-1]*(f[N-1]-phi); | |
else: # non-zero average fitness | |
ydtemp = 0 | |
for loop in range(N-1): | |
ydtemp = ydtemp - yd[loop] | |
yd[N-1] = ydtemp | |
return yd | |
# Solve for the trajectories | |
t = np.linspace(0, tspan, 701) | |
x_t = integrate.odeint(flow_deriv,y,t) | |
return t, x_t | |
# model_case 1 = zero diagonal | |
# model_case 2 = zero trace | |
# model_case 3 = asymmetric (zero trace) | |
print(' ') | |
print('trirep.py') | |
print('Case: 1 = antisymm zero diagonal') | |
print('Case: 2 = antisymm zero trace') | |
print('Case: 3 = random') | |
model_case = int(input('Enter the Model Case (1-3)')) | |
N = 3 | |
asymm = 3 # 1 = zero diag (replicator eqn) 2 = zero trace (autocatylitic model) 3 = random (but zero trace) | |
phi0 = 0.001 # average fitness (positive number) damps oscillations | |
T = 100; | |
if model_case == 1: | |
Atemp = np.zeros(shape=(N,N)) | |
for yloop in range(N): | |
for xloop in range(yloop+1,N): | |
Atemp[yloop,xloop] = 2*(0.5 - np.random.random(1)) | |
Atemp[xloop,yloop] = -Atemp[yloop,xloop] | |
if model_case == 2: | |
Atemp = np.zeros(shape=(N,N)) | |
for yloop in range(N): | |
for xloop in range(yloop+1,N): | |
Atemp[yloop,xloop] = 2*(0.5 - np.random.random(1)) | |
Atemp[xloop,yloop] = -Atemp[yloop,xloop] | |
Atemp[yloop,yloop] = 2*(0.5 - np.random.random(1)) | |
tr = np.trace(Atemp) | |
A = Atemp | |
for yloop in range(N): | |
A[yloop,yloop] = Atemp[yloop,yloop] - tr/N | |
else: | |
Atemp = np.zeros(shape=(N,N)) | |
for yloop in range(N): | |
for xloop in range(N): | |
Atemp[yloop,xloop] = 2*(0.5 - np.random.random(1)) | |
tr = np.trace(Atemp) | |
A = Atemp | |
for yloop in range(N): | |
A[yloop,yloop] = Atemp[yloop,yloop] - tr/N | |
plt.figure(3) | |
im = plt.matshow(A,3,cmap=plt.cm.get_cmap('seismic')) # hsv, seismic, bwr | |
cbar = im.figure.colorbar(im) | |
M = 20 | |
delt = 1/M | |
ep = 0.01; | |
tempx = np.zeros(shape = (3,)) | |
for xloop in range(M): | |
tempx[0] = delt*(xloop)+ep; | |
for yloop in range(M-xloop): | |
tempx[1] = delt*yloop+ep | |
tempx[2] = 1 - tempx[0] - tempx[1] | |
x0 = tempx/np.sum(tempx); # initial populations | |
tspan = 70 | |
t, x_t = solve_flow(x0,tspan) | |
y1 = x_t[:,0] | |
y2 = x_t[:,1] | |
y3 = x_t[:,2] | |
plt.figure(1) | |
lines = plt.plot(t,y1,t,y2,t,y3) | |
plt.setp(lines, linewidth=0.5) | |
plt.show() | |
plt.ylabel('X Position') | |
plt.xlabel('Time') | |
tripartite(y1,y2,y3) |