patellae commited on
Commit
cd3efb0
1 Parent(s): 9eb9c70

Upload 2 files

Browse files
Files changed (2) hide show
  1. app.py +119 -0
  2. requirements.txt +9 -0
app.py ADDED
@@ -0,0 +1,119 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import pandas as pd
3
+ from gradio import Interface, components
4
+ import matplotlib.cm as cm
5
+ import numpy as np
6
+ from scipy.integrate import odeint
7
+ import matplotlib.pyplot as plt
8
+ from PIL import Image, ImageSequence
9
+ from math import factorial
10
+ from tqdm import tqdm
11
+ from sklearn.cluster import DBSCAN
12
+
13
+ def create_trajectory_gif(k1=3, k2=20, p=0.1, u1=1, u2=2, u3=2.3, timesteps=6, grid_interval=0.1):
14
+ k1 = int(round(k1))
15
+ k2 = int(round(k2))
16
+ timesteps = int(round(timesteps))
17
+
18
+ # Computes the probability of a strategy being best response to a given sample of k
19
+ def xtp1(x1, x2, k):
20
+ probs = np.zeros(3)
21
+ for i in range(k):
22
+ for j in range(k-i):
23
+ if 1.* i/k *u1 > 1.*j/k *u2 and 1.* i/k*u1 > 1.*(k-i-j)/k *u3:
24
+ probs[0] += factorial(k)/(factorial(j)* factorial(i) * factorial(k-i-j) ) *(x1)**i * (x2)**j * (1-x1-x2)**(k-i-j)
25
+ elif 1.* j/k *u2 > 1.*i/k *u1 and 1.* j/k*u2 > 1.*(k-i-j)/k *u3:
26
+ probs[1] += factorial(k)/(factorial(j)* factorial(i) * factorial(k-i-j) ) *(x1)**i * (x2)**j * (1-x1-x2)**(k-i-j)
27
+ else:
28
+ probs[2] += factorial(k)/(factorial(j)* factorial(i) * factorial(k-i-j) ) *(x1)**i * (x2)**j * (1-x1-x2)**(k-i-j)
29
+ return probs
30
+
31
+ def W(x1, x2):
32
+ return p*xtp1(x1, x2, k1) + (1-p)* xtp1(x1, x2, k2)
33
+
34
+ # Define the system of differential equations
35
+ def system(Y, t=0):
36
+ x1, x2 = Y
37
+ w = W(x1, x2)
38
+ dx1dt = w[0] - x1
39
+ dx2dt = w[1] - x2
40
+ return [dx1dt, dx2dt]
41
+
42
+ # time space
43
+ t = np.linspace(0, timesteps, int(timesteps*5))
44
+ 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]
45
+
46
+ # Generating a color map
47
+ colors = cm.rainbow(np.linspace(0, 1, len(grid_points)))
48
+
49
+ final_points = []
50
+ frames = []
51
+ for t_val in tqdm(t):
52
+ plt.figure(figsize=(12, 8))
53
+ for ic, color in zip(grid_points, colors):
54
+ t_segment = np.linspace(0, t_val, 100) # 100 points for each trajectory segment
55
+ sol = odeint(system, ic, t_segment)
56
+ plt.plot(sol[:, 0], sol[:, 1], color=color, alpha=0.5)
57
+ if t_val == t[-1]: # If it's the last timestep, collect the final point
58
+ final_points.append(sol[-1])
59
+
60
+ plt.title(f"Attractor plot at time = {t_val:.2f}")
61
+ plt.xlabel("x1")
62
+ plt.ylabel("x2")
63
+ plt.grid(True)
64
+ plt.tight_layout()
65
+
66
+ # Save the current frame to a file and add to the list of frames
67
+ filename = f"./temp/temp_frame_{int(t_val*10):04d}.png"
68
+ plt.savefig(filename)
69
+ frames.append(Image.open(filename))
70
+ plt.close()
71
+
72
+ # Save frames as a GIF
73
+ gif_filename = './trajectory_animation2.gif'
74
+ frames[0].save(gif_filename, save_all=True, append_images=frames[1:], loop=0, duration=100)
75
+
76
+ # Cleanup temporary frame files
77
+ for frame in frames:
78
+ frame.close()
79
+
80
+ # Cluster the final points using DBSCAN
81
+ clustering = DBSCAN(eps=0.1, min_samples=1).fit(final_points)
82
+ cluster_labels = clustering.labels_
83
+
84
+ # Determine the stable points by averaging the points in each cluster
85
+ stable_points = []
86
+ for label in set(cluster_labels):
87
+ points_in_cluster = np.array(final_points)[cluster_labels == label]
88
+ stable_point = np.around(np.mean(points_in_cluster, axis=0), decimals = 2)
89
+ stable_points.append(stable_point)
90
+
91
+ list_of_lists = [list(arr) + [1 - sum(arr)] for arr in stable_points]
92
+ df = pd.DataFrame(list_of_lists, columns=['x1', 'x2', 'x3'])
93
+
94
+ return gif_filename, df
95
+
96
+
97
+
98
+ iface = gr.Interface(
99
+ fn= create_trajectory_gif,
100
+ inputs=[
101
+ gr.Number( label="Sample Size 1"),
102
+ gr.Number( label="Sample Size 2"),
103
+ gr.Slider(minimum=0, maximum=1, step=0.01, label="Proportion of Cohort 1 (with sample size 1)"),
104
+ gr.Number(label="Payoff u1"),
105
+ gr.Number(label="Payoff u2"),
106
+ gr.Number(label="Payoff u3"),
107
+ gr.Number(label="Timesteps"),
108
+ gr.Number(label="Grid resolution"),
109
+ ],
110
+ outputs=[
111
+ gr.Image(label="Simulation GIF"),
112
+ gr.Dataframe(type="pandas", label="Stable equilibria")
113
+ ],
114
+ examples=[
115
+ [3, 20, 0.1, 1, 2, 2.3, 6, 0.1]
116
+ ]
117
+ )
118
+
119
+ iface.launch()
requirements.txt ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
 
1
+ Pillow
2
+ scipy
3
+ tqdm
4
+ gradio
5
+ matplotlib
6
+ numpy
7
+ pandas
8
+ gradio
9
+ scikit-learn