piegy 2.3.7__tar.gz → 2.3.8__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 (33) hide show
  1. {piegy-2.3.7/src/piegy.egg-info → piegy-2.3.8}/PKG-INFO +1 -1
  2. {piegy-2.3.7 → piegy-2.3.8}/pyproject.toml +1 -1
  3. {piegy-2.3.7 → piegy-2.3.8}/src/piegy/C_core/patch.c +20 -14
  4. {piegy-2.3.7 → piegy-2.3.8}/src/piegy/C_core/patch.h +6 -3
  5. {piegy-2.3.7 → piegy-2.3.8}/src/piegy/C_core/sim_funcs.c +62 -58
  6. {piegy-2.3.7 → piegy-2.3.8}/src/piegy/C_core/sim_funcs.h +21 -29
  7. {piegy-2.3.7 → piegy-2.3.8}/src/piegy/__init__.py +2 -2
  8. {piegy-2.3.7 → piegy-2.3.8}/src/piegy/__version__.py +2 -1
  9. {piegy-2.3.7 → piegy-2.3.8}/src/piegy/data_tools.py +4 -4
  10. {piegy-2.3.7 → piegy-2.3.8}/src/piegy/simulation.py +3 -3
  11. {piegy-2.3.7 → piegy-2.3.8}/src/piegy/test_var.py +8 -8
  12. {piegy-2.3.7 → piegy-2.3.8/src/piegy.egg-info}/PKG-INFO +1 -1
  13. {piegy-2.3.7 → piegy-2.3.8}/LICENSE.txt +0 -0
  14. {piegy-2.3.7 → piegy-2.3.8}/MANIFEST.in +0 -0
  15. {piegy-2.3.7 → piegy-2.3.8}/README.md +0 -0
  16. {piegy-2.3.7 → piegy-2.3.8}/setup.cfg +0 -0
  17. {piegy-2.3.7 → piegy-2.3.8}/setup.py +0 -0
  18. {piegy-2.3.7 → piegy-2.3.8}/src/piegy/C_core/Makefile +0 -0
  19. {piegy-2.3.7 → piegy-2.3.8}/src/piegy/C_core/model.c +0 -0
  20. {piegy-2.3.7 → piegy-2.3.8}/src/piegy/C_core/model.h +0 -0
  21. {piegy-2.3.7 → piegy-2.3.8}/src/piegy/analysis.py +0 -0
  22. {piegy-2.3.7 → piegy-2.3.8}/src/piegy/build_info.py +0 -0
  23. {piegy-2.3.7 → piegy-2.3.8}/src/piegy/figures.py +0 -0
  24. {piegy-2.3.7 → piegy-2.3.8}/src/piegy/simulation_py.py +0 -0
  25. {piegy-2.3.7 → piegy-2.3.8}/src/piegy/tools/__init__.py +0 -0
  26. {piegy-2.3.7 → piegy-2.3.8}/src/piegy/tools/figure_tools.py +0 -0
  27. {piegy-2.3.7 → piegy-2.3.8}/src/piegy/tools/file_tools.py +0 -0
  28. {piegy-2.3.7 → piegy-2.3.8}/src/piegy/tools/find_C.py +0 -0
  29. {piegy-2.3.7 → piegy-2.3.8}/src/piegy/videos.py +0 -0
  30. {piegy-2.3.7 → piegy-2.3.8}/src/piegy.egg-info/SOURCES.txt +0 -0
  31. {piegy-2.3.7 → piegy-2.3.8}/src/piegy.egg-info/dependency_links.txt +0 -0
  32. {piegy-2.3.7 → piegy-2.3.8}/src/piegy.egg-info/requires.txt +0 -0
  33. {piegy-2.3.7 → piegy-2.3.8}/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.7
3
+ Version: 2.3.8
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.7'
7
+ version = '2.3.8'
8
8
  description = 'Payoff-Driven Stochastic Spatial Model for Evolutionary Game Theory'
9
9
  readme = 'README.md'
10
10
  requires-python = '>=3.7'
@@ -5,32 +5,38 @@
5
5
 
6
6
  #include "patch.h"
7
7
 
