Spaces:
Sleeping
Sleeping
import gradio as gr | |
import pandas as pd | |
from gradio import Interface, components | |
import matplotlib.cm as cm | |
import numpy as np | |
from scipy.integrate import odeint | |
import matplotlib.pyplot as plt | |
from PIL import Image, ImageSequence | |
from math import factorial | |
from tqdm import tqdm | |
from sklearn.cluster import DBSCAN | |
def create_trajectory_gif(k1=3, k2=20, p=0.1, u1=1, u2=2, u3=2.3, timesteps=6, grid_interval=0.1): | |
k1 = int(round(k1)) | |
k2 = int(round(k2)) | |
timesteps = int(round(timesteps)) | |
# Computes the probability of a strategy being best response to a given sample of k | |
def xtp1(x1, x2, k): | |
probs = np.zeros(3) | |
for i in range(k): | |
for j in range(k-i): | |
if 1.* i/k *u1 > 1.*j/k *u2 and 1.* i/k*u1 > 1.*(k-i-j)/k *u3: | |
probs[0] += factorial(k)/(factorial(j)* factorial(i) * factorial(k-i-j) ) *(x1)**i * (x2)**j * (1-x1-x2)**(k-i-j) | |
elif 1.* j/k *u2 > 1.*i/k *u1 and 1.* j/k*u2 > 1.*(k-i-j)/k *u3: | |
probs[1] += factorial(k)/(factorial(j)* factorial(i) * factorial(k-i-j) ) *(x1)**i * (x2)**j * (1-x1-x2)**(k-i-j) | |
else: | |
probs[2] += factorial(k)/(factorial(j)* factorial(i) * factorial(k-i-j) ) *(x1)**i * (x2)**j * (1-x1-x2)**(k-i-j) | |
return probs | |
def W(x1, x2): | |
return p*xtp1(x1, x2, k1) + (1-p)* xtp1(x1, x2, k2) | |
# Define the system of differential equations | |
def system(Y, t=0): | |
x1, x2 = Y | |
w = W(x1, x2) | |
dx1dt = w[0] - x1 | |
dx2dt = w[1] - x2 | |
return [dx1dt, dx2dt] | |
# time space | |
t = np.linspace(0, timesteps, int(timesteps*5)) | |
grid_points = [(x, y) for x in np.arange(0, 1.1, grid_interval) for y in np.arange(0, 1.1, grid_interval) if x + y <= 1] | |
# Generating a color map | |
colors = cm.rainbow(np.linspace(0, 1, len(grid_points))) | |
final_points = [] | |
frames = [] | |
for t_val in tqdm(t): | |
plt.figure(figsize=(12, 8)) | |
for ic, color in zip(grid_points, colors): | |
t_segment = np.linspace(0, t_val, 100) # 100 points for each trajectory segment | |
sol = odeint(system, ic, t_segment) | |
plt.plot(sol[:, 0], sol[:, 1], color=color, alpha=0.5) | |
if t_val == t[-1]: # If it's the last timestep, collect the final point | |
final_points.append(sol[-1]) | |
plt.title(f"Attractor plot at time = {t_val:.2f}") | |
plt.xlabel("x1") | |
plt.ylabel("x2") | |
plt.grid(True) | |
plt.tight_layout() | |
# Save the current frame to a file and add to the list of frames | |
filename = f"./static/temp/temp_frame_{int(t_val*10):04d}.png" | |
plt.savefig(filename) | |
frames.append(Image.open(filename)) | |
plt.close() | |
# Save frames as a GIF | |
gif_filename = './static/trajectory_animation2.gif' | |
frames[0].save(gif_filename, save_all=True, append_images=frames[1:], loop=0, duration=100) | |
# Cleanup temporary frame files | |
for frame in frames: | |
frame.close() | |
# Cluster the final points using DBSCAN | |
clustering = DBSCAN(eps=0.1, min_samples=1).fit(final_points) | |
cluster_labels = clustering.labels_ | |
# Determine the stable points by averaging the points in each cluster | |
stable_points = [] | |
for label in set(cluster_labels): | |
points_in_cluster = np.array(final_points)[cluster_labels == label] | |
stable_point = np.around(np.mean(points_in_cluster, axis=0), decimals = 2) | |
stable_points.append(stable_point) | |
list_of_lists = [list(arr) + [1 - sum(arr)] for arr in stable_points] | |
df = pd.DataFrame(list_of_lists, columns=['x1', 'x2', 'x3']) | |
return gif_filename, df | |
iface = gr.Interface( | |
fn= create_trajectory_gif, | |
inputs=[ | |
gr.Number( label="Sample Size 1"), | |
gr.Number( label="Sample Size 2"), | |
gr.Slider(minimum=0, maximum=1, step=0.01, label="Proportion of Cohort 1 (with sample size 1)"), | |
gr.Number(label="Payoff u1"), | |
gr.Number(label="Payoff u2"), | |
gr.Number(label="Payoff u3"), | |
gr.Number(label="Timesteps"), | |
gr.Number(label="Grid resolution"), | |
], | |
outputs=[ | |
gr.Image(label="Simulation GIF"), | |
gr.Dataframe(type="pandas", label="Stable equilibria") | |
], | |
examples=[ | |
[3, 20, 0.1, 1, 2, 2.3, 6, 0.1] | |
] | |
) | |
iface.launch() |