#!/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)