8
- void patch_init(patch_t* p, uint32_t U, uint32_t V, size_t row, size_t col) {
8
+ void patch_init(patch_t* p, uint32_t U, uint32_t V, size_t row, size_t col, double* X_start, double* P_start) {
9
9
  if (p == NULL) return;
10
10
  p->row = row;
11
11
  p->col = col;
12
12
 
13
13
  p->U = U;
14
14
  p->V = V;
15
- p->U_pi = 0.0;
16
- p->V_pi = 0.0;
15
+ p->U_pi = 0;
16
+ p->V_pi = 0;
17
+
18
+ memcpy(p->X, X_start, 4 * sizeof(double));
19
+ memcpy(p->P, P_start, 6 * sizeof(double));
20
+ for (size_t i = 0; i < 6; i++) {
21
+ p->P[i] = P_start[i];
22
+ }
17
23
 
18
24
  for (size_t i = 0; i < 4; i++) {
19
- p->U_weight[i] = 0.0;
20
- p->V_weight[i] = 0.0;
21
- p->pi_death_rates[i] = 0.0;
25
+ p->U_weight[i] = 0;
26
+ p->V_weight[i] = 0;
27
+ p->pi_death_rates[i] = 0;
22
28
  }
23
29
  for (size_t i = 0; i < 8; i++) {
24
- p->mig_rates[i] = 0.0;
30
+ p->mig_rates[i] = 0;
25
31
  }
26
- p->sum_U_weight = 0.0;
27
- p->sum_V_weight = 0.0;
28
- p->sum_pi_death_rates = 0.0;
29
- p->sum_mig_rates = 0.0;
32
+ p->sum_U_weight = 0;
33
+ p->sum_V_weight = 0;
34
+ p->sum_pi_death_rates = 0;
35
+ p->sum_mig_rates = 0;
30
36
  }
31
37
 
32
38
 
33
- void set_nb(patch_t* world, double* P_start, size_t* nb_start, size_t ij, size_t NM) {
39
+ void set_nb(patch_t* world, size_t* nb_start, size_t ij, size_t NM) {
34
40
  // nb_start is the where patch ij's neighbor indices start
35
41
  size_t num_nb = 0;
36
42
  for (size_t k = 0; k < 4; k++) {
@@ -42,6 +48,6 @@ void set_nb(patch_t* world, double* P_start, size_t* nb_start, size_t ij, size_t
42
48
  world[ij].nb[k] = NULL;
43
49
  }
44
50
  }
45
- P_start[0] *= (0.25 * num_nb); // scale total migration rates by how many neighbors the patch has
46
- P_start[1] *= (0.25 * num_nb);
51
+ world[ij].P[0] *= (0.25 * num_nb);
52
+ world[ij].P[1] *= (0.25 * num_nb);
47
53
  }
@@ -10,7 +10,7 @@
10
10
  #include <stdio.h>
11
11
  #include <stdint.h>
12
12
  #include <stdbool.h>
13
-
13
+ #include <string.h>
14
14
 
15
15
 
16
16
  typedef struct patch_t {
@@ -22,6 +22,9 @@ typedef struct patch_t {
22
22
  double U_pi;
23
23
  double V_pi;
24
24
 
25
+ double X[4]; // a copy of matrix and patch variables (mu, w, kappa)
26
+ double P[6];
27
+
25
28
  struct patch_t* nb[4];
26
29
  double U_weight[4]; // stores migration weight of each of the 4 neighbors
27
30
  double V_weight[4];
@@ -34,8 +37,8 @@ typedef struct patch_t {
34
37
  } patch_t;
35
38
 
36
39
  // in .c
37
- void patch_init(patch_t* p, uint32_t U, uint32_t V, size_t row, size_t col);
38
- void set_nb(patch_t* world, double* P_start, size_t* nb_start, size_t ij, size_t NM) ;
40
+ void patch_init(patch_t* p, uint32_t U, uint32_t V, size_t row, size_t col, double* X_start, double* P_start);
41
+ void set_nb(patch_t* world, size_t* nb_start, size_t ij, size_t NM) ;
39
42
 
40
43
  #endif // PATCH_H
41
44
 
@@ -81,7 +81,7 @@ static double single_init(const model_t* restrict mod, patch_t* restrict world,
81
81
  // init world
82
82
  for (size_t i = 0; i < N; i++) {
83
83
  for (size_t j = 0; j < M; j++) {
84
- patch_init(&world[ij_out], mod->I[ij_out * 2], mod->I[ij_out * 2 + 1], i, j);
84
+ patch_init(&world[ij_out], mod->I[ij_out * 2], mod->I[ij_out * 2 + 1], i, j, &(mod->X[ij_out * 4]), &(mod->P[ij_out * 6]));
85
85
  ij_out++;
86
86
  }
87
87
  }
@@ -107,21 +107,21 @@ static double single_init(const model_t* restrict mod, patch_t* restrict world,
107
107
 
108
108
  // set nb pointers for patches
109
109
  for (size_t ij = 0; ij < NM; ij++) {
110
- set_nb(world, &(mod->P[ij * 6]), &nb_indices[ij * 4], ij, NM);
110
+ set_nb(world, &nb_indices[ij * 4], ij, NM);
111
111
  }
112
112
 
113
113
  //////// Begin Running ////////
114
114
 
115
115
  // init payoff & natural death rates
116
116
  for (size_t ij = 0; ij < N; ij++) {
117
- update_pi_k(&world[ij], &(mod->X[ij * 4]), &(mod->P[ij * 6]));
117
+ update_pi_k(&world[ij]);
118
118
  }
119
119
 
120
120
  // init migration rates & store patch rates
121
121
  ij_out = 0;
122
122
  for (size_t i = 0; i < N; i++) {
123
123
  for (size_t j = 0; j < M; j++) {
124
- uint8_t mig_result = init_mig(&world[ij_out], &(mod->P[ij_out * 6])); // init mig rates for all 4 directions
124
+ uint8_t mig_result = init_mig(&world[ij_out]); // init mig rates for all 4 directions
125
125
  if (mig_result == SIM_OVERFLOW) {
126
126
  return -1 * SIM_OVERFLOW;
127
127
  }
@@ -164,7 +164,7 @@ static double single_init(const model_t* restrict mod, patch_t* restrict world,
164
164
  // maxtime too small
165
165
  return -1 * SMALL_MAXTIME;
166
166
  }
167
-
167
+
168
168
  // store data
169
169
  if (time > mod->record_itv) {
170
170
  size_t recod_idx = (size_t) (time / mod->record_itv);
@@ -194,24 +194,10 @@ static uint8_t single_test(model_t* restrict mod, char* message) {
194
194
  size_t max_record = mod->max_record;
195
195
  double record_itv = mod->record_itv;
196
196
  bool boundary = mod->boundary;
197
- double* X = mod->X;
198
- double* P = mod->P;
199
- double* U1d = mod->U1d;
200
- double* V1d = mod->V1d;
201
- double* Upi_1d = mod->Upi_1d;
202
- double* Vpi_1d = mod->Vpi_1d;
203
-
204
- // print progress
205
- double one_progress = 0.0;
206
- if (mod->print_pct != -1) {
207
- one_progress = maxtime * mod->print_pct / 100.0;
208
- fprintf(stdout, "\r ");
209
- fprintf(stdout, "\r%s: 0 %%", message);
210
- fflush(stdout);
211
- } else {
212
- one_progress = 2.0 * maxtime;
213
- }
214
- double current_progress = one_progress;
197
+ double* mod_U1d = mod->U1d;
198
+ double* mod_V1d = mod->V1d;
199
+ double* mod_Upi_1d = mod->Upi_1d;
200
+ double* mod_Vpi_1d = mod->Vpi_1d;
215
201
 
216
202
  // update sum of rates every 1e5 rounds
217
203
  // many rates are updated each time, rather than re-calculated.
@@ -219,10 +205,9 @@ static uint8_t single_test(model_t* restrict mod, char* message) {
219
205
  size_t curr_update_sum_round = 0; // current round
220
206
  size_t update_sum_freq = UPDATE_SUM_ROUNDS_SM; // recalculate sum every this many rounds
221
207
 
222
- // Initialize simulation
208
+ // core containers
223
209
  patch_t* world = (patch_t*) calloc(NM, sizeof(patch_t));
224
210
  size_t* nb_indices = (size_t*) calloc(NM * 4, sizeof(size_t));
225
-
226
211
  double* patch_rates = (double*) calloc(NM, sizeof(double));
227
212
  double* sum_rates_by_row = (double*) calloc(N, sizeof(double));
228
213
  double sum_rates = 0;
@@ -230,6 +215,17 @@ static uint8_t single_test(model_t* restrict mod, char* message) {
230
215
  signal_t signal;
231
216
  patch_picked_t picked;
232
217
 
218
+ // print progress
219
+ double one_progress = one_progress = 2.0 * maxtime;
220
+ if (mod->print_pct != -1) {
221
+ one_progress = maxtime * mod->print_pct / 100.0;
222
+ fprintf(stdout, "\r ");
223
+ fprintf(stdout, "\r%s: 0 %%", message);
224
+ fflush(stdout);
225
+ }
226
+ double current_progress = one_progress;
227
+
228
+ // Call single_init. Initialize rates and run for 1 event
233
229
  double time = single_init(mod, world, nb_indices, patch_rates, sum_rates_by_row, &sum_rates, &signal, &picked);
234
230
  if (time == -1 * SMALL_MAXTIME) {
235
231
  // time too small
@@ -251,9 +247,10 @@ static uint8_t single_test(model_t* restrict mod, char* message) {
251
247
  size_t record_index = (size_t) (time / mod->record_itv);
252
248
  double record_time = time - record_index * record_itv;
253
249
 
250
+ //////// while loop ////////
254
251
 
255
252
  while (time < maxtime) {
256
-
253
+
257
254
  // update sums and print progress
258
255
  curr_update_sum_round++;
259
256
  if (curr_update_sum_round > update_sum_freq) {
@@ -268,7 +265,9 @@ static uint8_t single_test(model_t* restrict mod, char* message) {
268
265
  fprintf(stdout, "\r%s: %d%%", message, (int)(time * 100 / maxtime));
269
266
  }
270
267
  fflush(stdout);
271
- //fflush(stdout); // Make sure it prints immediately
268
+ //fprintf(stdout, "\n99: %d, %d, %f, %f\n100: %d, %d, %f, %f\n",
269
+ //world[98].U, world[98].V, world[98].mig_rates[3], world[98].mig_rates[7], world[99].U, world[99].V, world[99].mig_rates[2], world[99].mig_rates[6]);
270
+ //fflush(stdout);
272
271
  current_progress += one_progress;
273
272
  }
274
273
 
@@ -315,8 +314,8 @@ static uint8_t single_test(model_t* restrict mod, char* message) {
315
314
  sum_rates_by_row[si1] -= patch_rates[sij1];
316
315
  sum_rates -= patch_rates[sij1];
317
316
 
318
- update_pi_k(&world[sij1], &(X[sij1 * 4]), &(P[sij1 * 6]));
319
- update_mig_just_rate(&world[sij1], &(P[sij1 * 6]));
317
+ update_pi_k(&world[sij1]);
318
+ update_mig_just_rate(&world[sij1]);
320
319
 
321
320
  patch_rates[sij1] = world[sij1].sum_pi_death_rates + world[sij1].sum_mig_rates;
322
321
  sum_rates_by_row[si1] += patch_rates[sij1];
@@ -328,11 +327,11 @@ static uint8_t single_test(model_t* restrict mod, char* message) {
328
327
  sum_rates -= patch_rates[sij1];
329
328
  sum_rates -= patch_rates[sij2];
330
329
 
331
- update_pi_k(&world[sij1], &(X[sij1 * 4]), &(P[sij1 * 6])); // update both patches' payoffs first
332
- update_pi_k(&world[sij2], &(X[sij2 * 4]), &(P[sij2 * 6]));
330
+ update_pi_k(&world[sij1]); // update both patches' payoffs first
331
+ update_pi_k(&world[sij2]);
333
332
 
334
- if (update_mig_weight_rate(&world[sij1], &(P[sij1 * 6]), rela_loc) == SIM_OVERFLOW ||
335
- update_mig_weight_rate(&world[sij2], &(P[sij2 * 6]), rela_loc ^ 1) == SIM_OVERFLOW) {
333
+ if (update_mig_weight_rate(&world[sij1], rela_loc) == SIM_OVERFLOW ||
334
+ update_mig_weight_rate(&world[sij2], rela_loc ^ 1) == SIM_OVERFLOW) {
336
335
 
337
336
  fprintf(stdout, "\nError: overflow at t = %f\n", time);
338
337
  fflush(stdout);
@@ -354,7 +353,7 @@ static uint8_t single_test(model_t* restrict mod, char* message) {
354
353
  size_t nb_idx = nb_indices[sij1 * 4 + k];
355
354
  if (nb_idx == NM) { continue; } // invalid neighbor
356
355
  // all neighbors, as long as exists, need to change
357
- if (update_mig_weight_rate(&world[nb_idx], &(P[nb_idx * 6]), k ^ 1) == SIM_OVERFLOW) {
356
+ if (update_mig_weight_rate(&world[nb_idx], k ^ 1) == SIM_OVERFLOW) {
358
357
  fprintf(stdout, "\nError: overflow at t = %f\n", time);
359
358
  fflush(stdout);
360
359
  single_test_free(&world, &nb_indices, &patch_rates, &sum_rates_by_row);
@@ -369,7 +368,7 @@ static uint8_t single_test(model_t* restrict mod, char* message) {
369
368
  if (nb_idx == NM) { continue; }
370
369
  if (k != rela_loc) {
371
370
  // nb_idx isn't the second last-changed patch
372
- if (update_mig_weight_rate(&world[nb_idx], &(P[nb_idx * 6]), k ^ 1) == SIM_OVERFLOW) {
371
+ if (update_mig_weight_rate(&world[nb_idx], k ^ 1) == SIM_OVERFLOW) {
373
372
  fprintf(stdout, "\nError: overflow at t = %f\n", time);
374
373
  fflush(stdout);
375
374
  single_test_free(&world, &nb_indices, &patch_rates, &sum_rates_by_row);
@@ -383,7 +382,7 @@ static uint8_t single_test(model_t* restrict mod, char* message) {
383
382
  if (nb_idx == NM) { continue; }
384
383
  if (k != (rela_loc ^ 1)) {
385
384
  // nb_idx isn't the first last-changed patch
386
- if (update_mig_weight_rate(&world[nb_idx], &(P[nb_idx * 6]), k ^ 1) == SIM_OVERFLOW) {
385
+ if (update_mig_weight_rate(&world[nb_idx], k ^ 1) == SIM_OVERFLOW) {
387
386
  fprintf(stdout, "\nError: overflow at t = %f\n", time);
388
387
  fflush(stdout);
389
388
  single_test_free(&world, &nb_indices, &patch_rates, &sum_rates_by_row);
@@ -393,7 +392,6 @@ static uint8_t single_test(model_t* restrict mod, char* message) {
393
392
  }
394
393
  }
395
394
 
396
-
397
395
  // pick a random event
398
396
  double expected_sum = random01() * sum_rates;
399
397
  find_patch(&picked, expected_sum, patch_rates, sum_rates_by_row, sum_rates, N, M);
@@ -413,7 +411,7 @@ static uint8_t single_test(model_t* restrict mod, char* message) {
413
411
  make_signal_periodical(N, M, picked.i, picked.j, e0, &signal);
414
412
  }
415
413
  signal.ij1 = signal.i1 * M + signal.j1;
416
- signal.ij2 = signal.i2 * M + signal.j2;
414
+ signal.ij2 = signal.i2 * M + signal.j2;
417
415
 
418
416
  // let the event happenn
419
417
  change_popu(&world[signal.ij1], signal.e1);
@@ -436,10 +434,10 @@ static uint8_t single_test(model_t* restrict mod, char* message) {
436
434
  for (size_t ij = 0; ij < NM; ij++) {
437
435
  size_t ij_max_record = ij * max_record;
438
436
  for (size_t k = record_index; k < upper; k++) {
439
- U1d[ij_max_record + k] += world[ij].U;
440
- V1d[ij_max_record + k] += world[ij].V;
441
- Upi_1d[ij_max_record + k] += world[ij].U_pi;
442
- Vpi_1d[ij_max_record + k] += world[ij].V_pi;
437
+ mod_U1d[ij_max_record + k] += world[ij].U;
438
+ mod_V1d[ij_max_record + k] += world[ij].V;
439
+ mod_Upi_1d[ij_max_record + k] += world[ij].U_pi;
440
+ mod_Vpi_1d[ij_max_record + k] += world[ij].V_pi;
443
441
  }
444
442
  }
445
443
  record_index += multi_records;
@@ -450,10 +448,10 @@ static uint8_t single_test(model_t* restrict mod, char* message) {
450
448
  for (size_t ij = 0; ij < NM; ij++) {
451
449
  size_t ij_max_record = ij * max_record;
452
450
  for (size_t k = record_index; k < max_record; k++) {
453
- U1d[ij_max_record + k] += world[ij].U;
454
- V1d[ij_max_record + k] += world[ij].V;
455
- Upi_1d[ij_max_record + k] += world[ij].U_pi;
456
- Vpi_1d[ij_max_record + k] += world[ij].V_pi;
451
+ mod_U1d[ij_max_record + k] += world[ij].U;
452
+ mod_V1d[ij_max_record + k] += world[ij].V;
453
+ mod_Upi_1d[ij_max_record + k] += world[ij].U_pi;
454
+ mod_Vpi_1d[ij_max_record + k] += world[ij].V_pi;
457
455
  }
458
456
  }
459
457
  }
@@ -513,27 +511,33 @@ uint8_t run(model_t* restrict mod, char* message, size_t msg_len) {
513
511
 
514
512
  if (mod->print_pct == 0) {
515
513
  mod->print_pct = 5; // default print_pct
514
+ }
515
+ size_t print_round = 0; // print every some round if print_pct == x * 100, set to 0 for not printing
516
+ if (mod->print_pct >= 100) {
517
+ print_round = mod->print_pct / 100; // print progress every some round
518
+ mod->print_pct = -1; // not printing progress in single_test
516
519
  }
517
520
 
518
- size_t i = 0;
521
+ size_t round = 0;
519
522
 
520
- while (i < mod->sim_time) {
523
+ while (round < mod->sim_time) {
521
524
  char curr_msg[100 + msg_len]; // message for current round
522
525
  strcpy(curr_msg, message);
523
526
  strcat(curr_msg, "round ");
524
- snprintf(curr_msg + strlen(curr_msg), sizeof(curr_msg) - strlen(curr_msg), "%zu", i);
527
+ snprintf(curr_msg + strlen(curr_msg), sizeof(curr_msg) - strlen(curr_msg), "%zu", round);
525
528
 
526
- /*if (predict_runtime && i > 0) {
527
- double time_elapsed = timer() - start;
528
- double pred_runtime = time_elapsed / i * (mod->sim_time - i);
529
- snprintf(end_info, sizeof(end_info), ", ~%.2fs left", pred_runtime);
530
- }*/
529
+ if ((print_round != 0) && (round % print_round == 0)) {
530
+ // only printing the round number
531
+ // add "!= 0" because round 0 could trigger printing
532
+ fprintf(stdout, "\r%s", curr_msg);
533
+ fflush(stdout);
534
+ }
531
535
 
532
536
  uint8_t result = single_test(mod, curr_msg);
533
537
 
534
538
  switch (result) {
535
539
  case SUCCESS:
536
- i++;
540
+ round++;
537
541
  break;
538
542
  case SMALL_MAXTIME:
539
543
  // error message is handled by single_test
@@ -549,9 +553,9 @@ uint8_t run(model_t* restrict mod, char* message, size_t msg_len) {
549
553
 
550
554
  calculate_ave(mod);
551
555
 
552
- double stop = clock();
553
-
554
- if (mod->print_pct != -1) {
556
+ if ((mod->print_pct != -1) || (print_round != 0)) {
557
+ // print runtime if the original mod->print_pct != -1
558
+ double stop = clock();
555
559
  fprintf(stdout, "\r%sruntime: %.3fs \n", message, (double)(stop - start) / CLOCKS_PER_SEC);
556
560
  fflush(stdout);
557
561
  }
@@ -122,10 +122,8 @@ static inline double random01() {
122
122
  * patch functions
123
123
  */
124
124
 
125
- static inline void update_pi_k(patch_t* restrict p, const double* restrict M_start, const double* restrict P_start) {
126
- // M_start: start index of patch (i, j)'s matrix
127
- // P_start: start index of p's patch variables, i.e., ij * 6
128
-
125
+ static inline void update_pi_k(patch_t* restrict p) {
126
+ // update payoff and carrying capacity rates
129
127
  uint32_t U = p->U;
130
128
  uint32_t V = p->V;
131
129
  double sum = U + V;
@@ -134,13 +132,13 @@ static inline void update_pi_k(patch_t* restrict p, const double* restrict M_sta
134
132
 
135
133
  if (sum > 0) {
136
134
  if (U > 0) {
137
- p->U_pi = U_ratio * M_start[0] + V_ratio * M_start[1];
135
+ p->U_pi = U_ratio * p->X[0] + V_ratio * p->X[1];
138
136
  } else {
139
137
  p->U_pi = 0.0;
140
138
  }
141
139
 
142
140
  if (V > 0) {
143
- p->V_pi = U_ratio * M_start[2] + V_ratio * M_start[3];
141
+ p->V_pi = U_ratio * p->X[2] + V_ratio * p->X[3];
144
142
  } else {
145
143
  p->V_pi = 0.0;
146
144
  }
@@ -153,8 +151,8 @@ static inline void update_pi_k(patch_t* restrict p, const double* restrict M_sta
153
151
  p->pi_death_rates[0] = fabs(U * p->U_pi);
154
152
  p->pi_death_rates[1] = fabs(V * p->V_pi);
155
153
 
156
- p->pi_death_rates[2] = P_start[4] * U * sum;
157
- p->pi_death_rates[3] = P_start[5] * V * sum;
154
+ p->pi_death_rates[2] = p->P[4] * U * sum;
155
+ p->pi_death_rates[3] = p->P[5] * V * sum;
158
156
 
159
157
  p->sum_pi_death_rates = 0.0;
160
158
  for (size_t i = 0; i < 4; i++) {
@@ -164,14 +162,14 @@ static inline void update_pi_k(patch_t* restrict p, const double* restrict M_sta
164
162
 
165
163
 
166
164
 
167
- static inline void update_mig_just_rate(patch_t* restrict p, const double* restrict P_start) {
165
+ static inline void update_mig_just_rate(patch_t* restrict p) {
168
166
  // update migration weight for patch p, in location loc. Only rate is updated
169
167
  // used by last-changed patch, when there is only one last-changed patch
170
168
  double* p_U_weight = p->U_weight;
171
169
  double* p_V_weight = p->V_weight;
172
170
 
173
- double mu1_U = P_start[0] * p->U;
174
- double mu2_V = P_start[1] * p->V;
171
+ double mu1_U = p->P[0] * p->U;
172
+ double mu2_V = p->P[1] * p->V;
175
173
 
176
174
  double mu1_U_divide_sum = mu1_U / p->sum_U_weight;
177
175
  double mu2_V_divide_sum = mu2_V / p->sum_V_weight;
@@ -184,7 +182,7 @@ static inline void update_mig_just_rate(patch_t* restrict p, const double* restr
184
182
  }
185
183
 
186
184
 
187
- static inline uint8_t update_mig_weight_rate(patch_t* restrict p, const double* P_start, uint8_t loc) {
185
+ static inline uint8_t update_mig_weight_rate(patch_t* restrict p, uint8_t loc) {
188
186
  // update migration weight as well as rates, in one direction
189
187
  // used by neighbors of last-changed patches
190
188
  // also used by last-changed patches themselve, when there are two patch changed, to update mig rates of in each other's direction
@@ -196,8 +194,8 @@ static inline uint8_t update_mig_weight_rate(patch_t* restrict p, const double*
196
194
  p->sum_U_weight -= p_U_weight[loc];
197
195
  p->sum_V_weight -= p_V_weight[loc];
198
196
 
199
- double w1_Upi = P_start[2] * nbi->U_pi;
200
- double w2_Vpi = P_start[3] * nbi->V_pi;
197
+ double w1_Upi = p->P[2] * nbi->U_pi;
198
+ double w2_Vpi = p->P[3] * nbi->V_pi;
201
199
  if (w1_Upi > EXP_OVERFLOW_BOUND) {
202
200
  return SIM_OVERFLOW;
203
201
  }
@@ -226,8 +224,8 @@ static inline uint8_t update_mig_weight_rate(patch_t* restrict p, const double*
226
224
  p->sum_U_weight += p_U_weight[loc];
227
225
  p->sum_V_weight += p_V_weight[loc];
228
226
 
229
- double mu1_U = P_start[0] * (double)p->U;
230
- double mu2_V = P_start[1] * (double)p->V;
227
+ double mu1_U = p->P[0] * p->U;
228
+ double mu2_V = p->P[1] * p->V;
231
229
  double mu1_U_divide_sum = mu1_U / p->sum_U_weight;
232
230
  double mu2_V_divide_sum = mu2_V / p->sum_V_weight;
233
231
 
@@ -242,7 +240,7 @@ static inline uint8_t update_mig_weight_rate(patch_t* restrict p, const double*
242
240
 
243
241
 
244
242
 
245
- static inline uint8_t init_mig(patch_t* restrict p, const double* restrict P_start) {
243
+ static inline uint8_t init_mig(patch_t* restrict p) {
246
244
  // update migration rate for all directions
247
245
 
248
246
  double* p_U_weight = p->U_weight;
@@ -251,8 +249,8 @@ static inline uint8_t init_mig(patch_t* restrict p, const double* restrict P_sta
251
249
  p->sum_U_weight = 0.0;
252
250
  p->sum_V_weight = 0.0;
253
251
 
254
- double w1 = P_start[2];
255
- double w2 = P_start[3];
252
+ double w1 = p->P[2];
253
+ double w2 = p->P[3];
256
254
 
257
255
  for (uint8_t i = 0; i < 4; i++) {
258
256
  patch_t* nbi = p->nb[i];
@@ -274,8 +272,8 @@ static inline uint8_t init_mig(patch_t* restrict p, const double* restrict P_sta
274
272
  }
275
273
  }
276
274
 
277
- double mu1_U = P_start[0] * (double)p->U;
278
- double mu2_V = P_start[1] * (double)p->V;
275
+ double mu1_U = p->P[0] * p->U;
276
+ double mu2_V = p->P[1] * p->V;
279
277
  double mu1_U_divide_sum = mu1_U / p->sum_U_weight;
280
278
  double mu2_V_divide_sum = mu2_V / p->sum_V_weight;
281
279
 
@@ -367,6 +365,7 @@ static inline void find_patch(patch_picked_t* restrict picked, double expected_s
367
365
  double current_sum = 0;
368
366
  size_t row = 0;
369
367
  size_t col = 0;
368
+ size_t row_M = 0;
370
369
 
371
370
  // Find row
372
371
  if (N != 1) {
@@ -388,10 +387,9 @@ static inline void find_patch(patch_picked_t* restrict picked, double expected_s
388
387
  }
389
388
  row++;
390
389
  }
390
+ row_M = row * M;
391
391
  }
392
392
 
393
- size_t row_M = row * M;
394
-
395
393
  // Find col in that row
396
394
  if ((expected_sum - current_sum) < sum_rates_by_row[row] * 0.5) {
397
395
  col = 0;
@@ -496,9 +494,6 @@ static inline void make_signal_zero_flux(size_t i, size_t j, uint8_t e, signal_t
496
494
  signal->e2 = 3;
497
495
  signal->rela_loc = MIG_RIGHT;
498
496
  return;
499
- //default:
500
- // fprintf(stderr, "Bug: invalid case in make_signal_zf, i, j, e: %zu, %zu, %hhu\n", i, j, e);
501
- // return;
502
497
  }
503
498
  }
504
499
 
@@ -582,9 +577,6 @@ static inline void make_signal_periodical(size_t N, size_t M, size_t i, size_t j
582
577
  signal->e2 = 3;
583
578
  signal->rela_loc = MIG_RIGHT;
584
579
  return;
585
- //default:
586
- // fprintf(stderr, "Bug: invalid case in make_signal_pr, i, j, e: %zu, %zu, %hhu\n", i, j, e);
587
- // return;
588
580
  }
589
581
  }
590
582
 
@@ -23,7 +23,7 @@ from .build_info import build_info
23
23
 
24
24
  from .simulation import model, run, demo_model, UV_expected_val, check_overflow_func
25
25
  from .videos import make_video, SUPPORTED_FIGURES
26
- from .data_tools import save_data, read_data
26
+ from .data_tools import save, load
27
27
 
28
28
  from .analysis import rounds_expected, scale_maxtime, check_convergence, combine_sim
29
29
 
@@ -38,7 +38,7 @@ simulation_memebers = ['model', 'run', 'demo_model']
38
38
 
39
39
  videos_members = ['make_video', 'SUPPORTED_FIGURES']
40
40
 
41
- data_members = ['save_data', 'read_data']
41
+ data_members = ['save', 'load']
42
42
 
43
43
  analysis_members = ['expected_rounds', 'scale_maxtime', 'check_convergence', 'combine_mod']
44
44
 
@@ -1,4 +1,4 @@
1
- __version__ = '2.3.7'
1
+ __version__ = '2.3.8'
2
2
 
3
3
  '''
4
4
  version history:
@@ -44,4 +44,5 @@ version history:
44
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.
45
45
  2.3.6: index error due to reduced accuracy is now explicitly handled.
46
46
  2.3.7: update migration rules on the boundary. mu values are scaled based on how many neighbors a patch has. Minor debugging in several modules.
47
+ 2.3.8: bug fix for 2.3.7 update.
47
48
  '''
@@ -2,8 +2,8 @@
2
2
  Stores and reads a model object.
3
3
 
4
4
  Functions:
5
- - save_data: save a model object.
6
- - read_data: read a model object.
5
+ - save: save a model object.
6
+ - load: load a model object.
7
7
  '''
8
8
 
9
9
 
@@ -14,7 +14,7 @@ import gzip
14
14
  import os
15
15
 
16
16
 
17
- def save_data(mod, dirs = '', print_msg = True):
17
+ def save(mod, dirs = '', print_msg = True):
18
18
  '''
19
19
  Saves a model object. Data will be stored at dirs/data.json.gz
20
20
 
@@ -70,7 +70,7 @@ def save_data(mod, dirs = '', print_msg = True):
70
70
 
71
71
 
72
72
 
73
- def read_data(dirs):
73
+ def load(dirs):
74
74
  '''
75
75
  Reads and returns a model object.
76
76
 
@@ -176,7 +176,7 @@ class model:
176
176
  # if set to an int, say 20, mod will take average over every 20 data points and save them as new data.
177
177
  # May be used over and over again to recursively reduce data size.
178
178
  # Default is 1, not to take average.
179
- self.U = None # initialized by simulation.run or data_tools.read_data
179
+ self.U = None # initialized by simulation.run or data_tools.load
180
180
  self.V = None
181
181
  self.Upi = None
182
182
  self.Vpi = None
@@ -426,10 +426,10 @@ def run(mod, message = ""):
426
426
  P = np.ascontiguousarray(mod.P.flatten(), dtype = np.float64)
427
427
 
428
428
  mod_c = model_c()
429
- success = LIB.mod_init(ctypes.byref(mod_c),
429
+ init_sucess = LIB.mod_init(ctypes.byref(mod_c),
430
430
  mod.N, mod.M, mod.maxtime, mod.record_itv, mod.sim_time, mod.boundary,
431
431
  I, X, P, mod.print_pct, mod.seed)
432
- if not success:
432
+ if not init_sucess:
433
433
  LIB.mod_free_py(ctypes.byref(mod_c))
434
434
  del mod_c
435
435
  raise RuntimeError('Model initialization failed')
@@ -91,7 +91,7 @@ def test_var1(mod, var, values, dirs, compress_itv = None):
91
91
  simulation.run(sim2, message = current_var_str + ', ')
92
92
  if compress_itv != None:
93
93
  sim2.compress_data(compress_itv)
94
- data_t.save_data(sim2, var_dirs[k], print_msg = False)
94
+ data_t.save(sim2, var_dirs[k], print_msg = False)
95
95
  del sim2
96
96
  except (OverflowError, RuntimeError):
97
97
  print(current_var_str + ' raised error, skipped')
@@ -139,7 +139,7 @@ def test_var2(mod, var1, var2, values1, values2, dirs, compress_itv = None):
139
139
  simulation.run(sim2, message = current_var_str + ', ')
140
140
  if compress_itv != None:
141
141
  sim2.compress_data(compress_itv)
142
- data_t.save_data(sim2, var_dirs[k1][k2], print_msg = False)
142
+ data_t.save(sim2, var_dirs[k1][k2], print_msg = False)
143
143
  del sim2
144
144
  except (OverflowError, RuntimeError):
145
145
  print(current_var_str + ' raised error, skipped')
@@ -175,7 +175,7 @@ def var_UV1(var, values, var_dirs, ax_U = None, ax_V = None, start = 0.95, end =
175
175
 
176
176
  for k in range(len(var_dirs)):
177
177
  try:
178
- simk = data_t.read_data(var_dirs[k])
178
+ simk = data_t.load(var_dirs[k])
179
179
  except FileNotFoundError:
180
180
  print(var + '=' + str(values[k]) + ' not found, skipped')
181
181
  U_ave.append(None)
@@ -244,7 +244,7 @@ def var_UV2(var1, var2, values1, values2, var_dirs, ax_U = None, ax_V = None, va
244
244
  for k1 in range(len(var_dirs)):
245
245
  for k2 in range(len(var_dirs[k1])):
246
246
  try:
247
- simk = data_t.read_data(var_dirs[k1][k2])
247
+ simk = data_t.load(var_dirs[k1][k2])
248
248
  except FileNotFoundError:
249
249
  print(var1 + '=' + str(values1[k1]) + ', ' + var2 + '=' + str(values2[k2]) + ' not found, skipped')
250
250
  U_ave[k1].append(None)
@@ -332,7 +332,7 @@ def var_pi1(var, values, var_dirs, ax_U = None, ax_V = None, start = 0.95, end =
332
332
 
333
333
  for k in range(len(var_dirs)):
334
334
  try:
335
- simk = data_t.read_data(var_dirs[k])
335
+ simk = data_t.load(var_dirs[k])
336
336
  except FileNotFoundError:
337
337
  print(var + '=' + str(values[k]) + ' not found, skipped')
338
338
  U_ave.append(None)
@@ -397,7 +397,7 @@ def var_pi2(var1, var2, values1, values2, var_dirs, ax_U = None, ax_V = None, va
397
397
  for k1 in range(len(var_dirs)):
398
398
  for k2 in range(len(var_dirs[k1])):
399
399
  try:
400
- simk = data_t.read_data(var_dirs[k1][k2])
400
+ simk = data_t.load(var_dirs[k1][k2])
401
401
  except FileNotFoundError:
402
402
  print(var1 + '=' + str(values1[k1]) + ', ' + var2 + '=' + str(values2[k2]) + ' not found, skipped')
403
403
  U_ave[k1].append(None)
@@ -512,7 +512,7 @@ def var_convergence1(var_dirs, interval = 20, start = 0.8, fluc = 0.07):
512
512
  for k in range(len(var_dirs)):
513
513
  dirs = var_dirs[k]
514
514
  try:
515
- simk = data_t.read_data(dirs)
515
+ simk = data_t.load(dirs)
516
516
  except FileNotFoundError:
517
517
  print(dirs + ' data not found, skipped')
518
518
  continue
@@ -581,7 +581,7 @@ def var_convergence2(var_dirs, interval = 20, start = 0.8, fluc = 0.07):
581
581
  for k in range(len(sublist)):
582
582
  dirs = sublist[k]
583
583
  try:
584
- simk = data_t.read_data(dirs)
584
+ simk = data_t.load(dirs)
585
585
  except FileNotFoundError:
586
586
  print(dirs + ' data not found, skipped')
587
587
  continue
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: piegy
3
- Version: 2.3.7
3
+ Version: 2.3.8
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