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.
- {piegy-2.3.7/src/piegy.egg-info → piegy-2.3.8}/PKG-INFO +1 -1
- {piegy-2.3.7 → piegy-2.3.8}/pyproject.toml +1 -1
- {piegy-2.3.7 → piegy-2.3.8}/src/piegy/C_core/patch.c +20 -14
- {piegy-2.3.7 → piegy-2.3.8}/src/piegy/C_core/patch.h +6 -3
- {piegy-2.3.7 → piegy-2.3.8}/src/piegy/C_core/sim_funcs.c +62 -58
- {piegy-2.3.7 → piegy-2.3.8}/src/piegy/C_core/sim_funcs.h +21 -29
- {piegy-2.3.7 → piegy-2.3.8}/src/piegy/__init__.py +2 -2
- {piegy-2.3.7 → piegy-2.3.8}/src/piegy/__version__.py +2 -1
- {piegy-2.3.7 → piegy-2.3.8}/src/piegy/data_tools.py +4 -4
- {piegy-2.3.7 → piegy-2.3.8}/src/piegy/simulation.py +3 -3
- {piegy-2.3.7 → piegy-2.3.8}/src/piegy/test_var.py +8 -8
- {piegy-2.3.7 → piegy-2.3.8/src/piegy.egg-info}/PKG-INFO +1 -1
- {piegy-2.3.7 → piegy-2.3.8}/LICENSE.txt +0 -0
- {piegy-2.3.7 → piegy-2.3.8}/MANIFEST.in +0 -0
- {piegy-2.3.7 → piegy-2.3.8}/README.md +0 -0
- {piegy-2.3.7 → piegy-2.3.8}/setup.cfg +0 -0
- {piegy-2.3.7 → piegy-2.3.8}/setup.py +0 -0
- {piegy-2.3.7 → piegy-2.3.8}/src/piegy/C_core/Makefile +0 -0
- {piegy-2.3.7 → piegy-2.3.8}/src/piegy/C_core/model.c +0 -0
- {piegy-2.3.7 → piegy-2.3.8}/src/piegy/C_core/model.h +0 -0
- {piegy-2.3.7 → piegy-2.3.8}/src/piegy/analysis.py +0 -0
- {piegy-2.3.7 → piegy-2.3.8}/src/piegy/build_info.py +0 -0
- {piegy-2.3.7 → piegy-2.3.8}/src/piegy/figures.py +0 -0
- {piegy-2.3.7 → piegy-2.3.8}/src/piegy/simulation_py.py +0 -0
- {piegy-2.3.7 → piegy-2.3.8}/src/piegy/tools/__init__.py +0 -0
- {piegy-2.3.7 → piegy-2.3.8}/src/piegy/tools/figure_tools.py +0 -0
- {piegy-2.3.7 → piegy-2.3.8}/src/piegy/tools/file_tools.py +0 -0
- {piegy-2.3.7 → piegy-2.3.8}/src/piegy/tools/find_C.py +0 -0
- {piegy-2.3.7 → piegy-2.3.8}/src/piegy/videos.py +0 -0
- {piegy-2.3.7 → piegy-2.3.8}/src/piegy.egg-info/SOURCES.txt +0 -0
- {piegy-2.3.7 → piegy-2.3.8}/src/piegy.egg-info/dependency_links.txt +0 -0
- {piegy-2.3.7 → piegy-2.3.8}/src/piegy.egg-info/requires.txt +0 -0
- {piegy-2.3.7 → piegy-2.3.8}/src/piegy.egg-info/top_level.txt +0 -0
@@ -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
|
16
|
-
p->V_pi = 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
|
20
|
-
p->V_weight[i] = 0
|
21
|
-
p->pi_death_rates[i] = 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
|
30
|
+
p->mig_rates[i] = 0;
|
25
31
|
}
|
26
|
-
p->sum_U_weight = 0
|
27
|
-
p->sum_V_weight = 0
|
28
|
-
p->sum_pi_death_rates = 0
|
29
|
-
p->sum_mig_rates = 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,
|
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
|
-
|
46
|
-
|
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,
|
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, &
|
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]
|
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]
|
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*
|
198
|
-
double*
|
199
|
-
double*
|
200
|
-
double*
|
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
|
-
//
|
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
|
-
//
|
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]
|
319
|
-
update_mig_just_rate(&world[sij1]
|
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]
|
332
|
-
update_pi_k(&world[sij2]
|
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],
|
335
|
-
update_mig_weight_rate(&world[sij2],
|
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],
|
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],
|
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],
|
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
|
-
|
440
|
-
|
441
|
-
|
442
|
-
|
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
|
-
|
454
|
-
|
455
|
-
|
456
|
-
|
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
|
521
|
+
size_t round = 0;
|
519
522
|
|
520
|
-
while (
|
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",
|
527
|
+
snprintf(curr_msg + strlen(curr_msg), sizeof(curr_msg) - strlen(curr_msg), "%zu", round);
|
525
528
|
|
526
|
-
|
527
|
-
|
528
|
-
|
529
|
-
|
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
|
-
|
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
|
-
|
553
|
-
|
554
|
-
|
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
|
126
|
-
//
|
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 *
|
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 *
|
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] =
|
157
|
-
p->pi_death_rates[3] =
|
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
|
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 =
|
174
|
-
double mu2_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,
|
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 =
|
200
|
-
double w2_Vpi =
|
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 =
|
230
|
-
double mu2_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
|
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 =
|
255
|
-
double w2 =
|
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 =
|
278
|
-
double mu2_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
|
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 = ['
|
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.
|
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
|
-
-
|
6
|
-
-
|
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
|
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
|
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.
|
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
|
-
|
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
|
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.
|
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.
|
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.
|
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.
|
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.
|
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.
|
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.
|
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.
|
584
|
+
simk = data_t.load(dirs)
|
585
585
|
except FileNotFoundError:
|
586
586
|
print(dirs + ' data not found, skipped')
|
587
587
|
continue
|
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
|