piegy 2.3.3__tar.gz → 2.3.5__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (34) hide show
  1. {piegy-2.3.3/src/piegy.egg-info → piegy-2.3.5}/PKG-INFO +1 -1
  2. {piegy-2.3.3 → piegy-2.3.5}/pyproject.toml +1 -1
  3. {piegy-2.3.3 → piegy-2.3.5}/src/piegy/C_core/runner.c +3 -4
  4. {piegy-2.3.3 → piegy-2.3.5}/src/piegy/C_core/sim_funcs.c +56 -48
  5. {piegy-2.3.3 → piegy-2.3.5}/src/piegy/C_core/sim_funcs.h +26 -35
  6. {piegy-2.3.3 → piegy-2.3.5}/src/piegy/__version__.py +3 -1
  7. {piegy-2.3.3 → piegy-2.3.5}/src/piegy/figures.py +4 -4
  8. {piegy-2.3.3 → piegy-2.3.5}/src/piegy/simulation.py +4 -8
  9. {piegy-2.3.3 → piegy-2.3.5/src/piegy.egg-info}/PKG-INFO +1 -1
  10. {piegy-2.3.3 → piegy-2.3.5}/LICENSE.txt +0 -0
  11. {piegy-2.3.3 → piegy-2.3.5}/MANIFEST.in +0 -0
  12. {piegy-2.3.3 → piegy-2.3.5}/README.md +0 -0
  13. {piegy-2.3.3 → piegy-2.3.5}/setup.cfg +0 -0
  14. {piegy-2.3.3 → piegy-2.3.5}/setup.py +0 -0
  15. {piegy-2.3.3 → piegy-2.3.5}/src/piegy/C_core/Makefile +0 -0
  16. {piegy-2.3.3 → piegy-2.3.5}/src/piegy/C_core/model.c +0 -0
  17. {piegy-2.3.3 → piegy-2.3.5}/src/piegy/C_core/model.h +0 -0
  18. {piegy-2.3.3 → piegy-2.3.5}/src/piegy/C_core/patch.c +0 -0
  19. {piegy-2.3.3 → piegy-2.3.5}/src/piegy/C_core/patch.h +0 -0
  20. {piegy-2.3.3 → piegy-2.3.5}/src/piegy/__init__.py +0 -0
  21. {piegy-2.3.3 → piegy-2.3.5}/src/piegy/analysis.py +0 -0
  22. {piegy-2.3.3 → piegy-2.3.5}/src/piegy/build_info.py +0 -0
  23. {piegy-2.3.3 → piegy-2.3.5}/src/piegy/data_tools.py +0 -0
  24. {piegy-2.3.3 → piegy-2.3.5}/src/piegy/simulation_py.py +0 -0
  25. {piegy-2.3.3 → piegy-2.3.5}/src/piegy/test_var.py +0 -0
  26. {piegy-2.3.3 → piegy-2.3.5}/src/piegy/tools/__init__.py +0 -0
  27. {piegy-2.3.3 → piegy-2.3.5}/src/piegy/tools/figure_tools.py +0 -0
  28. {piegy-2.3.3 → piegy-2.3.5}/src/piegy/tools/file_tools.py +0 -0
  29. {piegy-2.3.3 → piegy-2.3.5}/src/piegy/tools/find_C.py +0 -0
  30. {piegy-2.3.3 → piegy-2.3.5}/src/piegy/videos.py +0 -0
  31. {piegy-2.3.3 → piegy-2.3.5}/src/piegy.egg-info/SOURCES.txt +0 -0
  32. {piegy-2.3.3 → piegy-2.3.5}/src/piegy.egg-info/dependency_links.txt +0 -0
  33. {piegy-2.3.3 → piegy-2.3.5}/src/piegy.egg-info/requires.txt +0 -0
  34. {piegy-2.3.3 → piegy-2.3.5}/src/piegy.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: piegy
3
- Version: 2.3.3
3
+ Version: 2.3.5
4
4
  Summary: Payoff-Driven Stochastic Spatial Model for Evolutionary Game Theory
5
5
  Author-email: Chenning Xu <cxu7@caltech.edu>
6
6
  License: BSD 3-Clause License
@@ -4,7 +4,7 @@ build-backend = 'setuptools.build_meta'
4
4
 
