piegy 2.2.3__tar.gz → 2.3.2__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.
- {piegy-2.2.3/src/piegy.egg-info → piegy-2.3.2}/PKG-INFO +1 -1
- {piegy-2.2.3 → piegy-2.3.2}/pyproject.toml +1 -1
- {piegy-2.2.3 → piegy-2.3.2}/src/piegy/C_core/Makefile +1 -1
- {piegy-2.2.3 → piegy-2.3.2}/src/piegy/C_core/patch.h +6 -6
- {piegy-2.2.3 → piegy-2.3.2}/src/piegy/C_core/runner.c +2 -2
- {piegy-2.2.3 → piegy-2.3.2}/src/piegy/C_core/sim_funcs.c +22 -30
- {piegy-2.2.3 → piegy-2.3.2}/src/piegy/C_core/sim_funcs.h +114 -88
- {piegy-2.2.3 → piegy-2.3.2}/src/piegy/__init__.py +2 -2
- {piegy-2.2.3 → piegy-2.3.2}/src/piegy/__version__.py +5 -1
- {piegy-2.2.3 → piegy-2.3.2}/src/piegy/figures.py +74 -17
- {piegy-2.2.3 → piegy-2.3.2}/src/piegy/test_var.py +8 -2
- {piegy-2.2.3 → piegy-2.3.2}/src/piegy/tools/figure_tools.py +1 -1
- {piegy-2.2.3 → piegy-2.3.2/src/piegy.egg-info}/PKG-INFO +1 -1
- {piegy-2.2.3 → piegy-2.3.2}/LICENSE.txt +0 -0
- {piegy-2.2.3 → piegy-2.3.2}/MANIFEST.in +0 -0
- {piegy-2.2.3 → piegy-2.3.2}/README.md +0 -0
- {piegy-2.2.3 → piegy-2.3.2}/setup.cfg +0 -0
- {piegy-2.2.3 → piegy-2.3.2}/setup.py +0 -0
- {piegy-2.2.3 → piegy-2.3.2}/src/piegy/C_core/model.c +0 -0
- {piegy-2.2.3 → piegy-2.3.2}/src/piegy/C_core/model.h +0 -0
- {piegy-2.2.3 → piegy-2.3.2}/src/piegy/C_core/patch.c +0 -0
- {piegy-2.2.3 → piegy-2.3.2}/src/piegy/analysis.py +0 -0
- {piegy-2.2.3 → piegy-2.3.2}/src/piegy/build_info.py +0 -0
- {piegy-2.2.3 → piegy-2.3.2}/src/piegy/data_tools.py +0 -0
- {piegy-2.2.3 → piegy-2.3.2}/src/piegy/simulation.py +0 -0
- {piegy-2.2.3 → piegy-2.3.2}/src/piegy/simulation_py.py +0 -0
- {piegy-2.2.3 → piegy-2.3.2}/src/piegy/tools/__init__.py +0 -0
- {piegy-2.2.3 → piegy-2.3.2}/src/piegy/tools/file_tools.py +0 -0
- {piegy-2.2.3 → piegy-2.3.2}/src/piegy/tools/find_C.py +0 -0
- {piegy-2.2.3 → piegy-2.3.2}/src/piegy/videos.py +0 -0
- {piegy-2.2.3 → piegy-2.3.2}/src/piegy.egg-info/SOURCES.txt +0 -0
- {piegy-2.2.3 → piegy-2.3.2}/src/piegy.egg-info/dependency_links.txt +0 -0
- {piegy-2.2.3 → piegy-2.3.2}/src/piegy.egg-info/requires.txt +0 -0
- {piegy-2.2.3 → piegy-2.3.2}/src/piegy.egg-info/top_level.txt +0 -0
@@ -5,7 +5,7 @@ CC = gcc
|
|
5
5
|
|
6
6
|
## Flags for Max Speed ##
|
7
7
|
# standard
|
8
|
-
CFLAGS_COMMON = -O3 -flto -std=c99 -DNDEBUG -ffp-contract=fast -MMD -MP
|
8
|
+
CFLAGS_COMMON = -O3 -march=native -flto -std=c99 -DNDEBUG -ffp-contract=fast -funroll-loops -fomit-frame-pointer -MMD -MP
|
9
9
|
LDFLAGS_COMMON = -flto
|
10
10
|
|
11
11
|
## Flags for Debugging ##
|
@@ -23,14 +23,14 @@ typedef struct patch_t {
|
|
23
23
|
double V_pi;
|
24
24
|
|
25
25
|
struct patch_t* nb[4];
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
26
|
+
double U_weight[4]; // stores migration weight of each of the 4 neighbors
|
27
|
+
double V_weight[4];
|
28
|
+
double sum_U_weight; // sum of U_weight
|
29
|
+
double sum_V_weight;
|
30
30
|
double pi_death_rates[4];
|
31
|
-
|
31
|
+
double mig_rates[8];
|
32
32
|
double sum_pi_death_rates;
|
33
|
-
|
33
|
+
double sum_mig_rates;
|
34
34
|
} patch_t;
|
35
35
|
|
36
36
|
// in .c
|
@@ -11,9 +11,9 @@
|
|
11
11
|
int main() {
|
12
12
|
size_t N = 1;
|
13
13
|
size_t M = 100;
|
14
|
-
double maxtime =
|
14
|
+
double maxtime = 100;
|
15
15
|
double record_itv = 0.1;
|
16
|
-
size_t sim_time =
|
16
|
+
size_t sim_time = 10;
|
17
17
|
bool boundary = true;
|
18
18
|
uint32_t I_single[2] = {200, 100};
|
19
19
|
double X_single[4] = {-1, 4, 0, 2};
|
@@ -69,7 +69,7 @@ static void find_nb_periodical(size_t* restrict nb, size_t i, size_t j, size_t N
|
|
69
69
|
|
70
70
|
// single_init function: initializes world, runs 1 event, returns updated variables
|
71
71
|
static double single_init(const model_t* mod, patch_t* world, size_t* nb_indices,
|
72
|
-
|
72
|
+
double* patch_rates, double* sum_rates_by_row, double* sum_rates_p, signal_t* sig_p, patch_picked_t* picked_p) {
|
73
73
|
|
74
74
|
size_t N = mod->N;
|
75
75
|
size_t M = mod->M;
|
@@ -128,7 +128,7 @@ static double single_init(const model_t* mod, patch_t* world, size_t* nb_indices
|
|
128
128
|
ij = 0;
|
129
129
|
for (size_t i = 0; i < N; i++) {
|
130
130
|
for (size_t j = 0; j < M; j++) {
|
131
|
-
uint8_t mig_result =
|
131
|
+
uint8_t mig_result = init_mig(&world[ij], &(mod->P[ij * 6])); // init mig rates for all 4 directions
|
132
132
|
if (mig_result == SIM_OVERFLOW) {
|
133
133
|
return -1 * SIM_OVERFLOW;
|
134
134
|
}
|
@@ -141,7 +141,7 @@ static double single_init(const model_t* mod, patch_t* world, size_t* nb_indices
|
|
141
141
|
}
|
142
142
|
|
143
143
|
// pick the first random event
|
144
|
-
|
144
|
+
double expected_sum = random01() * *sum_rates_p;
|
145
145
|
find_patch(picked_p, expected_sum, patch_rates, sum_rates_by_row, *sum_rates_p, N, M);
|
146
146
|
size_t picked_idx = picked_p->i * M + picked_p->j;
|
147
147
|
size_t e0 = find_event(&world[picked_idx], expected_sum - picked_p->current_sum);
|
@@ -157,7 +157,7 @@ static double single_init(const model_t* mod, patch_t* world, size_t* nb_indices
|
|
157
157
|
|
158
158
|
// update patch based on signal
|
159
159
|
change_popu(&world[sig_p->ij1], sig_p->e1);
|
160
|
-
if (
|
160
|
+
if (sig_p->rela_loc != NO_MIG) {
|
161
161
|
change_popu(&world[sig_p->ij2], sig_p->e2);
|
162
162
|
}
|
163
163
|
|
@@ -223,9 +223,9 @@ static uint8_t single_test(model_t* restrict mod, uint32_t update_sum_freq, char
|
|
223
223
|
patch_t* world = (patch_t*) calloc(NM, sizeof(patch_t));
|
224
224
|
size_t* nb_indices = (size_t*) calloc(NM * 4, sizeof(size_t));
|
225
225
|
|
226
|
-
|
227
|
-
|
228
|
-
|
226
|
+
double* patch_rates = (double*) calloc(NM, sizeof(double));
|
227
|
+
double* sum_rates_by_row = (double*) calloc(N, sizeof(double));
|
228
|
+
double sum_rates = 0;
|
229
229
|
|
230
230
|
signal_t signal;
|
231
231
|
patch_picked_t picked;
|
@@ -300,21 +300,15 @@ static uint8_t single_test(model_t* restrict mod, uint32_t update_sum_freq, char
|
|
300
300
|
size_t si2 = signal.i2;
|
301
301
|
size_t sij1 = signal.ij1;
|
302
302
|
size_t sij2 = signal.ij2;
|
303
|
-
|
304
|
-
if (
|
303
|
+
uint8_t rela_loc = signal.rela_loc;
|
304
|
+
if (rela_loc == NO_MIG) {
|
305
305
|
// if only one
|
306
306
|
double picked_rate = world[sij1].sum_pi_death_rates + world[sij1].sum_mig_rates;
|
307
307
|
sum_rates_by_row[si1] -= picked_rate;
|
308
308
|
sum_rates -= picked_rate;
|
309
309
|
|
310
310
|
update_pi_k(&world[sij1], &(mod->X[sij1 * 4]), &(mod->P[sij1 * 6]));
|
311
|
-
|
312
|
-
if (mig_result == SIM_OVERFLOW) {
|
313
|
-
fprintf(stdout, "\nError: overflow at t = %f\n", time);
|
314
|
-
fflush(stdout);
|
315
|
-
single_test_free(&world, &nb_indices, &patch_rates, &sum_rates_by_row);
|
316
|
-
return SIM_OVERFLOW;
|
317
|
-
}
|
311
|
+
update_mig_just_rate(&world[sij1], &(mod->P[sij1 * 6]));
|
318
312
|
|
319
313
|
picked_rate = world[sij1].sum_pi_death_rates + world[sij1].sum_mig_rates;
|
320
314
|
patch_rates[sij1] = picked_rate;
|
@@ -331,9 +325,10 @@ static uint8_t single_test(model_t* restrict mod, uint32_t update_sum_freq, char
|
|
331
325
|
|
332
326
|
update_pi_k(&world[sij1], &(mod->X[sij1 * 4]), &(mod->P[sij1 * 6])); // update both patches' payoffs first
|
333
327
|
update_pi_k(&world[sij2], &(mod->X[sij2 * 4]), &(mod->P[sij2 * 6]));
|
334
|
-
|
335
|
-
|
336
|
-
|
328
|
+
|
329
|
+
if (update_mig_weight_rate(&world[sij1], &(mod->P[sij1 * 6]), rela_loc) == SIM_OVERFLOW ||
|
330
|
+
update_mig_weight_rate(&world[sij2], &(mod->P[sij2 * 6]), rela_loc ^ 1) == SIM_OVERFLOW) {
|
331
|
+
|
337
332
|
fprintf(stdout, "\nError: overflow at t = %f\n", time);
|
338
333
|
fflush(stdout);
|
339
334
|
single_test_free(&world, &nb_indices, &patch_rates, &sum_rates_by_row);
|
@@ -352,19 +347,18 @@ static uint8_t single_test(model_t* restrict mod, uint32_t update_sum_freq, char
|
|
352
347
|
}
|
353
348
|
|
354
349
|
// update neighbors of last-changed patches
|
355
|
-
if (
|
350
|
+
if (rela_loc == NO_MIG) {
|
356
351
|
for (uint8_t k = 0; k < 4; k++) {
|
357
352
|
size_t nb_idx = nb_indices[sij1 * 4 + k];
|
358
353
|
if (nb_idx == NM) { continue; } // invalid neighbor
|
359
354
|
// all neighbors, as long as exists, need to change
|
360
|
-
|
361
|
-
if (mig_result == SIM_OVERFLOW) {
|
355
|
+
if (update_mig_weight_rate(&world[nb_idx], &(mod->P[nb_idx * 6]), k ^ 1) == SIM_OVERFLOW) {
|
362
356
|
fprintf(stdout, "\nError: overflow at t = %f\n", time);
|
363
357
|
fflush(stdout);
|
364
358
|
single_test_free(&world, &nb_indices, &patch_rates, &sum_rates_by_row);
|
365
359
|
return SIM_OVERFLOW;
|
366
360
|
}
|
367
|
-
//
|
361
|
+
// patch_rates, and sums of rates is not changed
|
368
362
|
}
|
369
363
|
} else {
|
370
364
|
// the first patch
|
@@ -372,8 +366,7 @@ static uint8_t single_test(model_t* restrict mod, uint32_t update_sum_freq, char
|
|
372
366
|
size_t nb_idx = nb_indices[sij1 * 4 + k];
|
373
367
|
if (nb_idx == NM) { continue; }
|
374
368
|
if (nb_need_change(nb_idx, sij1, sij2)) {
|
375
|
-
|
376
|
-
if (mig_result == SIM_OVERFLOW) {
|
369
|
+
if (update_mig_weight_rate(&world[nb_idx], &(mod->P[nb_idx * 6]), k ^ 1) == SIM_OVERFLOW) {
|
377
370
|
fprintf(stdout, "\nError: overflow at t = %f\n", time);
|
378
371
|
fflush(stdout);
|
379
372
|
single_test_free(&world, &nb_indices, &patch_rates, &sum_rates_by_row);
|
@@ -386,8 +379,7 @@ static uint8_t single_test(model_t* restrict mod, uint32_t update_sum_freq, char
|
|
386
379
|
size_t nb_idx = nb_indices[sij2 * 4 + k];
|
387
380
|
if (nb_idx == NM) { continue; }
|
388
381
|
if (nb_need_change(nb_idx, sij1, sij2)) {
|
389
|
-
|
390
|
-
if (mig_result == SIM_OVERFLOW) {
|
382
|
+
if (update_mig_weight_rate(&world[nb_idx], &(mod->P[nb_idx * 6]), k ^ 1) == SIM_OVERFLOW) {
|
391
383
|
fprintf(stdout, "\nError: overflow at t = %f\n", time);
|
392
384
|
fflush(stdout);
|
393
385
|
single_test_free(&world, &nb_indices, &patch_rates, &sum_rates_by_row);
|
@@ -399,7 +391,7 @@ static uint8_t single_test(model_t* restrict mod, uint32_t update_sum_freq, char
|
|
399
391
|
|
400
392
|
|
401
393
|
// pick a random event
|
402
|
-
|
394
|
+
double expected_sum = random01() * sum_rates;
|
403
395
|
find_patch(&picked, expected_sum, patch_rates, sum_rates_by_row, sum_rates, N, M);
|
404
396
|
size_t picked_idx = picked.i * M + picked.j;
|
405
397
|
uint8_t e0 = find_event(&world[picked_idx], expected_sum - picked.current_sum);
|
@@ -415,7 +407,7 @@ static uint8_t single_test(model_t* restrict mod, uint32_t update_sum_freq, char
|
|
415
407
|
|
416
408
|
// let the event happenn
|
417
409
|
change_popu(&world[signal.ij1], signal.e1);
|
418
|
-
if (
|
410
|
+
if (signal.rela_loc != NO_MIG) {
|
419
411
|
change_popu(&world[signal.ij2], signal.e2);
|
420
412
|
}
|
421
413
|
|
@@ -477,7 +469,7 @@ static uint8_t single_test(model_t* restrict mod, uint32_t update_sum_freq, char
|
|
477
469
|
|
478
470
|
|
479
471
|
|
480
|
-
static void single_test_free(patch_t** world, size_t** nb_indices,
|
472
|
+
static void single_test_free(patch_t** world, size_t** nb_indices, double** patch_rates, double** sum_rates_by_row) {
|
481
473
|
free(*world);
|
482
474
|
free(*nb_indices);
|
483
475
|
free(*patch_rates);
|
@@ -28,16 +28,17 @@
|
|
28
28
|
#define MIG_DOWN 1
|
29
29
|
#define MIG_LEFT 2
|
30
30
|
#define MIG_RIGHT 3
|
31
|
+
#define NO_MIG 4
|
31
32
|
|
32
33
|
// results of single_test
|
33
34
|
#define SUCCESS 0
|
34
35
|
#define DATA_NOT_EMPTY 1
|
35
|
-
#define SMALL_MAXTIME 2
|
36
|
-
#define SIM_OVERFLOW 3
|
36
|
+
#define SMALL_MAXTIME 2
|
37
|
+
#define SIM_OVERFLOW 3
|
37
38
|
|
38
39
|
// where exp(x) is considered overflow
|
39
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
|
40
|
-
#define EXP_OVERFLOW_BOUND
|
41
|
+
#define EXP_OVERFLOW_BOUND 500
|
41
42
|
|
42
43
|
|
43
44
|
static uint64_t pcg_state = 0;
|
@@ -59,8 +60,10 @@ typedef struct patch_picked_t {
|
|
59
60
|
* index & event number in make_signal_*
|
60
61
|
*/
|
61
62
|
typedef struct signal_t {
|
62
|
-
//
|
63
|
-
|
63
|
+
// relative location of the second patch to the first
|
64
|
+
// set to NO_MIG if the event only affects one patch
|
65
|
+
// otherwise set to MIG_* constants as defined above
|
66
|
+
uint8_t rela_loc;
|
64
67
|
|
65
68
|
// the first patch
|
66
69
|
size_t i1;
|
@@ -83,9 +86,9 @@ typedef struct signal_t {
|
|
83
86
|
static void find_nb_zero_flux(size_t* restrict nb, size_t i, size_t j, size_t N, size_t M, size_t NM);
|
84
87
|
static void find_nb_periodical(size_t* restrict nb, size_t i, size_t j, size_t N, size_t M, size_t NM);
|
85
88
|
static double single_init(const model_t* mod, patch_t* world, size_t* nb_indices,
|
86
|
-
|
89
|
+
double* patch_rates, double* sum_rates_by_row, double* sum_rates, signal_t* sig_p, patch_picked_t* picked_p) ;
|
87
90
|
static uint8_t single_test(model_t* restrict mod, uint32_t update_sum_frequency, char* message);
|
88
|
-
static void single_test_free(patch_t** world, size_t** nb_indices,
|
91
|
+
static void single_test_free(patch_t** world, size_t** nb_indices, double** patch_rates, double** sum_rates_by_row);
|
89
92
|
uint8_t run(model_t* mod, char* message, size_t msg_len, uint32_t update_sum_freq);
|
90
93
|
|
91
94
|
|
@@ -94,12 +97,12 @@ uint8_t run(model_t* mod, char* message, size_t msg_len, uint32_t update_sum_fre
|
|
94
97
|
* Inline Functions
|
95
98
|
*/
|
96
99
|
|
97
|
-
static inline
|
100
|
+
static inline double random01() {
|
98
101
|
// generate a 24 bit random int, then convert to a (0, 1) ranged double
|
99
102
|
uint32_t r1 = rand() & 0x7fff; // RAND_MAX is different across machines, ensure 15 bits
|
100
103
|
uint32_t r2 = rand() & 0x7fff;
|
101
104
|
|
102
|
-
|
105
|
+
double r_combined = (r1 << 15) + r2; // discard the lower 3 bits, which are unstable
|
103
106
|
return (r_combined + 1) / RAND_UPPER_PLUS_2;
|
104
107
|
}
|
105
108
|
|
@@ -113,19 +116,19 @@ static inline void update_pi_k(patch_t* restrict p, const double* restrict M_sta
|
|
113
116
|
|
114
117
|
double U = (double) p->U;
|
115
118
|
double V = (double) p->V;
|
116
|
-
double
|
119
|
+
double sum = U + V;
|
117
120
|
|
118
|
-
if (
|
121
|
+
if (sum > 0) {
|
119
122
|
if (U != 0) {
|
120
|
-
p->U_pi = (
|
121
|
-
(V /
|
123
|
+
p->U_pi = (U / sum) * M_start[0] +
|
124
|
+
(V / sum) * M_start[1];
|
122
125
|
} else {
|
123
126
|
p->U_pi = 0.0;
|
124
127
|
}
|
125
128
|
|
126
129
|
if (V != 0) {
|
127
|
-
p->V_pi = (U /
|
128
|
-
(
|
130
|
+
p->V_pi = (U / sum) * M_start[2] +
|
131
|
+
(V / sum) * M_start[3];
|
129
132
|
} else {
|
130
133
|
p->V_pi = 0.0;
|
131
134
|
}
|
@@ -138,8 +141,8 @@ static inline void update_pi_k(patch_t* restrict p, const double* restrict M_sta
|
|
138
141
|
p->pi_death_rates[0] = fabs(U * p->U_pi);
|
139
142
|
p->pi_death_rates[1] = fabs(V * p->V_pi);
|
140
143
|
|
141
|
-
p->pi_death_rates[2] = P_start[4] * U *
|
142
|
-
p->pi_death_rates[3] = P_start[5] * V *
|
144
|
+
p->pi_death_rates[2] = P_start[4] * U * sum;
|
145
|
+
p->pi_death_rates[3] = P_start[5] * V * sum;
|
143
146
|
|
144
147
|
p->sum_pi_death_rates = 0.0;
|
145
148
|
for (size_t i = 0; i < 4; i++) {
|
@@ -148,19 +151,37 @@ static inline void update_pi_k(patch_t* restrict p, const double* restrict M_sta
|
|
148
151
|
}
|
149
152
|
|
150
153
|
|
151
|
-
|
152
|
-
|
153
|
-
//
|
154
|
-
//
|
154
|
+
|
155
|
+
static inline void update_mig_just_rate(patch_t* restrict p, const double* restrict P_start) {
|
156
|
+
// update migration weight for patch p, in location loc. Only rate is updated
|
157
|
+
// used by neighbors of last-changed patches, to update migration weights
|
158
|
+
double* p_U_weight = p->U_weight;
|
159
|
+
double* p_V_weight = p->V_weight;
|
155
160
|
|
156
161
|
double mu1_U = P_start[0] * (double)p->U;
|
157
162
|
double mu2_V = P_start[1] * (double)p->V;
|
158
|
-
|
159
|
-
|
163
|
+
double mu1_U_divide_sum = mu1_U / p->sum_U_weight;
|
164
|
+
double mu2_V_divide_sum = mu2_V / p->sum_V_weight;
|
160
165
|
|
161
|
-
|
162
|
-
|
163
|
-
|
166
|
+
for (uint8_t i = 0; i < 4; i++) {
|
167
|
+
p->mig_rates[i] = mu1_U_divide_sum * p_U_weight[i];
|
168
|
+
p->mig_rates[i + 4] = mu2_V_divide_sum * p_V_weight[i];
|
169
|
+
}
|
170
|
+
p->sum_mig_rates = mu1_U + mu2_V;
|
171
|
+
}
|
172
|
+
|
173
|
+
|
174
|
+
static inline uint8_t update_mig_weight_rate(patch_t* restrict p, const double* P_start, uint8_t loc) {
|
175
|
+
// update migration weight as well as rates, in one direction
|
176
|
+
// used by neighbors of last-changed patches
|
177
|
+
// also used by last-changed patches themselve, when there is only one patch changed, to update mig rates without having to update weights
|
178
|
+
|
179
|
+
double* p_U_weight = p->U_weight;
|
180
|
+
double* p_V_weight = p->V_weight;
|
181
|
+
|
182
|
+
patch_t* nbi = p->nb[loc];
|
183
|
+
p->sum_U_weight -= p_U_weight[loc];
|
184
|
+
p->sum_V_weight -= p_V_weight[loc];
|
164
185
|
|
165
186
|
double w1_Upi = P_start[2] * nbi->U_pi;
|
166
187
|
double w2_Vpi = P_start[3] * nbi->V_pi;
|
@@ -171,47 +192,48 @@ static inline uint8_t update_mig_one(patch_t* restrict p, const double* restrict
|
|
171
192
|
return SIM_OVERFLOW;
|
172
193
|
}
|
173
194
|
|
174
|
-
switch(
|
195
|
+
switch(loc) {
|
175
196
|
case MIG_UP:
|
176
|
-
p_U_weight[MIG_UP] =
|
177
|
-
p_V_weight[MIG_UP] =
|
197
|
+
p_U_weight[MIG_UP] = exp(w1_Upi);
|
198
|
+
p_V_weight[MIG_UP] = exp(w2_Vpi);
|
178
199
|
break;
|
179
200
|
case MIG_DOWN:
|
180
|
-
p_U_weight[MIG_DOWN] =
|
181
|
-
p_V_weight[MIG_DOWN] =
|
201
|
+
p_U_weight[MIG_DOWN] = exp(w1_Upi);
|
202
|
+
p_V_weight[MIG_DOWN] = exp(w2_Vpi);
|
182
203
|
break;
|
183
204
|
case MIG_LEFT:
|
184
|
-
p_U_weight[MIG_LEFT] =
|
185
|
-
p_V_weight[MIG_LEFT] =
|
205
|
+
p_U_weight[MIG_LEFT] = exp(w1_Upi);
|
206
|
+
p_V_weight[MIG_LEFT] = exp(w2_Vpi);
|
186
207
|
break;
|
187
208
|
default:
|
188
|
-
p_U_weight[MIG_RIGHT] =
|
189
|
-
p_V_weight[MIG_RIGHT] =
|
209
|
+
p_U_weight[MIG_RIGHT] = exp(w1_Upi);
|
210
|
+
p_V_weight[MIG_RIGHT] = exp(w2_Vpi);
|
190
211
|
break;
|
191
212
|
}
|
192
|
-
p->sum_U_weight += p_U_weight[
|
193
|
-
p->sum_V_weight += p_V_weight[
|
213
|
+
p->sum_U_weight += p_U_weight[loc];
|
214
|
+
p->sum_V_weight += p_V_weight[loc];
|
194
215
|
|
216
|
+
double mu1_U = P_start[0] * (double)p->U;
|
217
|
+
double mu2_V = P_start[1] * (double)p->V;
|
195
218
|
double mu1_U_divide_sum = mu1_U / p->sum_U_weight;
|
196
219
|
double mu2_V_divide_sum = mu2_V / p->sum_V_weight;
|
197
220
|
|
198
|
-
for (
|
221
|
+
for (uint8_t i = 0; i < 4; i++) {
|
199
222
|
p->mig_rates[i] = mu1_U_divide_sum * p_U_weight[i];
|
200
223
|
p->mig_rates[i + 4] = mu2_V_divide_sum * p_V_weight[i];
|
201
224
|
}
|
225
|
+
p->sum_mig_rates = mu1_U + mu2_V;
|
202
226
|
|
203
227
|
return SUCCESS;
|
204
228
|
}
|
205
229
|
|
206
230
|
|
207
231
|
|
208
|
-
static inline uint8_t
|
232
|
+
static inline uint8_t init_mig(patch_t* restrict p, const double* restrict P_start) {
|
209
233
|
// update migration rate for all directions
|
210
|
-
double mu1_U = P_start[0] * (double)p->U;
|
211
|
-
double mu2_V = P_start[1] * (double)p->V;
|
212
234
|
|
213
|
-
|
214
|
-
|
235
|
+
double* p_U_weight = p->U_weight;
|
236
|
+
double* p_V_weight = p->V_weight;
|
215
237
|
|
216
238
|
p->sum_U_weight = 0.0;
|
217
239
|
p->sum_V_weight = 0.0;
|
@@ -232,14 +254,17 @@ static inline uint8_t update_mig_all(patch_t* restrict p, const double* restrict
|
|
232
254
|
if (w2_Vpi > EXP_OVERFLOW_BOUND) {
|
233
255
|
return SIM_OVERFLOW;
|
234
256
|
}
|
235
|
-
p_U_weight[i] =
|
236
|
-
p_V_weight[i] =
|
257
|
+
p_U_weight[i] = exp(w1_Upi);
|
258
|
+
p_V_weight[i] = exp(w2_Vpi);
|
237
259
|
|
238
260
|
p->sum_U_weight += p_U_weight[i];
|
239
261
|
p->sum_V_weight += p_V_weight[i];
|
240
262
|
}
|
241
263
|
}
|
242
264
|
|
265
|
+
|
266
|
+
double mu1_U = P_start[0] * (double)p->U;
|
267
|
+
double mu2_V = P_start[1] * (double)p->V;
|
243
268
|
double mu1_U_divide_sum = mu1_U / p->sum_U_weight;
|
244
269
|
double mu2_V_divide_sum = mu2_V / p->sum_V_weight;
|
245
270
|
|
@@ -247,7 +272,6 @@ static inline uint8_t update_mig_all(patch_t* restrict p, const double* restrict
|
|
247
272
|
p->mig_rates[i] = mu1_U_divide_sum * p_U_weight[i];
|
248
273
|
p->mig_rates[i + 4] = mu2_V_divide_sum * p_V_weight[i];
|
249
274
|
}
|
250
|
-
|
251
275
|
p->sum_mig_rates = mu1_U + mu2_V;
|
252
276
|
|
253
277
|
return SUCCESS;
|
@@ -255,7 +279,7 @@ static inline uint8_t update_mig_all(patch_t* restrict p, const double* restrict
|
|
255
279
|
|
256
280
|
|
257
281
|
|
258
|
-
static inline uint8_t find_event(const patch_t* restrict p,
|
282
|
+
static inline uint8_t find_event(const patch_t* restrict p, double expected_sum) {
|
259
283
|
size_t event = 0;
|
260
284
|
double current_sum;
|
261
285
|
|
@@ -330,30 +354,32 @@ static inline void change_popu(patch_t* restrict p, uint8_t s) {
|
|
330
354
|
* Main Simulation Functions
|
331
355
|
*/
|
332
356
|
|
333
|
-
static inline void find_patch(patch_picked_t* restrict picked,
|
334
|
-
const
|
357
|
+
static inline void find_patch(patch_picked_t* restrict picked, double expected_sum,
|
358
|
+
const double* restrict patch_rates, const double* restrict sum_rates_by_row, double sum_rates, size_t N, size_t M) {
|
335
359
|
double current_sum = 0;
|
336
360
|
size_t row = 0;
|
337
361
|
size_t col = 0;
|
338
362
|
|
339
363
|
// Find row
|
340
|
-
if (
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
current_sum
|
345
|
-
|
346
|
-
|
347
|
-
|
348
|
-
current_sum -= sum_rates_by_row[row];
|
349
|
-
} else {
|
350
|
-
current_sum = sum_rates;
|
351
|
-
row = N - 1;
|
352
|
-
while (current_sum > expected_sum) {
|
353
|
-
current_sum -= sum_rates_by_row[row];
|
364
|
+
if (N != 1) {
|
365
|
+
if (expected_sum < sum_rates * 0.5) {
|
366
|
+
current_sum = 0.0;
|
367
|
+
row = 0;
|
368
|
+
while (current_sum < expected_sum) {
|
369
|
+
current_sum += sum_rates_by_row[row];
|
370
|
+
row++;
|
371
|
+
}
|
354
372
|
row--;
|
373
|
+
current_sum -= sum_rates_by_row[row];
|
374
|
+
} else {
|
375
|
+
current_sum = sum_rates;
|
376
|
+
row = N - 1;
|
377
|
+
while (current_sum > expected_sum) {
|
378
|
+
current_sum -= sum_rates_by_row[row];
|
379
|
+
row--;
|
380
|
+
}
|
381
|
+
row++;
|
355
382
|
}
|
356
|
-
row++;
|
357
383
|
}
|
358
384
|
|
359
385
|
size_t row_M = row * M;
|
@@ -392,75 +418,75 @@ static inline void make_signal_zero_flux(size_t i, size_t j, uint8_t e, signal_t
|
|
392
418
|
switch (e) {
|
393
419
|
case 0:
|
394
420
|
signal->e1 = 2;
|
395
|
-
signal->
|
421
|
+
signal->rela_loc = NO_MIG;
|
396
422
|
return;
|
397
423
|
case 1:
|
398
424
|
signal->e1 = 5;
|
399
|
-
signal->
|
425
|
+
signal->rela_loc = NO_MIG;
|
400
426
|
return;
|
401
427
|
case 2:
|
402
428
|
signal->e1 = 1;
|
403
|
-
signal->
|
429
|
+
signal->rela_loc = NO_MIG;
|
404
430
|
return;
|
405
431
|
case 3:
|
406
432
|
signal->e1 = 4;
|
407
|
-
signal->
|
433
|
+
signal->rela_loc = NO_MIG;
|
408
434
|
return;
|
409
435
|
case 4:
|
410
436
|
signal->e1 = 1;
|
411
437
|
signal->i2 = i - 1;
|
412
438
|
signal->j2 = j;
|
413
439
|
signal->e2 = 0;
|
414
|
-
signal->
|
440
|
+
signal->rela_loc = MIG_UP;
|
415
441
|
return;
|
416
442
|
case 5:
|
417
443
|
signal->e1 = 1;
|
418
444
|
signal->i2 = i + 1;
|
419
445
|
signal->j2 = j;
|
420
446
|
signal->e2 = 0;
|
421
|
-
signal->
|
447
|
+
signal->rela_loc = MIG_DOWN;
|
422
448
|
return;
|
423
449
|
case 6:
|
424
450
|
signal->e1 = 1;
|
425
451
|
signal->i2 = i;
|
426
452
|
signal->j2 = j - 1;
|
427
453
|
signal->e2 = 0;
|
428
|
-
signal->
|
454
|
+
signal->rela_loc = MIG_LEFT;
|
429
455
|
return;
|
430
456
|
case 7:
|
431
457
|
signal->e1 = 1;
|
432
458
|
signal->i2 = i;
|
433
459
|
signal->j2 = j + 1;
|
434
460
|
signal->e2 = 0;
|
435
|
-
signal->
|
461
|
+
signal->rela_loc = MIG_RIGHT;
|
436
462
|
return;
|
437
463
|
case 8:
|
438
464
|
signal->e1 = 4;
|
439
465
|
signal->i2 = i - 1;
|
440
466
|
signal->j2 = j;
|
441
467
|
signal->e2 = 3;
|
442
|
-
signal->
|
468
|
+
signal->rela_loc = MIG_UP;
|
443
469
|
return;
|
444
470
|
case 9:
|
445
471
|
signal->e1 = 4;
|
446
472
|
signal->i2 = i + 1;
|
447
473
|
signal->j2 = j;
|
448
474
|
signal->e2 = 3;
|
449
|
-
signal->
|
475
|
+
signal->rela_loc = MIG_DOWN;
|
450
476
|
return;
|
451
477
|
case 10:
|
452
478
|
signal->e1 = 4;
|
453
479
|
signal->i2 = i;
|
454
480
|
signal->j2 = j - 1;
|
455
481
|
signal->e2 = 3;
|
456
|
-
signal->
|
482
|
+
signal->rela_loc = MIG_LEFT;
|
457
483
|
return;
|
458
484
|
default:
|
459
485
|
signal->e1 = 4;
|
460
486
|
signal->i2 = i;
|
461
487
|
signal->j2 = j + 1;
|
462
488
|
signal->e2 = 3;
|
463
|
-
signal->
|
489
|
+
signal->rela_loc = MIG_RIGHT;
|
464
490
|
return;
|
465
491
|
//default:
|
466
492
|
// fprintf(stderr, "Bug: invalid case in make_signal_zf, i, j, e: %zu, %zu, %hhu\n", i, j, e);
|
@@ -478,75 +504,75 @@ static inline void make_signal_periodical(size_t N, size_t M, size_t i, size_t j
|
|
478
504
|
switch (e) {
|
479
505
|
case 0:
|
480
506
|
signal->e1 = 2;
|
481
|
-
signal->
|
507
|
+
signal->rela_loc = NO_MIG;
|
482
508
|
return;
|
483
509
|
case 1:
|
484
510
|
signal->e1 = 5;
|
485
|
-
signal->
|
511
|
+
signal->rela_loc = NO_MIG;
|
486
512
|
return;
|
487
513
|
case 2:
|
488
514
|
signal->e1 = 1;
|
489
|
-
signal->
|
515
|
+
signal->rela_loc = NO_MIG;
|
490
516
|
return;
|
491
517
|
case 3:
|
492
518
|
signal->e1 = 4;
|
493
|
-
signal->
|
519
|
+
signal->rela_loc = NO_MIG;
|
494
520
|
return;
|
495
521
|
case 4:
|
496
522
|
signal->e1 = 1;
|
497
523
|
signal->i2 = i != 0 ? i - 1 : N - 1;
|
498
524
|
signal->j2 = j;
|
499
525
|
signal->e2 = 0;
|
500
|
-
signal->
|
526
|
+
signal->rela_loc = MIG_UP;
|
501
527
|
return;
|
502
528
|
case 5:
|
503
529
|
signal->e1 = 1;
|
504
530
|
signal->i2 = i != N - 1 ? i + 1 : 0;
|
505
531
|
signal->j2 = j;
|
506
532
|
signal->e2 = 0;
|
507
|
-
signal->
|
533
|
+
signal->rela_loc = MIG_DOWN;
|
508
534
|
return;
|
509
535
|
case 6:
|
510
536
|
signal->e1 = 1;
|
511
537
|
signal->i2 = i;
|
512
538
|
signal->j2 = j != 0 ? j - 1 : M - 1;
|
513
539
|
signal->e2 = 0;
|
514
|
-
signal->
|
540
|
+
signal->rela_loc = MIG_LEFT;
|
515
541
|
return;
|
516
542
|
case 7:
|
517
543
|
signal->e1 = 1;
|
518
544
|
signal->i2 = i;
|
519
545
|
signal->j2 = j != M - 1 ? j + 1 : 0;
|
520
546
|
signal->e2 = 0;
|
521
|
-
signal->
|
547
|
+
signal->rela_loc = MIG_RIGHT;
|
522
548
|
return;
|
523
549
|
case 8:
|
524
550
|
signal->e1 = 4;
|
525
551
|
signal->i2 = i != 0 ? i - 1 : N - 1;
|
526
552
|
signal->j2 = j;
|
527
553
|
signal->e2 = 3;
|
528
|
-
signal->
|
554
|
+
signal->rela_loc = MIG_UP;
|
529
555
|
return;
|
530
556
|
case 9:
|
531
557
|
signal->e1 = 4;
|
532
558
|
signal->i2 = i != N - 1 ? i + 1 : 0;
|
533
559
|
signal->j2 = j;
|
534
560
|
signal->e2 = 3;
|
535
|
-
signal->
|
561
|
+
signal->rela_loc = MIG_DOWN;
|
536
562
|
return;
|
537
563
|
case 10:
|
538
564
|
signal->e1 = 4;
|
539
565
|
signal->i2 = i;
|
540
566
|
signal->j2 = j != 0 ? j - 1 : M - 1;
|
541
567
|
signal->e2 = 3;
|
542
|
-
signal->
|
568
|
+
signal->rela_loc = MIG_LEFT;
|
543
569
|
return;
|
544
570
|
default:
|
545
571
|
signal->e1 = 4;
|
546
572
|
signal->i2 = i;
|
547
573
|
signal->j2 = j != M - 1 ? j + 1 : 0;
|
548
574
|
signal->e2 = 3;
|
549
|
-
signal->
|
575
|
+
signal->rela_loc = MIG_RIGHT;
|
550
576
|
return;
|
551
577
|
//default:
|
552
578
|
// fprintf(stderr, "Bug: invalid case in make_signal_pr, i, j, e: %zu, %zu, %hhu\n", i, j, e);
|
@@ -28,7 +28,7 @@ from .data_tools import save_data, read_data
|
|
28
28
|
from .analysis import rounds_expected, scale_maxtime, check_convergence, combine_sim
|
29
29
|
|
30
30
|
from .figures import (UV_hmap, UV_bar, UV_dyna, UV_hist, UV_std, UV_expected,
|
31
|
-
pi_hmap, pi_bar, pi_dyna, pi_hist, pi_std, UV_pi)
|
31
|
+
pi_hmap, pi_bar, pi_dyna, pi_hist, pi_std, UV_pi, video_fig)
|
32
32
|
|
33
33
|
from .test_var import (test_var1, var_UV1, var_pi1, var_convergence1, get_dirs1,
|
34
34
|
test_var2, var_UV2, var_pi2, var_convergence2, get_dirs2)
|
@@ -43,7 +43,7 @@ data_members = ['save_data', 'read_data']
|
|
43
43
|
analysis_members = ['expected_rounds', 'scale_maxtime', 'check_convergence', 'combine_mod']
|
44
44
|
|
45
45
|
figures_members = ['UV_hmap', 'UV_bar', 'UV_dyna', 'UV_hist', 'UV_std', 'UV_expected_val', 'UV_expected',
|
46
|
-
'pi_hmap', 'pi_bar', 'pi_dyna', 'pi_hist', 'pi_std', 'UV_pi']
|
46
|
+
'pi_hmap', 'pi_bar', 'pi_dyna', 'pi_hist', 'pi_std', 'UV_pi', 'video_fig']
|
47
47
|
|
48
48
|
test_var_members = ['test_var1', 'var_UV1', 'var_pi1', 'var_convergence1', 'get_dirs1',
|
49
49
|
'test_var2', 'var_UV2', 'var_pi2', 'var_convergence2', 'get_dirs2']
|
@@ -1,4 +1,4 @@
|
|
1
|
-
__version__ = '2.2
|
1
|
+
__version__ = '2.3.2'
|
2
2
|
|
3
3
|
'''
|
4
4
|
version history:
|
@@ -35,4 +35,8 @@ version history:
|
|
35
35
|
2.2.1: change heatmap plotting tool from Seaborn to Matplotlib. Change video maker to cv2 (opencv-python).
|
36
36
|
2.2.2: impose stricter overflow error check. Used update_mig_one function (already written before, didn't use). This gives 30% speed improvement.
|
37
37
|
2.2.3: raised rate calculation to higher accuracy (long double), and switched to 30-bit random number generator.
|
38
|
+
2.3.1: roll back accuracy update. Decrease toleratable bound for exponent of exp() to 500.
|
39
|
+
Add video_fig function to figures module, which plots change of patch popu/payoff overtime in a 2D figure. Add auto-sorting for values passed to test_var plot functions.
|
40
|
+
2.3.2: allow play-with-self in payoff calculation. Changed migration function to e^(w*pi) (removed "1+" term).
|
41
|
+
Simplified update-migration functions, improve speed by ~10%. Add -march=native flag to Makefile.
|
38
42
|
'''
|
@@ -306,9 +306,9 @@ def pi_hmap(mod, ax_U = None, ax_V = None, U_color = 'BuPu', V_color = 'YlGn', s
|
|
306
306
|
Upi_ave = figure_t.ave_interval(mod.Upi, start_index, end_index)
|
307
307
|
V_pi_ave = figure_t.ave_interval(mod.Vpi, start_index, end_index)
|
308
308
|
|
309
|
-
U_title = figure_t.gen_title('Payoff ' + r'$
|
309
|
+
U_title = figure_t.gen_title('Payoff ' + r'$p_H$', start, end)
|
310
310
|
U_text = figure_t.gen_text(np.mean(Upi_ave), np.std(Upi_ave))
|
311
|
-
V_title = figure_t.gen_title('Payoff ' + r'$
|
311
|
+
V_title = figure_t.gen_title('Payoff ' + r'$p_D$', start, end)
|
312
312
|
V_text = figure_t.gen_text(np.mean(V_pi_ave), np.std(V_pi_ave))
|
313
313
|
|
314
314
|
figure_t.hmap(Upi_ave, ax_U, U_color, U_title, U_text, vmin = vrange_U[0], vmax = vrange_U[1])
|
@@ -334,13 +334,13 @@ def pi_bar(mod, ax_U = None, ax_V = None, U_color = 'violet', V_color = 'yellowg
|
|
334
334
|
Upi_ave = figure_t.ave_interval_1D(mod.Upi, start_index, end_index)
|
335
335
|
V_pi_ave = figure_t.ave_interval_1D(mod.Vpi, start_index, end_index)
|
336
336
|
|
337
|
-
U_title = figure_t.gen_title(r'$
|
337
|
+
U_title = figure_t.gen_title(r'$p_H$', start, end)
|
338
338
|
U_text = figure_t.gen_text(np.mean(Upi_ave), np.std(Upi_ave))
|
339
|
-
V_title = figure_t.gen_title(r'$
|
339
|
+
V_title = figure_t.gen_title(r'$p_D$', start, end)
|
340
340
|
V_text = figure_t.gen_text(np.mean(V_pi_ave), np.std(V_pi_ave))
|
341
341
|
|
342
|
-
ax_U = figure_t.bar(Upi_ave, ax_U, U_color, 'Patches', 'Payoff ' + r'$
|
343
|
-
ax_V = figure_t.bar(V_pi_ave, ax_V, V_color, 'Patches', 'Payoff ' + r'$
|
342
|
+
ax_U = figure_t.bar(Upi_ave, ax_U, U_color, 'Patches', 'Payoff ' + r'$p_H$', U_title, U_text)
|
343
|
+
ax_V = figure_t.bar(V_pi_ave, ax_V, V_color, 'Patches', 'Payoff ' + r'$p_D$', V_title, V_text)
|
344
344
|
|
345
345
|
return ax_U, ax_V
|
346
346
|
|
@@ -376,12 +376,12 @@ def pi_dyna(mod, ax = None, interval = 20, grid = True):
|
|
376
376
|
if ax == None:
|
377
377
|
_, ax = plt.subplots()
|
378
378
|
ax.grid(grid)
|
379
|
-
ax.plot(xaxis, U_curve, CURVE_TYPE, label = r'$
|
380
|
-
ax.plot(xaxis, V_curve, CURVE_TYPE, label = r'$
|
379
|
+
ax.plot(xaxis, U_curve, CURVE_TYPE, label = r'$p_H$')
|
380
|
+
ax.plot(xaxis, V_curve, CURVE_TYPE, label = r'$p_D$')
|
381
381
|
ax.plot(xaxis, total_curve, CURVE_TYPE, label = 'total')
|
382
382
|
ax.set_xlabel('Time')
|
383
383
|
ax.set_ylabel('Payoff')
|
384
|
-
ax.set_title('Payoff ' + r'$
|
384
|
+
ax.set_title('Payoff ' + r'$p_H$' + ' & ' + r'$p_D$' + ' over time')
|
385
385
|
ax.legend()
|
386
386
|
|
387
387
|
return ax
|
@@ -408,17 +408,17 @@ def pi_hist(mod, ax_U = None, ax_V = None, U_color = 'violet', V_color = 'yellow
|
|
408
408
|
|
409
409
|
if ax_U == None:
|
410
410
|
_, ax_U = plt.subplots()
|
411
|
-
ax_U.set_xlabel('Payoff ' + r'$
|
411
|
+
ax_U.set_xlabel('Payoff ' + r'$p_H$')
|
412
412
|
ax_U.set_ylabel('Density')
|
413
413
|
ax_U.hist(Upi_ave, color = U_color, density = True)
|
414
|
-
ax_U.set_title(figure_t.gen_title('Payoff ' + r'$
|
414
|
+
ax_U.set_title(figure_t.gen_title('Payoff ' + r'$p_H$' + ' Hist', start, end))
|
415
415
|
|
416
416
|
if ax_V == None:
|
417
417
|
_, ax_V = plt.subplots()
|
418
|
-
ax_V.set_xlabel('Payoff ' + r'$
|
418
|
+
ax_V.set_xlabel('Payoff ' + r'$p_D$')
|
419
419
|
ax_V.set_ylabel('Density')
|
420
420
|
ax_V.hist(V_pi_ave, color = V_color, density = True)
|
421
|
-
ax_V.set_title(figure_t.gen_title('Payoff ' + r'$
|
421
|
+
ax_V.set_title(figure_t.gen_title('Payoff ' + r'$p_D$' + ' Hist', start, end))
|
422
422
|
|
423
423
|
return ax_U, ax_V
|
424
424
|
|
@@ -453,8 +453,8 @@ def pi_std(mod, ax = None, interval = 20, grid = True):
|
|
453
453
|
if ax == None:
|
454
454
|
_, ax = plt.subplots()
|
455
455
|
ax.grid(grid)
|
456
|
-
ax.plot(xaxis, Upi_std, CURVE_TYPE, label = r'$
|
457
|
-
ax.plot(xaxis, V_pi_std, CURVE_TYPE, label = r'$
|
456
|
+
ax.plot(xaxis, Upi_std, CURVE_TYPE, label = r'$p_H$' + ' std')
|
457
|
+
ax.plot(xaxis, V_pi_std, CURVE_TYPE, label = r'$p_D$' + ' std')
|
458
458
|
ax.legend()
|
459
459
|
ax.set_xlabel('Time')
|
460
460
|
ax.set_ylabel('Std Dev')
|
@@ -484,9 +484,66 @@ def UV_pi(mod, ax_U = None, ax_V = None, U_color = 'violet', V_color = 'yellowgr
|
|
484
484
|
V_pi_ave = figure_t.ave_interval(mod.Vpi, start_index, end_index)
|
485
485
|
|
486
486
|
|
487
|
-
ax_U = figure_t.scatter(U_ave, Upi_ave, ax_U, U_color, alpha, xlabel = 'U', ylabel = 'Payoff ' + r'$
|
488
|
-
ax_V = figure_t.scatter(V_ave, V_pi_ave, ax_V, V_color, alpha, xlabel = 'V', ylabel = 'Payoff ' + r'$
|
487
|
+
ax_U = figure_t.scatter(U_ave, Upi_ave, ax_U, U_color, alpha, xlabel = 'U', ylabel = 'Payoff ' + r'$p_H$', title = 'U - ' + r'$p_H$')
|
488
|
+
ax_V = figure_t.scatter(V_ave, V_pi_ave, ax_V, V_color, alpha, xlabel = 'V', ylabel = 'Payoff ' + r'$p_D$', title = 'V - ' + r'$p_D$')
|
489
489
|
|
490
490
|
return ax_U, ax_V
|
491
491
|
|
492
492
|
|
493
|
+
|
494
|
+
def video_fig(mod, ax_list = None, num_grid = 100, U_color = 'Purples', V_color = 'Greens'):
|
495
|
+
'''
|
496
|
+
Plot distribution dynamics over time, of U, V population and payoff.
|
497
|
+
|
498
|
+
mod: simulation.model object
|
499
|
+
ax_list: a 2*2 list of ax, or None (a new 2*2 ax_list will be created)
|
500
|
+
num_grid: how many grid for the time axis
|
501
|
+
U_color & V_color: matplotlib color map, color for U, V population and payoff.
|
502
|
+
'''
|
503
|
+
|
504
|
+
if num_grid > mod.max_record:
|
505
|
+
raise ValueError('num_grid too large, larger than mod.max_record')
|
506
|
+
idx_step = int(mod.max_record / num_grid)
|
507
|
+
ave_U = []
|
508
|
+
ave_V = []
|
509
|
+
ave_Upi = []
|
510
|
+
ave_Vpi = []
|
511
|
+
|
512
|
+
for lower_idx in range(0, mod.max_record, idx_step):
|
513
|
+
ave_U.append(figure_t.ave_interval_1D(mod.U, lower_idx, lower_idx + idx_step))
|
514
|
+
ave_V.append(figure_t.ave_interval_1D(mod.V, lower_idx, lower_idx + idx_step))
|
515
|
+
ave_Upi.append(figure_t.ave_interval_1D(mod.Upi, lower_idx, lower_idx + idx_step))
|
516
|
+
ave_Vpi.append(figure_t.ave_interval_1D(mod.Vpi, lower_idx, lower_idx + idx_step))
|
517
|
+
|
518
|
+
if ax_list == None:
|
519
|
+
|
520
|
+
_, ax_list = plt.subplots(2, 2, figsize = (9.6, 12.8), dpi = 300)
|
521
|
+
|
522
|
+
for i in range(2):
|
523
|
+
for j in range(2):
|
524
|
+
ax_list[i, j].spines['top'].set_visible(False)
|
525
|
+
ax_list[i, j].spines['right'].set_visible(False)
|
526
|
+
ax_list[i, j].set_xlabel('Patches')
|
527
|
+
ax_list[i, j].set_ylabel('Time')
|
528
|
+
ax_list[i, j].set_xlim([0, mod.M])
|
529
|
+
ax_list[i, j].set_ylim([0, mod.maxtime])
|
530
|
+
|
531
|
+
|
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])
|
534
|
+
ax_list[0, 0].set_title('Population U over time')
|
535
|
+
|
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])
|
538
|
+
ax_list[0, 1].set_title('Population V over time')
|
539
|
+
|
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])
|
542
|
+
ax_list[1, 0].set_title('Payoff ' + r'$p_H$' + ' over time')
|
543
|
+
|
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])
|
546
|
+
ax_list[1, 1].set_title('Payoff ' + r'$p_D$' + ' over time')
|
547
|
+
|
548
|
+
return ax_list
|
549
|
+
|
@@ -169,6 +169,7 @@ def var_UV1(var, values, var_dirs, ax_U = None, ax_V = None, start = 0.95, end =
|
|
169
169
|
# average value of U, V over the interval. One entry for one value of var
|
170
170
|
U_ave = []
|
171
171
|
V_ave = []
|
172
|
+
values = sorted(values)
|
172
173
|
|
173
174
|
for k in range(len(var_dirs)):
|
174
175
|
try:
|
@@ -234,6 +235,8 @@ def var_UV2(var1, var2, values1, values2, var_dirs, ax_U = None, ax_V = None, va
|
|
234
235
|
# average value of U, V over the interval. One entry for one values of var1, var2
|
235
236
|
U_ave = [[] for k1 in range(len(var_dirs))]
|
236
237
|
V_ave = [[] for k1 in range(len(var_dirs))]
|
238
|
+
values1 = sorted(values1)
|
239
|
+
values2 = sorted(values2)
|
237
240
|
|
238
241
|
for k1 in range(len(var_dirs)):
|
239
242
|
for k2 in range(len(var_dirs[k1])):
|
@@ -321,6 +324,7 @@ def var_pi1(var, values, var_dirs, ax_U = None, ax_V = None, start = 0.95, end =
|
|
321
324
|
# take average value of payoff over an interval of time
|
322
325
|
U_ave = []
|
323
326
|
V_ave = []
|
327
|
+
values = sorted(values)
|
324
328
|
|
325
329
|
for k in range(len(var_dirs)):
|
326
330
|
try:
|
@@ -347,12 +351,12 @@ def var_pi1(var, values, var_dirs, ax_U = None, ax_V = None, start = 0.95, end =
|
|
347
351
|
var_disp = PATCH_VAR_DISP[var]
|
348
352
|
|
349
353
|
ax_U.set_xlabel(var_disp)
|
350
|
-
ax_U.set_ylabel('Payoff ' + r'$
|
354
|
+
ax_U.set_ylabel('Payoff ' + r'$p_H$')
|
351
355
|
ax_U.plot(values, U_ave, DOTTED_CURVE_TYPE, color = U_color)
|
352
356
|
ax_U.set_title(figure_t.gen_title(var_disp + r'$\,-\,p_U$', start, end))
|
353
357
|
|
354
358
|
ax_V.set_xlabel(var_disp)
|
355
|
-
ax_V.set_ylabel('Payoff ' + r'$
|
359
|
+
ax_V.set_ylabel('Payoff ' + r'$p_D$')
|
356
360
|
ax_V.plot(values, V_ave, DOTTED_CURVE_TYPE, color = V_color)
|
357
361
|
ax_V.set_title(figure_t.gen_title(var_disp + r'$\,-\,p_V$', start, end))
|
358
362
|
|
@@ -384,6 +388,8 @@ def var_pi2(var1, var2, values1, values2, var_dirs, ax_U = None, ax_V = None, va
|
|
384
388
|
# take average value of payoff over an interval of time
|
385
389
|
U_ave = [[] for k1 in range(len(var_dirs))]
|
386
390
|
V_ave = [[] for k1 in range(len(var_dirs))]
|
391
|
+
values1 = sorted(values1)
|
392
|
+
values2 = sorted(values2)
|
387
393
|
|
388
394
|
for k1 in range(len(var_dirs)):
|
389
395
|
for k2 in range(len(var_dirs[k1])):
|
@@ -172,7 +172,7 @@ def ave_interval(data, start_index, end_index):
|
|
172
172
|
def ave_interval_1D(data, start_index, end_index):
|
173
173
|
'''
|
174
174
|
Calculate average value of data over an interval. Return a 1D np.array.
|
175
|
-
Assume data is 3D and has shape (
|
175
|
+
Assume data is 3D and has shape (N x M x K). Then implicitly 'compress' that N x M to 1D (NM) and takes average on the 3rd axis K.
|
176
176
|
|
177
177
|
Input:
|
178
178
|
data: 3D np.array or list. One of its dimensions must have size 1. Will take average on the 3rd axis.
|
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
|
File without changes
|
File without changes
|