piegy 2.3.1__tar.gz → 2.3.3__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.1/src/piegy.egg-info → piegy-2.3.3}/PKG-INFO +1 -1
- {piegy-2.3.1 → piegy-2.3.3}/pyproject.toml +1 -1
- {piegy-2.3.1 → piegy-2.3.3}/src/piegy/C_core/Makefile +1 -1
- {piegy-2.3.1 → piegy-2.3.3}/src/piegy/C_core/runner.c +5 -5
- {piegy-2.3.1 → piegy-2.3.3}/src/piegy/C_core/sim_funcs.c +30 -45
- {piegy-2.3.1 → piegy-2.3.3}/src/piegy/C_core/sim_funcs.h +108 -81
- {piegy-2.3.1 → piegy-2.3.3}/src/piegy/__version__.py +4 -1
- {piegy-2.3.1 → piegy-2.3.3}/src/piegy/figures.py +6 -6
- {piegy-2.3.1 → piegy-2.3.3/src/piegy.egg-info}/PKG-INFO +1 -1
- {piegy-2.3.1 → piegy-2.3.3}/LICENSE.txt +0 -0
- {piegy-2.3.1 → piegy-2.3.3}/MANIFEST.in +0 -0
- {piegy-2.3.1 → piegy-2.3.3}/README.md +0 -0
- {piegy-2.3.1 → piegy-2.3.3}/setup.cfg +0 -0
- {piegy-2.3.1 → piegy-2.3.3}/setup.py +0 -0
- {piegy-2.3.1 → piegy-2.3.3}/src/piegy/C_core/model.c +0 -0
- {piegy-2.3.1 → piegy-2.3.3}/src/piegy/C_core/model.h +0 -0
- {piegy-2.3.1 → piegy-2.3.3}/src/piegy/C_core/patch.c +0 -0
- {piegy-2.3.1 → piegy-2.3.3}/src/piegy/C_core/patch.h +0 -0
- {piegy-2.3.1 → piegy-2.3.3}/src/piegy/__init__.py +0 -0
- {piegy-2.3.1 → piegy-2.3.3}/src/piegy/analysis.py +0 -0
- {piegy-2.3.1 → piegy-2.3.3}/src/piegy/build_info.py +0 -0
- {piegy-2.3.1 → piegy-2.3.3}/src/piegy/data_tools.py +0 -0
- {piegy-2.3.1 → piegy-2.3.3}/src/piegy/simulation.py +0 -0
- {piegy-2.3.1 → piegy-2.3.3}/src/piegy/simulation_py.py +0 -0
- {piegy-2.3.1 → piegy-2.3.3}/src/piegy/test_var.py +0 -0
- {piegy-2.3.1 → piegy-2.3.3}/src/piegy/tools/__init__.py +0 -0
- {piegy-2.3.1 → piegy-2.3.3}/src/piegy/tools/figure_tools.py +0 -0
- {piegy-2.3.1 → piegy-2.3.3}/src/piegy/tools/file_tools.py +0 -0
- {piegy-2.3.1 → piegy-2.3.3}/src/piegy/tools/find_C.py +0 -0
- {piegy-2.3.1 → piegy-2.3.3}/src/piegy/videos.py +0 -0
- {piegy-2.3.1 → piegy-2.3.3}/src/piegy.egg-info/SOURCES.txt +0 -0
- {piegy-2.3.1 → piegy-2.3.3}/src/piegy.egg-info/dependency_links.txt +0 -0
- {piegy-2.3.1 → piegy-2.3.3}/src/piegy.egg-info/requires.txt +0 -0
- {piegy-2.3.1 → piegy-2.3.3}/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 ##
|
@@ -11,14 +11,14 @@
|
|
11
11
|
int main() {
|
12
12
|
size_t N = 1;
|
13
13
|
size_t M = 100;
|
14
|
-
double maxtime =
|
14
|
+
double maxtime = 600;
|
15
15
|
double record_itv = 0.1;
|
16
|
-
size_t sim_time =
|
16
|
+
size_t sim_time = 1;
|
17
17
|
bool boundary = true;
|
18
|
-
uint32_t I_single[2] = {
|
18
|
+
uint32_t I_single[2] = {440, 220};
|
19
19
|
double X_single[4] = {-1, 4, 0, 2};
|
20
|
-
double P_single[6] = {0.5, 0.5,
|
21
|
-
int32_t print_pct =
|
20
|
+
double P_single[6] = {0.5, 0.5, 100, 100, 0.001, 0.001};
|
21
|
+
int32_t print_pct = 1;
|
22
22
|
int32_t seed = 36; // -1 for None
|
23
23
|
|
24
24
|
uint32_t I[N * M * 2];
|
@@ -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
|
}
|
@@ -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
|
|
@@ -300,71 +300,58 @@ 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
|
-
|
307
|
-
|
308
|
-
sum_rates -= picked_rate;
|
306
|
+
sum_rates_by_row[si1] -= patch_rates[sij1];
|
307
|
+
sum_rates -= patch_rates[sij1];
|
309
308
|
|
310
309
|
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
|
-
}
|
310
|
+
init_mig(&world[sij1], &(mod->P[sij1 * 6]));
|
318
311
|
|
319
|
-
|
320
|
-
patch_rates[sij1]
|
321
|
-
|
322
|
-
sum_rates += picked_rate;
|
312
|
+
patch_rates[sij1] = world[sij1].sum_pi_death_rates + world[sij1].sum_mig_rates;
|
313
|
+
sum_rates_by_row[si1] += patch_rates[sij1];
|
314
|
+
sum_rates += patch_rates[sij1];
|
323
315
|
} else {
|
324
316
|
// two
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
sum_rates -= picked_rate1;
|
330
|
-
sum_rates -= picked_rate2;
|
317
|
+
sum_rates_by_row[si1] -= patch_rates[sij1];
|
318
|
+
sum_rates_by_row[si2] -= patch_rates[sij2];
|
319
|
+
sum_rates -= patch_rates[sij1];
|
320
|
+
sum_rates -= patch_rates[sij2];
|
331
321
|
|
332
322
|
update_pi_k(&world[sij1], &(mod->X[sij1 * 4]), &(mod->P[sij1 * 6])); // update both patches' payoffs first
|
333
323
|
update_pi_k(&world[sij2], &(mod->X[sij2 * 4]), &(mod->P[sij2 * 6]));
|
334
|
-
|
335
|
-
|
336
|
-
|
324
|
+
|
325
|
+
if (update_mig_weight_rate(&world[sij1], &(mod->P[sij1 * 6]), rela_loc) == SIM_OVERFLOW ||
|
326
|
+
update_mig_weight_rate(&world[sij2], &(mod->P[sij2 * 6]), rela_loc ^ 1) == SIM_OVERFLOW) {
|
327
|
+
|
337
328
|
fprintf(stdout, "\nError: overflow at t = %f\n", time);
|
338
329
|
fflush(stdout);
|
339
330
|
single_test_free(&world, &nb_indices, &patch_rates, &sum_rates_by_row);
|
340
331
|
return SIM_OVERFLOW;
|
341
332
|
}
|
342
333
|
|
343
|
-
|
344
|
-
|
345
|
-
|
346
|
-
|
347
|
-
patch_rates[
|
348
|
-
|
349
|
-
sum_rates_by_row[si2] += picked_rate2;
|
350
|
-
sum_rates += picked_rate1;
|
351
|
-
sum_rates += picked_rate2;
|
334
|
+
patch_rates[sij1] = world[sij1].sum_pi_death_rates + world[sij1].sum_mig_rates;
|
335
|
+
patch_rates[sij2] = world[sij2].sum_pi_death_rates + world[sij2].sum_mig_rates;
|
336
|
+
sum_rates_by_row[si1] += patch_rates[sij1];
|
337
|
+
sum_rates_by_row[si2] += patch_rates[sij2];
|
338
|
+
sum_rates += patch_rates[sij1];
|
339
|
+
sum_rates += patch_rates[sij2];
|
352
340
|
}
|
353
341
|
|
354
342
|
// update neighbors of last-changed patches
|
355
|
-
if (
|
343
|
+
if (rela_loc == NO_MIG) {
|
356
344
|
for (uint8_t k = 0; k < 4; k++) {
|
357
345
|
size_t nb_idx = nb_indices[sij1 * 4 + k];
|
358
346
|
if (nb_idx == NM) { continue; } // invalid neighbor
|
359
347
|
// all neighbors, as long as exists, need to change
|
360
|
-
|
361
|
-
if (mig_result == SIM_OVERFLOW) {
|
348
|
+
if (update_mig_weight_rate(&world[nb_idx], &(mod->P[nb_idx * 6]), k ^ 1) == SIM_OVERFLOW) {
|
362
349
|
fprintf(stdout, "\nError: overflow at t = %f\n", time);
|
363
350
|
fflush(stdout);
|
364
351
|
single_test_free(&world, &nb_indices, &patch_rates, &sum_rates_by_row);
|
365
352
|
return SIM_OVERFLOW;
|
366
353
|
}
|
367
|
-
//
|
354
|
+
// patch_rates, and sums of rates is not changed
|
368
355
|
}
|
369
356
|
} else {
|
370
357
|
// the first patch
|
@@ -372,8 +359,7 @@ static uint8_t single_test(model_t* restrict mod, uint32_t update_sum_freq, char
|
|
372
359
|
size_t nb_idx = nb_indices[sij1 * 4 + k];
|
373
360
|
if (nb_idx == NM) { continue; }
|
374
361
|
if (nb_need_change(nb_idx, sij1, sij2)) {
|
375
|
-
|
376
|
-
if (mig_result == SIM_OVERFLOW) {
|
362
|
+
if (update_mig_weight_rate(&world[nb_idx], &(mod->P[nb_idx * 6]), k ^ 1) == SIM_OVERFLOW) {
|
377
363
|
fprintf(stdout, "\nError: overflow at t = %f\n", time);
|
378
364
|
fflush(stdout);
|
379
365
|
single_test_free(&world, &nb_indices, &patch_rates, &sum_rates_by_row);
|
@@ -386,8 +372,7 @@ static uint8_t single_test(model_t* restrict mod, uint32_t update_sum_freq, char
|
|
386
372
|
size_t nb_idx = nb_indices[sij2 * 4 + k];
|
387
373
|
if (nb_idx == NM) { continue; }
|
388
374
|
if (nb_need_change(nb_idx, sij1, sij2)) {
|
389
|
-
|
390
|
-
if (mig_result == SIM_OVERFLOW) {
|
375
|
+
if (update_mig_weight_rate(&world[nb_idx], &(mod->P[nb_idx * 6]), k ^ 1) == SIM_OVERFLOW) {
|
391
376
|
fprintf(stdout, "\nError: overflow at t = %f\n", time);
|
392
377
|
fflush(stdout);
|
393
378
|
single_test_free(&world, &nb_indices, &patch_rates, &sum_rates_by_row);
|
@@ -415,7 +400,7 @@ static uint8_t single_test(model_t* restrict mod, uint32_t update_sum_freq, char
|
|
415
400
|
|
416
401
|
// let the event happenn
|
417
402
|
change_popu(&world[signal.ij1], signal.e1);
|
418
|
-
if (
|
403
|
+
if (signal.rela_loc != NO_MIG) {
|
419
404
|
change_popu(&world[signal.ij2], signal.e2);
|
420
405
|
}
|
421
406
|
|
@@ -28,14 +28,15 @@
|
|
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
|
-
// where exp(x) is considered overflow
|
39
|
+
// where 1 + 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
41
|
#define EXP_OVERFLOW_BOUND 500
|
41
42
|
|
@@ -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;
|
@@ -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 - 1;
|
120
|
+
//double U_ratio = U / sum;
|
121
|
+
//double V_ratio = V / sum;
|
117
122
|
|
118
|
-
if (
|
119
|
-
if (U
|
120
|
-
p->U_pi = (
|
121
|
-
(V / sum_minus_1) * M_start[1];
|
123
|
+
if (sum > 0) {
|
124
|
+
if (U > 0) {
|
125
|
+
p->U_pi = (U - 1) / sum * M_start[0] + V / sum * M_start[1];
|
122
126
|
} else {
|
123
127
|
p->U_pi = 0.0;
|
124
128
|
}
|
125
129
|
|
126
|
-
if (V
|
127
|
-
p->V_pi =
|
128
|
-
((V - 1) / sum_minus_1) * M_start[3];
|
130
|
+
if (V > 0) {
|
131
|
+
p->V_pi = U / sum * M_start[2] + (V - 1) / 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 + 1);
|
145
|
+
p->pi_death_rates[3] = P_start[5] * V * (sum + 1);
|
143
146
|
|
144
147
|
p->sum_pi_death_rates = 0.0;
|
145
148
|
for (size_t i = 0; i < 4; i++) {
|
@@ -148,19 +151,38 @@ 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 last-changed patch, when there is only one last-changed patch
|
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;
|
163
|
+
p->sum_mig_rates = mu1_U + mu2_V;
|
164
|
+
|
165
|
+
double mu1_U_divide_sum = mu1_U / p->sum_U_weight;
|
166
|
+
double mu2_V_divide_sum = mu2_V / p->sum_V_weight;
|
167
|
+
|
168
|
+
for (uint8_t i = 0; i < 4; i++) {
|
169
|
+
p->mig_rates[i] = mu1_U_divide_sum * p_U_weight[i];
|
170
|
+
p->mig_rates[i + 4] = mu2_V_divide_sum * p_V_weight[i];
|
171
|
+
}
|
172
|
+
}
|
173
|
+
|
174
|
+
|
175
|
+
static inline uint8_t update_mig_weight_rate(patch_t* restrict p, const double* P_start, uint8_t loc) {
|
176
|
+
// update migration weight as well as rates, in one direction
|
177
|
+
// used by neighbors of last-changed patches
|
178
|
+
// also used by last-changed patches themselve, when there are two patch changed, to update mig rates of in each other's direction
|
179
|
+
|
158
180
|
double* p_U_weight = p->U_weight;
|
159
181
|
double* p_V_weight = p->V_weight;
|
160
182
|
|
161
|
-
patch_t* nbi = p->nb[
|
162
|
-
p->sum_U_weight -= p_U_weight[
|
163
|
-
p->sum_V_weight -= p_V_weight[
|
183
|
+
patch_t* nbi = p->nb[loc];
|
184
|
+
p->sum_U_weight -= p_U_weight[loc];
|
185
|
+
p->sum_V_weight -= p_V_weight[loc];
|
164
186
|
|
165
187
|
double w1_Upi = P_start[2] * nbi->U_pi;
|
166
188
|
double w2_Vpi = P_start[3] * nbi->V_pi;
|
@@ -171,44 +193,45 @@ static inline uint8_t update_mig_one(patch_t* restrict p, const double* restrict
|
|
171
193
|
return SIM_OVERFLOW;
|
172
194
|
}
|
173
195
|
|
174
|
-
switch(
|
196
|
+
switch(loc) {
|
175
197
|
case MIG_UP:
|
176
|
-
p_U_weight[MIG_UP] = 1
|
177
|
-
p_V_weight[MIG_UP] = 1
|
198
|
+
p_U_weight[MIG_UP] = 1 + exp(w1_Upi);
|
199
|
+
p_V_weight[MIG_UP] = 1 + exp(w2_Vpi);
|
178
200
|
break;
|
179
201
|
case MIG_DOWN:
|
180
|
-
p_U_weight[MIG_DOWN] = 1
|
181
|
-
p_V_weight[MIG_DOWN] = 1
|
202
|
+
p_U_weight[MIG_DOWN] = 1 + exp(w1_Upi);
|
203
|
+
p_V_weight[MIG_DOWN] = 1 + exp(w2_Vpi);
|
182
204
|
break;
|
183
205
|
case MIG_LEFT:
|
184
|
-
p_U_weight[MIG_LEFT] = 1
|
185
|
-
p_V_weight[MIG_LEFT] = 1
|
206
|
+
p_U_weight[MIG_LEFT] = 1 + exp(w1_Upi);
|
207
|
+
p_V_weight[MIG_LEFT] = 1 + exp(w2_Vpi);
|
186
208
|
break;
|
187
209
|
default:
|
188
|
-
p_U_weight[MIG_RIGHT] = 1
|
189
|
-
p_V_weight[MIG_RIGHT] = 1
|
210
|
+
p_U_weight[MIG_RIGHT] = 1 + exp(w1_Upi);
|
211
|
+
p_V_weight[MIG_RIGHT] = 1 + exp(w2_Vpi);
|
190
212
|
break;
|
191
213
|
}
|
192
|
-
p->sum_U_weight += p_U_weight[
|
193
|
-
p->sum_V_weight += p_V_weight[
|
214
|
+
p->sum_U_weight += p_U_weight[loc];
|
215
|
+
p->sum_V_weight += p_V_weight[loc];
|
194
216
|
|
217
|
+
double mu1_U = P_start[0] * (double)p->U;
|
218
|
+
double mu2_V = P_start[1] * (double)p->V;
|
195
219
|
double mu1_U_divide_sum = mu1_U / p->sum_U_weight;
|
196
220
|
double mu2_V_divide_sum = mu2_V / p->sum_V_weight;
|
197
221
|
|
198
|
-
for (
|
222
|
+
for (uint8_t i = 0; i < 4; i++) {
|
199
223
|
p->mig_rates[i] = mu1_U_divide_sum * p_U_weight[i];
|
200
224
|
p->mig_rates[i + 4] = mu2_V_divide_sum * p_V_weight[i];
|
201
225
|
}
|
226
|
+
p->sum_mig_rates = mu1_U + mu2_V;
|
202
227
|
|
203
228
|
return SUCCESS;
|
204
229
|
}
|
205
230
|
|
206
231
|
|
207
232
|
|
208
|
-
static inline uint8_t
|
233
|
+
static inline uint8_t init_mig(patch_t* restrict p, const double* restrict P_start) {
|
209
234
|
// 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
235
|
|
213
236
|
double* p_U_weight = p->U_weight;
|
214
237
|
double* p_V_weight = p->V_weight;
|
@@ -232,14 +255,17 @@ static inline uint8_t update_mig_all(patch_t* restrict p, const double* restrict
|
|
232
255
|
if (w2_Vpi > EXP_OVERFLOW_BOUND) {
|
233
256
|
return SIM_OVERFLOW;
|
234
257
|
}
|
235
|
-
p_U_weight[i] = 1
|
236
|
-
p_V_weight[i] = 1
|
258
|
+
p_U_weight[i] = 1 + exp(w1_Upi);
|
259
|
+
p_V_weight[i] = 1 + exp(w2_Vpi);
|
237
260
|
|
238
261
|
p->sum_U_weight += p_U_weight[i];
|
239
262
|
p->sum_V_weight += p_V_weight[i];
|
240
263
|
}
|
241
264
|
}
|
242
265
|
|
266
|
+
|
267
|
+
double mu1_U = P_start[0] * (double)p->U;
|
268
|
+
double mu2_V = P_start[1] * (double)p->V;
|
243
269
|
double mu1_U_divide_sum = mu1_U / p->sum_U_weight;
|
244
270
|
double mu2_V_divide_sum = mu2_V / p->sum_V_weight;
|
245
271
|
|
@@ -247,7 +273,6 @@ static inline uint8_t update_mig_all(patch_t* restrict p, const double* restrict
|
|
247
273
|
p->mig_rates[i] = mu1_U_divide_sum * p_U_weight[i];
|
248
274
|
p->mig_rates[i + 4] = mu2_V_divide_sum * p_V_weight[i];
|
249
275
|
}
|
250
|
-
|
251
276
|
p->sum_mig_rates = mu1_U + mu2_V;
|
252
277
|
|
253
278
|
return SUCCESS;
|
@@ -297,7 +322,7 @@ static inline void change_popu(patch_t* restrict p, uint8_t s) {
|
|
297
322
|
return;
|
298
323
|
case 2:
|
299
324
|
// Natural birth/death for U due to payoff
|
300
|
-
if (p->U_pi > 0
|
325
|
+
if (p->U_pi > 0) {
|
301
326
|
p->U += 1;
|
302
327
|
} else if (p->U > 0) {
|
303
328
|
p->U -= 1;
|
@@ -313,7 +338,7 @@ static inline void change_popu(patch_t* restrict p, uint8_t s) {
|
|
313
338
|
return;
|
314
339
|
default:
|
315
340
|
// Natural birth/death for V due to payoff
|
316
|
-
if (p->V_pi > 0
|
341
|
+
if (p->V_pi > 0) {
|
317
342
|
p->V += 1;
|
318
343
|
} else if (p->V > 0) {
|
319
344
|
p->V -= 1;
|
@@ -337,23 +362,25 @@ static inline void find_patch(patch_picked_t* restrict picked, double expected_s
|
|
337
362
|
size_t col = 0;
|
338
363
|
|
339
364
|
// 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];
|
365
|
+
if (N != 1) {
|
366
|
+
if (expected_sum < sum_rates * 0.5) {
|
367
|
+
current_sum = 0.0;
|
368
|
+
row = 0;
|
369
|
+
while (current_sum < expected_sum) {
|
370
|
+
current_sum += sum_rates_by_row[row];
|
371
|
+
row++;
|
372
|
+
}
|
354
373
|
row--;
|
374
|
+
current_sum -= sum_rates_by_row[row];
|
375
|
+
} else {
|
376
|
+
current_sum = sum_rates;
|
377
|
+
row = N - 1;
|
378
|
+
while (current_sum > expected_sum) {
|
379
|
+
current_sum -= sum_rates_by_row[row];
|
380
|
+
row--;
|
381
|
+
}
|
382
|
+
row++;
|
355
383
|
}
|
356
|
-
row++;
|
357
384
|
}
|
358
385
|
|
359
386
|
size_t row_M = row * M;
|
@@ -392,75 +419,75 @@ static inline void make_signal_zero_flux(size_t i, size_t j, uint8_t e, signal_t
|
|
392
419
|
switch (e) {
|
393
420
|
case 0:
|
394
421
|
signal->e1 = 2;
|
395
|
-
signal->
|
422
|
+
signal->rela_loc = NO_MIG;
|
396
423
|
return;
|
397
424
|
case 1:
|
398
425
|
signal->e1 = 5;
|
399
|
-
signal->
|
426
|
+
signal->rela_loc = NO_MIG;
|
400
427
|
return;
|
401
428
|
case 2:
|
402
429
|
signal->e1 = 1;
|
403
|
-
signal->
|
430
|
+
signal->rela_loc = NO_MIG;
|
404
431
|
return;
|
405
432
|
case 3:
|
406
433
|
signal->e1 = 4;
|
407
|
-
signal->
|
434
|
+
signal->rela_loc = NO_MIG;
|
408
435
|
return;
|
409
436
|
case 4:
|
410
437
|
signal->e1 = 1;
|
411
438
|
signal->i2 = i - 1;
|
412
439
|
signal->j2 = j;
|
413
440
|
signal->e2 = 0;
|
414
|
-
signal->
|
441
|
+
signal->rela_loc = MIG_UP;
|
415
442
|
return;
|
416
443
|
case 5:
|
417
444
|
signal->e1 = 1;
|
418
445
|
signal->i2 = i + 1;
|
419
446
|
signal->j2 = j;
|
420
447
|
signal->e2 = 0;
|
421
|
-
signal->
|
448
|
+
signal->rela_loc = MIG_DOWN;
|
422
449
|
return;
|
423
450
|
case 6:
|
424
451
|
signal->e1 = 1;
|
425
452
|
signal->i2 = i;
|
426
453
|
signal->j2 = j - 1;
|
427
454
|
signal->e2 = 0;
|
428
|
-
signal->
|
455
|
+
signal->rela_loc = MIG_LEFT;
|
429
456
|
return;
|
430
457
|
case 7:
|
431
458
|
signal->e1 = 1;
|
432
459
|
signal->i2 = i;
|
433
460
|
signal->j2 = j + 1;
|
434
461
|
signal->e2 = 0;
|
435
|
-
signal->
|
462
|
+
signal->rela_loc = MIG_RIGHT;
|
436
463
|
return;
|
437
464
|
case 8:
|
438
465
|
signal->e1 = 4;
|
439
466
|
signal->i2 = i - 1;
|
440
467
|
signal->j2 = j;
|
441
468
|
signal->e2 = 3;
|
442
|
-
signal->
|
469
|
+
signal->rela_loc = MIG_UP;
|
443
470
|
return;
|
444
471
|
case 9:
|
445
472
|
signal->e1 = 4;
|
446
473
|
signal->i2 = i + 1;
|
447
474
|
signal->j2 = j;
|
448
475
|
signal->e2 = 3;
|
449
|
-
signal->
|
476
|
+
signal->rela_loc = MIG_DOWN;
|
450
477
|
return;
|
451
478
|
case 10:
|
452
479
|
signal->e1 = 4;
|
453
480
|
signal->i2 = i;
|
454
481
|
signal->j2 = j - 1;
|
455
482
|
signal->e2 = 3;
|
456
|
-
signal->
|
483
|
+
signal->rela_loc = MIG_LEFT;
|
457
484
|
return;
|
458
485
|
default:
|
459
486
|
signal->e1 = 4;
|
460
487
|
signal->i2 = i;
|
461
488
|
signal->j2 = j + 1;
|
462
489
|
signal->e2 = 3;
|
463
|
-
signal->
|
490
|
+
signal->rela_loc = MIG_RIGHT;
|
464
491
|
return;
|
465
492
|
//default:
|
466
493
|
// fprintf(stderr, "Bug: invalid case in make_signal_zf, i, j, e: %zu, %zu, %hhu\n", i, j, e);
|
@@ -478,75 +505,75 @@ static inline void make_signal_periodical(size_t N, size_t M, size_t i, size_t j
|
|
478
505
|
switch (e) {
|
479
506
|
case 0:
|
480
507
|
signal->e1 = 2;
|
481
|
-
signal->
|
508
|
+
signal->rela_loc = NO_MIG;
|
482
509
|
return;
|
483
510
|
case 1:
|
484
511
|
signal->e1 = 5;
|
485
|
-
signal->
|
512
|
+
signal->rela_loc = NO_MIG;
|
486
513
|
return;
|
487
514
|
case 2:
|
488
515
|
signal->e1 = 1;
|
489
|
-
signal->
|
516
|
+
signal->rela_loc = NO_MIG;
|
490
517
|
return;
|
491
518
|
case 3:
|
492
519
|
signal->e1 = 4;
|
493
|
-
signal->
|
520
|
+
signal->rela_loc = NO_MIG;
|
494
521
|
return;
|
495
522
|
case 4:
|
496
523
|
signal->e1 = 1;
|
497
524
|
signal->i2 = i != 0 ? i - 1 : N - 1;
|
498
525
|
signal->j2 = j;
|
499
526
|
signal->e2 = 0;
|
500
|
-
signal->
|
527
|
+
signal->rela_loc = MIG_UP;
|
501
528
|
return;
|
502
529
|
case 5:
|
503
530
|
signal->e1 = 1;
|
504
531
|
signal->i2 = i != N - 1 ? i + 1 : 0;
|
505
532
|
signal->j2 = j;
|
506
533
|
signal->e2 = 0;
|
507
|
-
signal->
|
534
|
+
signal->rela_loc = MIG_DOWN;
|
508
535
|
return;
|
509
536
|
case 6:
|
510
537
|
signal->e1 = 1;
|
511
538
|
signal->i2 = i;
|
512
539
|
signal->j2 = j != 0 ? j - 1 : M - 1;
|
513
540
|
signal->e2 = 0;
|
514
|
-
signal->
|
541
|
+
signal->rela_loc = MIG_LEFT;
|
515
542
|
return;
|
516
543
|
case 7:
|
517
544
|
signal->e1 = 1;
|
518
545
|
signal->i2 = i;
|
519
546
|
signal->j2 = j != M - 1 ? j + 1 : 0;
|
520
547
|
signal->e2 = 0;
|
521
|
-
signal->
|
548
|
+
signal->rela_loc = MIG_RIGHT;
|
522
549
|
return;
|
523
550
|
case 8:
|
524
551
|
signal->e1 = 4;
|
525
552
|
signal->i2 = i != 0 ? i - 1 : N - 1;
|
526
553
|
signal->j2 = j;
|
527
554
|
signal->e2 = 3;
|
528
|
-
signal->
|
555
|
+
signal->rela_loc = MIG_UP;
|
529
556
|
return;
|
530
557
|
case 9:
|
531
558
|
signal->e1 = 4;
|
532
559
|
signal->i2 = i != N - 1 ? i + 1 : 0;
|
533
560
|
signal->j2 = j;
|
534
561
|
signal->e2 = 3;
|
535
|
-
signal->
|
562
|
+
signal->rela_loc = MIG_DOWN;
|
536
563
|
return;
|
537
564
|
case 10:
|
538
565
|
signal->e1 = 4;
|
539
566
|
signal->i2 = i;
|
540
567
|
signal->j2 = j != 0 ? j - 1 : M - 1;
|
541
568
|
signal->e2 = 3;
|
542
|
-
signal->
|
569
|
+
signal->rela_loc = MIG_LEFT;
|
543
570
|
return;
|
544
571
|
default:
|
545
572
|
signal->e1 = 4;
|
546
573
|
signal->i2 = i;
|
547
574
|
signal->j2 = j != M - 1 ? j + 1 : 0;
|
548
575
|
signal->e2 = 3;
|
549
|
-
signal->
|
576
|
+
signal->rela_loc = MIG_RIGHT;
|
550
577
|
return;
|
551
578
|
//default:
|
552
579
|
// fprintf(stderr, "Bug: invalid case in make_signal_pr, i, j, e: %zu, %zu, %hhu\n", i, j, e);
|
@@ -1,4 +1,4 @@
|
|
1
|
-
__version__ = '2.3.
|
1
|
+
__version__ = '2.3.3'
|
2
2
|
|
3
3
|
'''
|
4
4
|
version history:
|
@@ -37,4 +37,7 @@ version history:
|
|
37
37
|
2.2.3: raised rate calculation to higher accuracy (long double), and switched to 30-bit random number generator.
|
38
38
|
2.3.1: roll back accuracy update. Decrease toleratable bound for exponent of exp() to 500.
|
39
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.
|
42
|
+
2.3.3: fix error in calculation of migration rates.
|
40
43
|
'''
|
@@ -491,19 +491,19 @@ def UV_pi(mod, ax_U = None, ax_V = None, U_color = 'violet', V_color = 'yellowgr
|
|
491
491
|
|
492
492
|
|
493
493
|
|
494
|
-
def video_fig(mod, ax_list = None,
|
494
|
+
def video_fig(mod, ax_list = None, num_grid = 100, U_color = 'Purples', V_color = 'Greens'):
|
495
495
|
'''
|
496
496
|
Plot distribution dynamics over time, of U, V population and payoff.
|
497
497
|
|
498
498
|
mod: simulation.model object
|
499
499
|
ax_list: a 2*2 list of ax, or None (a new 2*2 ax_list will be created)
|
500
|
-
|
500
|
+
num_grid: how many grid for the time axis
|
501
501
|
U_color & V_color: matplotlib color map, color for U, V population and payoff.
|
502
502
|
'''
|
503
503
|
|
504
|
-
if
|
505
|
-
raise ValueError('
|
506
|
-
idx_step = int(mod.max_record /
|
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
507
|
ave_U = []
|
508
508
|
ave_V = []
|
509
509
|
ave_Upi = []
|
@@ -525,7 +525,7 @@ def video_fig(mod, ax_list = None, num_itv = 100, U_color = 'Purples', V_color =
|
|
525
525
|
ax_list[i, j].spines['right'].set_visible(False)
|
526
526
|
ax_list[i, j].set_xlabel('Patches')
|
527
527
|
ax_list[i, j].set_ylabel('Time')
|
528
|
-
ax_list[i, j].set_xlim([0, mod.M
|
528
|
+
ax_list[i, j].set_xlim([0, mod.M])
|
529
529
|
ax_list[i, j].set_ylim([0, mod.maxtime])
|
530
530
|
|
531
531
|
|
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
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|