5
5
  [project]
6
6
  name = 'piegy'
7
- version = '2.3.3'
7
+ version = '2.3.5'
8
8
  description = 'Payoff-Driven Stochastic Spatial Model for Evolutionary Game Theory'
9
9
  readme = 'README.md'
10
10
  requires-python = '>=3.7'
@@ -11,11 +11,11 @@
11
11
  int main() {
12
12
  size_t N = 1;
13
13
  size_t M = 100;
14
- double maxtime = 600;
14
+ double maxtime = 300;
15
15
  double record_itv = 0.1;
16
16
  size_t sim_time = 1;
17
17
  bool boundary = true;
18
- uint32_t I_single[2] = {440, 220};
18
+ uint32_t I_single[2] = {3, 3};
19
19
  double X_single[4] = {-1, 4, 0, 2};
20
20
  double P_single[6] = {0.5, 0.5, 100, 100, 0.001, 0.001};
21
21
  int32_t print_pct = 1;
@@ -46,8 +46,7 @@ int main() {
46
46
  mod_init(mod, N, M, maxtime, record_itv, sim_time, boundary, I, X, P, print_pct, seed);
47
47
 
48
48
  char message[20] = ""; // writable buffer with enough space
49
- uint32_t update_sum_freq = 64;
50
- uint8_t result = run(mod, message, 20, update_sum_freq);
49
+ uint8_t result = run(mod, message, 20);
51
50
 
52
51
  /*for (size_t i = 0; i < mod->max_record; i++) {
53
52
  fprintf(stdout, "%f ", mod->U1d[i]);
@@ -191,7 +191,7 @@ static double single_init(const model_t* mod, patch_t* world, size_t* nb_indices
191
191
 
192
192
 
193
193
 
194
- static uint8_t single_test(model_t* restrict mod, uint32_t update_sum_freq, char* message) {
194
+ static uint8_t single_test(model_t* restrict mod, char* message) {
195
195
  // bring some dimensions to the front
196
196
  size_t N = mod->N;
197
197
  size_t M = mod->M;
@@ -201,9 +201,9 @@ static uint8_t single_test(model_t* restrict mod, uint32_t update_sum_freq, char
201
201
  double record_itv = mod->record_itv;
202
202
  bool boundary = mod->boundary;
203
203
 
204
- double one_time = maxtime / (double)(update_sum_freq > 100 ? update_sum_freq : 100);
204
+ // print progress
205
205
  double one_progress = 0.0;
206
-
206
+ double current_progress = one_progress;
207
207
  if (mod->print_pct != -1) {
208
208
  one_progress = maxtime * mod->print_pct / 100.0;
209
209
  fprintf(stdout, "\r ");
@@ -213,11 +213,11 @@ static uint8_t single_test(model_t* restrict mod, uint32_t update_sum_freq, char
213
213
  one_progress = 2.0 * maxtime;
214
214
  }
215
215
 
216
- double one_update_sum = maxtime / (double) (update_sum_freq + 1);
217
-
218
- double current_time = one_time;
219
- double current_progress = one_progress;
220
- double current_update_sum = one_update_sum;
216
+ // update sum of rates every 1e5 rounds
217
+ // many rates are updated each time, rather than re-calculated.
218
+ // So need to re-calculate from scratch every some time to reduce numerical errors
219
+ size_t curr_update_sum_round = 0; // current round
220
+ size_t update_sum_freq = UPDATE_SUM_FREQ_SM; // the frequency really using, change based on how large values are encountered
221
221
 
222
222
  // Initialize simulation
223
223
  patch_t* world = (patch_t*) calloc(NM, sizeof(patch_t));
@@ -249,47 +249,53 @@ static uint8_t single_test(model_t* restrict mod, uint32_t update_sum_freq, char
249
249
 
250
250
  while (time < maxtime) {
251
251
 
252
- // Print progress and update sums if needed
253
- if (time > current_time) {
254
- current_time += one_time;
255
- if (time > current_progress) {
256
- uint8_t curr_prog = (uint8_t)(time * 100 / maxtime);
257
- if (curr_prog < 10) {
258
- fprintf(stdout, "\r%s: %d %%", message, (int)(time * 100 / maxtime));
259
- } else {
260
- fprintf(stdout, "\r%s: %d%%", message, (int)(time * 100 / maxtime));
261
- }
262
- fflush(stdout);
263
- //fflush(stdout); // Make sure it prints immediately
264
- current_progress += one_progress;
252
+ // Print progress
253
+ if (time > current_progress) {
254
+ uint8_t curr_prog = (uint8_t)(time * 100 / maxtime);
255
+ if (curr_prog < 10) {
256
+ fprintf(stdout, "\r%s: %d %%", message, (int)(time * 100 / maxtime));
257
+ } else {
258
+ fprintf(stdout, "\r%s: %d%%", message, (int)(time * 100 / maxtime));
265
259
  }
266
- if (time > current_update_sum) {
267
- current_update_sum += one_update_sum;
260
+ fflush(stdout);
261
+ //fflush(stdout); // Make sure it prints immediately
262
+ current_progress += one_progress;
263
+ }
264
+
265
+ // update sums
266
+ curr_update_sum_round++;
267
+ if (curr_update_sum_round > update_sum_freq) {
268
+ curr_update_sum_round = 0;
269
+ update_sum_freq = UPDATE_SUM_FREQ_LG; // assume can make it larger
270
+ size_t ij = 0;
268
271
 
269
- // recalculate sum
270
- size_t ij = 0;
271
- for (size_t i = 0; i < N; i++) {
272
- for (size_t j = 0; j < M; j++) {
273
- world[ij].sum_U_weight = 0;
274
- world[ij].sum_V_weight = 0;
275
- for (size_t k = 0; k < 4; k++) {
276
- world[ij].sum_U_weight += world[ij].U_weight[k];
277
- world[ij].sum_V_weight += world[ij].V_weight[k];
278
- }
272
+ for (size_t i = 0; i < N; i++) {
273
+ for (size_t j = 0; j < M; j++) {
274
+ double sum_U_weight = 0;
275
+ double sum_V_weight = 0;
276
+ for (size_t k = 0; k < 4; k++) {
277
+ sum_U_weight += world[ij].U_weight[k];
278
+ sum_V_weight += world[ij].V_weight[k];
279
279
  }
280
- }
281
- ij = 0;
282
- for (size_t i = 0; i < N; i++) {
283
- sum_rates_by_row[i] = 0;
284
- for (size_t j = 0; j < M; j++) {
285
- sum_rates_by_row[i] += patch_rates[ij];
286
- ij++;
280
+ world[ij].sum_U_weight = sum_U_weight;
281
+ world[ij].sum_V_weight = sum_V_weight;
282
+ // patch_rates are updated every time a patch is changed
283
+ if (sum_U_weight > ACCURATE_BOUND) {
284
+ update_sum_freq = UPDATE_SUM_FREQ_SM; // values too large, put back the small update frequency
287
285
  }
286
+ ij++;
288
287
  }
289
- sum_rates = 0;
290
- for (size_t i = 0; i < N; i++) {
291
- sum_rates += sum_rates_by_row[i];
288
+ }
289
+ ij = 0;
290
+ sum_rates = 0;
291
+ for (size_t i = 0; i < N; i++) {
292
+ double sum_rates_by_row_i = 0;
293
+ for (size_t j = 0; j < M; j++) {
294
+ sum_rates_by_row_i += patch_rates[ij];
295
+ ij++;
292
296
  }
297
+ sum_rates_by_row[i] = sum_rates_by_row_i;
298
+ sum_rates += sum_rates_by_row_i;
293
299
  }
294
300
  }
295
301
 
@@ -307,7 +313,7 @@ static uint8_t single_test(model_t* restrict mod, uint32_t update_sum_freq, char
307
313
  sum_rates -= patch_rates[sij1];
308
314
 
309
315
  update_pi_k(&world[sij1], &(mod->X[sij1 * 4]), &(mod->P[sij1 * 6]));
310
- init_mig(&world[sij1], &(mod->P[sij1 * 6]));
316
+ update_mig_just_rate(&world[sij1], &(mod->P[sij1 * 6]));
311
317
 
312
318
  patch_rates[sij1] = world[sij1].sum_pi_death_rates + world[sij1].sum_mig_rates;
313
319
  sum_rates_by_row[si1] += patch_rates[sij1];
@@ -358,7 +364,8 @@ static uint8_t single_test(model_t* restrict mod, uint32_t update_sum_freq, char
358
364
  for (uint8_t k = 0; k < 4; k++) {
359
365
  size_t nb_idx = nb_indices[sij1 * 4 + k];
360
366
  if (nb_idx == NM) { continue; }
361
- if (nb_need_change(nb_idx, sij1, sij2)) {
367
+ if (k != rela_loc) {
368
+ // nb_idx isn't the second last-changed patch
362
369
  if (update_mig_weight_rate(&world[nb_idx], &(mod->P[nb_idx * 6]), k ^ 1) == SIM_OVERFLOW) {
363
370
  fprintf(stdout, "\nError: overflow at t = %f\n", time);
364
371
  fflush(stdout);
@@ -371,7 +378,8 @@ static uint8_t single_test(model_t* restrict mod, uint32_t update_sum_freq, char
371
378
  for (uint8_t k = 0; k < 4; k++) {
372
379
  size_t nb_idx = nb_indices[sij2 * 4 + k];
373
380
  if (nb_idx == NM) { continue; }
374
- if (nb_need_change(nb_idx, sij1, sij2)) {
381
+ if (k != (rela_loc ^ 1)) {
382
+ // nb_idx isn't the first last-changed patch
375
383
  if (update_mig_weight_rate(&world[nb_idx], &(mod->P[nb_idx * 6]), k ^ 1) == SIM_OVERFLOW) {
376
384
  fprintf(stdout, "\nError: overflow at t = %f\n", time);
377
385
  fflush(stdout);
@@ -475,7 +483,7 @@ static void single_test_free(patch_t** world, size_t** nb_indices, double** patc
475
483
 
476
484
 
477
485
 
478
- uint8_t run(model_t* mod, char* message, size_t msg_len, uint32_t update_sum_freq) {
486
+ uint8_t run(model_t* mod, char* message, size_t msg_len) {
479
487
  if (!mod->data_empty) {
480
488
  // this won't happen if called from python, the ``simulation.run`` caller has checked it.
481
489
  fprintf(stdout, "Error: mod has non-empty data\n");
@@ -518,7 +526,7 @@ uint8_t run(model_t* mod, char* message, size_t msg_len, uint32_t update_sum_fre
518
526
  snprintf(end_info, sizeof(end_info), ", ~%.2fs left", pred_runtime);
519
527
  }*/
520
528
 
521
- uint8_t result = single_test(mod, update_sum_freq, curr_msg);
529
+ uint8_t result = single_test(mod, curr_msg);
522
530
 
523
531
  switch (result) {
524
532
  case SUCCESS:
@@ -36,9 +36,14 @@
36
36
  #define SMALL_MAXTIME 2
37
37
  #define SIM_OVERFLOW 3
38
38
 
39
- // where 1 + exp(x) is considered overflow
39
+ // where exp(x) is considered overflow
40
40
  // below the actual bound (709) because the large numbers will be computed with close-to-0 ones (payoff rates), so higher accuracy is needed
41
41
  #define EXP_OVERFLOW_BOUND 500
42
+ #define ACCURATE_BOUND 10000000000LL
43
+
44
+ // how frequent to update rates & sum of rates in single test (recalculate)
45
+ #define UPDATE_SUM_FREQ_SM 100
46
+ #define UPDATE_SUM_FREQ_LG 10000
42
47
 
43
48
 
44
49
  static uint64_t pcg_state = 0;
@@ -87,9 +92,9 @@ static void find_nb_zero_flux(size_t* restrict nb, size_t i, size_t j, size_t N,
87
92
  static void find_nb_periodical(size_t* restrict nb, size_t i, size_t j, size_t N, size_t M, size_t NM);
88
93
  static double single_init(const model_t* mod, patch_t* world, size_t* nb_indices,
89
94
  double* patch_rates, double* sum_rates_by_row, double* sum_rates, signal_t* sig_p, patch_picked_t* picked_p) ;
90
- static uint8_t single_test(model_t* restrict mod, uint32_t update_sum_frequency, char* message);
95
+ static uint8_t single_test(model_t* restrict mod, char* message);
91
96
  static void single_test_free(patch_t** world, size_t** nb_indices, double** patch_rates, double** sum_rates_by_row);
92
- uint8_t run(model_t* mod, char* message, size_t msg_len, uint32_t update_sum_freq);
97
+ uint8_t run(model_t* mod, char* message, size_t msg_len);
93
98
 
94
99
 
95
100
 
@@ -116,19 +121,19 @@ static inline void update_pi_k(patch_t* restrict p, const double* restrict M_sta
116
121
 
117
122
  double U = (double) p->U;
118
123
  double V = (double) p->V;
119
- double sum = U + V - 1;
120
- //double U_ratio = U / sum;
121
- //double V_ratio = V / sum;
124
+ double sum = U + V;
125
+ double U_ratio = U / sum;
126
+ double V_ratio = V / sum;
122
127
 
123
128
  if (sum > 0) {
124
129
  if (U > 0) {
125
- p->U_pi = (U - 1) / sum * M_start[0] + V / sum * M_start[1];
130
+ p->U_pi = U_ratio * M_start[0] + V_ratio * M_start[1];
126
131
  } else {
127
132
  p->U_pi = 0.0;
128
133
  }
129
134
 
130
135
  if (V > 0) {
131
- p->V_pi = U / sum * M_start[2] + (V - 1) / sum * M_start[3];
136
+ p->V_pi = U_ratio * M_start[2] + V_ratio * M_start[3];
132
137
  } else {
133
138
  p->V_pi = 0.0;
134
139
  }
@@ -141,8 +146,8 @@ static inline void update_pi_k(patch_t* restrict p, const double* restrict M_sta
141
146
  p->pi_death_rates[0] = fabs(U * p->U_pi);
142
147
  p->pi_death_rates[1] = fabs(V * p->V_pi);
143
148
 
144
- p->pi_death_rates[2] = P_start[4] * U * (sum + 1);
145
- p->pi_death_rates[3] = P_start[5] * V * (sum + 1);
149
+ p->pi_death_rates[2] = P_start[4] * U * sum;
150
+ p->pi_death_rates[3] = P_start[5] * V * sum;
146
151
 
147
152
  p->sum_pi_death_rates = 0.0;
148
153
  for (size_t i = 0; i < 4; i++) {
@@ -160,7 +165,6 @@ static inline void update_mig_just_rate(patch_t* restrict p, const double* restr
160
165
 
161
166
  double mu1_U = P_start[0] * (double)p->U;
162
167
  double mu2_V = P_start[1] * (double)p->V;
163
- p->sum_mig_rates = mu1_U + mu2_V;
164
168
 
165
169
  double mu1_U_divide_sum = mu1_U / p->sum_U_weight;
166
170
  double mu2_V_divide_sum = mu2_V / p->sum_V_weight;
@@ -169,6 +173,7 @@ static inline void update_mig_just_rate(patch_t* restrict p, const double* restr
169
173
  p->mig_rates[i] = mu1_U_divide_sum * p_U_weight[i];
170
174
  p->mig_rates[i + 4] = mu2_V_divide_sum * p_V_weight[i];
171
175
  }
176
+ p->sum_mig_rates = mu1_U + mu2_V;
172
177
  }
173
178
 
174
179
 
@@ -195,20 +200,20 @@ static inline uint8_t update_mig_weight_rate(patch_t* restrict p, const double*
195
200
 
196
201
  switch(loc) {
197
202
  case MIG_UP:
198
- p_U_weight[MIG_UP] = 1 + exp(w1_Upi);
199
- p_V_weight[MIG_UP] = 1 + exp(w2_Vpi);
203
+ p_U_weight[MIG_UP] = exp(w1_Upi);
204
+ p_V_weight[MIG_UP] = exp(w2_Vpi);
200
205
  break;
201
206
  case MIG_DOWN:
202
- p_U_weight[MIG_DOWN] = 1 + exp(w1_Upi);
203
- p_V_weight[MIG_DOWN] = 1 + exp(w2_Vpi);
207
+ p_U_weight[MIG_DOWN] = exp(w1_Upi);
208
+ p_V_weight[MIG_DOWN] = exp(w2_Vpi);
204
209
  break;
205
210
  case MIG_LEFT:
206
- p_U_weight[MIG_LEFT] = 1 + exp(w1_Upi);
207
- p_V_weight[MIG_LEFT] = 1 + exp(w2_Vpi);
211
+ p_U_weight[MIG_LEFT] = exp(w1_Upi);
212
+ p_V_weight[MIG_LEFT] = exp(w2_Vpi);
208
213
  break;
209
214
  default:
210
- p_U_weight[MIG_RIGHT] = 1 + exp(w1_Upi);
211
- p_V_weight[MIG_RIGHT] = 1 + exp(w2_Vpi);
215
+ p_U_weight[MIG_RIGHT] = exp(w1_Upi);
216
+ p_V_weight[MIG_RIGHT] = exp(w2_Vpi);
212
217
  break;
213
218
  }
214
219
  p->sum_U_weight += p_U_weight[loc];
@@ -244,7 +249,6 @@ static inline uint8_t init_mig(patch_t* restrict p, const double* restrict P_sta
244
249
 
245
250
  for (uint8_t i = 0; i < 4; i++) {
246
251
  patch_t* nbi = p->nb[i];
247
-
248
252
  if (nbi) {
249
253
  // not NULL
250
254
  double w1_Upi = w1 * nbi->U_pi;
@@ -255,15 +259,14 @@ static inline uint8_t init_mig(patch_t* restrict p, const double* restrict P_sta
255
259
  if (w2_Vpi > EXP_OVERFLOW_BOUND) {
256
260
  return SIM_OVERFLOW;
257
261
  }
258
- p_U_weight[i] = 1 + exp(w1_Upi);
259
- p_V_weight[i] = 1 + exp(w2_Vpi);
262
+ p_U_weight[i] = exp(w1_Upi);
263
+ p_V_weight[i] = exp(w2_Vpi);
260
264
 
261
265
  p->sum_U_weight += p_U_weight[i];
262
266
  p->sum_V_weight += p_V_weight[i];
263
267
  }
264
268
  }
265
269
 
266
-
267
270
  double mu1_U = P_start[0] * (double)p->U;
268
271
  double mu2_V = P_start[1] * (double)p->V;
269
272
  double mu1_U_divide_sum = mu1_U / p->sum_U_weight;
@@ -582,16 +585,4 @@ static inline void make_signal_periodical(size_t N, size_t M, size_t i, size_t j
582
585
  }
583
586
 
584
587
 
585
- static inline bool nb_need_change(size_t nb_idx, size_t sij1, size_t sij2) {
586
- // a nb doesn't need change only if two patches are updated
587
-
588
- // or, can try this 1-line version
589
- // return (nb_idx != sij1) && (nb_idx != sij2);
590
- if ((nb_idx == sij1) || (nb_idx == sij2)) {
591
- return false;
592
- }
593
- return true; // need to change
594
- }
595
-
596
-
597
588
  #endif
@@ -1,4 +1,4 @@
1
- __version__ = '2.3.3'
1
+ __version__ = '2.3.4'
2
2
 
3
3
  '''
4
4
  version history:
@@ -40,4 +40,6 @@ version history:
40
40
  2.3.2: allow play-with-self in payoff calculation. Changed migration function to e^(w*pi) (removed "1+" term).
41
41
  Simplified update-migration functions, improve speed by ~10%. Add -march=native flag to Makefile.
42
42
  2.3.3: fix error in calculation of migration rates.
43
+ 2.3.4: change back to the mig & payoff rules in version 2.3.2
44
+ 2.3.5: improved accuracy for simulation, now can better handle large mig rates. Numerical errors are now being checked and reduced automatically based on how large the values are.
43
45
  '''
@@ -530,19 +530,19 @@ def video_fig(mod, ax_list = None, num_grid = 100, U_color = 'Purples', V_color
530
530
 
531
531
 
532
532
  im = ax_list[0, 0].imshow(ave_U, cmap = U_color)
533
- ax_list[0, 0].get_figure().colorbar(im, ax = ax_list[0, 0])
533
+ ax_list[0, 0].get_figure().colorbar(im, ax = ax_list[0, 0], extent = [0, mod.N * mod.M, 0, mod.maxtime], origin='lower', aspect = 'auto')
534
534
  ax_list[0, 0].set_title('Population U over time')
535
535
 
536
536
  im = ax_list[0, 1].imshow(ave_V, cmap = V_color)
537
- ax_list[0, 1].get_figure().colorbar(im, ax = ax_list[0, 1])
537
+ ax_list[0, 1].get_figure().colorbar(im, ax = ax_list[0, 1], extent = [0, mod.N * mod.M, 0, mod.maxtime], origin='lower', aspect = 'auto')
538
538
  ax_list[0, 1].set_title('Population V over time')
539
539
 
540
540
  im = ax_list[1, 0].imshow(ave_Upi, cmap = U_color)
541
- ax_list[1, 0].get_figure().colorbar(im, ax = ax_list[1, 0])
541
+ ax_list[1, 0].get_figure().colorbar(im, ax = ax_list[1, 0], extent = [0, mod.N * mod.M, 0, mod.maxtime], origin='lower', aspect = 'auto')
542
542
  ax_list[1, 0].set_title('Payoff ' + r'$p_H$' + ' over time')
543
543
 
544
544
  im = ax_list[1, 1].imshow(ave_Vpi, cmap = V_color)
545
- ax_list[1, 1].get_figure().colorbar(im, ax = ax_list[1, 1])
545
+ ax_list[1, 1].get_figure().colorbar(im, ax = ax_list[1, 1], extent = [0, mod.N * mod.M, 0, mod.maxtime], origin='lower', aspect = 'auto')
546
546
  ax_list[1, 1].set_title('Payoff ' + r'$p_D$' + ' over time')
547
547
 
548
548
  return ax_list
@@ -25,11 +25,7 @@ from numpy.ctypeslib import ndpointer
25
25
  # check whether overflow / too large values might be encountered
26
26
  # these values are considered as exponents in exp()
27
27
  EXP_OVERFLOW_BOUND = 709 # where exp(x) almost reaches overflow bound
28
- EXP_TOO_LARGE_BOUND = 88 # where exp(x) reaches 1e20
29
-
30
- # how frequent to update sum in simulation, i.e., accuracy
31
- # the defuault value is 64, increase to 4 times if encounter error
32
- UPDATE_SUM_FREQ = 64
28
+ EXP_TOO_LARGE_BOUND = 88 # where exp(x) reaches 1e34
33
29
 
34
30
 
35
31
  # read the C core into LIB
@@ -101,7 +97,7 @@ def read_lib():
101
97
  LIB.mod_free_py.argtypes = [ctypes.POINTER(model_c)]
102
98
  LIB.mod_free_py.restype = None
103
99
 
104
- LIB.run.argtypes = [ctypes.POINTER(model_c), ctypes.POINTER(c_char), c_size_t, c_uint32]
100
+ LIB.run.argtypes = [ctypes.POINTER(model_c), ctypes.POINTER(c_char), c_size_t]
105
101
  LIB.run.restype = c_ubyte # which is uint8
106
102
 
107
103
 
@@ -410,7 +406,7 @@ class model:
410
406
 
411
407
 
412
408
 
413
- def run(mod, message = "", update_sum_freq = UPDATE_SUM_FREQ):
409
+ def run(mod, message = ""):
414
410
  '''
415
411
  C-cored simulation
416
412
  '''
@@ -437,7 +433,7 @@ def run(mod, message = "", update_sum_freq = UPDATE_SUM_FREQ):
437
433
  del mod_c
438
434
  raise RuntimeError('Model initialization failed')
439
435
 
440
- result = LIB.run(ctypes.byref(mod_c), msg_buffer, msg_len, update_sum_freq)
436
+ result = LIB.run(ctypes.byref(mod_c), msg_buffer, msg_len)
441
437
 
442
438
  if result == SIM_SUCCESS:
443
439
  mod.set_data(False, mod.max_record, 1, mod_c.get_array('U1d').reshape(mod.N, mod.M, mod.max_record),
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: piegy
3
- Version: 2.3.3
3
+ Version: 2.3.5
4
4
  Summary: Payoff-Driven Stochastic Spatial Model for Evolutionary Game Theory
5
5
  Author-email: Chenning Xu <cxu7@caltech.edu>
6
6
  License: BSD 3-Clause License
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes