piegy 2.3.6__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.6 → piegy-2.3.8}/MANIFEST.in +1 -0
- {piegy-2.3.6/src/piegy.egg-info → piegy-2.3.8}/PKG-INFO +1 -1
- {piegy-2.3.6 → piegy-2.3.8}/pyproject.toml +1 -1
- piegy-2.3.8/src/piegy/C_core/patch.c +53 -0
- {piegy-2.3.6 → piegy-2.3.8}/src/piegy/C_core/patch.h +9 -6
- {piegy-2.3.6 → piegy-2.3.8}/src/piegy/C_core/sim_funcs.c +111 -106
- {piegy-2.3.6 → piegy-2.3.8}/src/piegy/C_core/sim_funcs.h +37 -43
- {piegy-2.3.6 → piegy-2.3.8}/src/piegy/__init__.py +2 -2
- {piegy-2.3.6 → piegy-2.3.8}/src/piegy/__version__.py +3 -1
- {piegy-2.3.6 → piegy-2.3.8}/src/piegy/data_tools.py +33 -45
- {piegy-2.3.6 → piegy-2.3.8}/src/piegy/figures.py +3 -3
- {piegy-2.3.6 → piegy-2.3.8}/src/piegy/simulation.py +7 -7
- {piegy-2.3.6 → piegy-2.3.8}/src/piegy/test_var.py +21 -15
- {piegy-2.3.6 → piegy-2.3.8}/src/piegy/tools/figure_tools.py +1 -1
- {piegy-2.3.6 → piegy-2.3.8}/src/piegy/tools/find_C.py +3 -4
- {piegy-2.3.6 → piegy-2.3.8}/src/piegy/videos.py +14 -11
- {piegy-2.3.6 → piegy-2.3.8/src/piegy.egg-info}/PKG-INFO +1 -1
- {piegy-2.3.6 → piegy-2.3.8}/src/piegy.egg-info/SOURCES.txt +0 -1
- piegy-2.3.6/src/piegy/C_core/patch.c +0 -43
- piegy-2.3.6/src/piegy/C_core/runner.c +0 -61
- {piegy-2.3.6 → piegy-2.3.8}/LICENSE.txt +0 -0
- {piegy-2.3.6 → piegy-2.3.8}/README.md +0 -0
- {piegy-2.3.6 → piegy-2.3.8}/setup.cfg +0 -0
- {piegy-2.3.6 → piegy-2.3.8}/setup.py +0 -0
- {piegy-2.3.6 → piegy-2.3.8}/src/piegy/C_core/Makefile +0 -0
- {piegy-2.3.6 → piegy-2.3.8}/src/piegy/C_core/model.c +0 -0
- {piegy-2.3.6 → piegy-2.3.8}/src/piegy/C_core/model.h +0 -0
- {piegy-2.3.6 → piegy-2.3.8}/src/piegy/analysis.py +0 -0
- {piegy-2.3.6 → piegy-2.3.8}/src/piegy/build_info.py +0 -0
- {piegy-2.3.6 → piegy-2.3.8}/src/piegy/simulation_py.py +0 -0
- {piegy-2.3.6 → piegy-2.3.8}/src/piegy/tools/__init__.py +0 -0
- {piegy-2.3.6 → piegy-2.3.8}/src/piegy/tools/file_tools.py +0 -0
- {piegy-2.3.6 → piegy-2.3.8}/src/piegy.egg-info/dependency_links.txt +0 -0
- {piegy-2.3.6 → piegy-2.3.8}/src/piegy.egg-info/requires.txt +0 -0
- {piegy-2.3.6 → piegy-2.3.8}/src/piegy.egg-info/top_level.txt +0 -0
@@ -0,0 +1,53 @@
|
|
1
|
+
/**
|
2
|
+
* This .c includes the patch struct and "member functions"
|
3
|
+
* that correponds to patch class in piegy.model module
|
4
|
+
*/
|
5
|
+
|
6
|
+
#include "patch.h"
|
7
|
+
|
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
|
+
if (p == NULL) return;
|
10
|
+
p->row = row;
|
11
|
+
p->col = col;
|
12
|
+
|
13
|
+
p->U = U;
|
14
|
+
p->V = V;
|
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
|
+
}
|
23
|
+
|
24
|
+
for (size_t i = 0; i < 4; i++) {
|
25
|
+
p->U_weight[i] = 0;
|
26
|
+
p->V_weight[i] = 0;
|
27
|
+
p->pi_death_rates[i] = 0;
|
28
|
+
}
|
29
|
+
for (size_t i = 0; i < 8; i++) {
|
30
|
+
p->mig_rates[i] = 0;
|
31
|
+
}
|
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;
|
36
|
+
}
|
37
|
+
|
38
|
+
|
39
|
+
void set_nb(patch_t* world, size_t* nb_start, size_t ij, size_t NM) {
|
40
|
+
// nb_start is the where patch ij's neighbor indices start
|
41
|
+
size_t num_nb = 0;
|
42
|
+
for (size_t k = 0; k < 4; k++) {
|
43
|
+
if (nb_start[k] != NM) {
|
44
|
+
// neighbor is valid
|
45
|
+
world[ij].nb[k] = &world[nb_start[k]];
|
46
|
+
num_nb += 1;
|
47
|
+
} else {
|
48
|
+
world[ij].nb[k] = NULL;
|
49
|
+
}
|
50
|
+
}
|
51
|
+
world[ij].P[0] *= (0.25 * num_nb);
|
52
|
+
world[ij].P[1] *= (0.25 * num_nb);
|
53
|
+
}
|
@@ -10,18 +10,21 @@
|
|
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 {
|
17
|
-
size_t
|
18
|
-
size_t
|
17
|
+
size_t row;
|
18
|
+
size_t col;
|
19
19
|
|
20
|
-
uint32_t U;
|
20
|
+
uint32_t U; // store as double directly to avoid runtime conversion (to double)
|
21
21
|
uint32_t V;
|
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
|
38
|
-
void set_nb(patch_t* world, size_t* nb_start, size_t ij, size_t NM);
|
40
|
+
void patch_init(patch_t* p, uint32_t U, uint32_t V, size_t row, size_t col, double* X_start, double* P_start);
|
41
|
+
void set_nb(patch_t* world, size_t* nb_start, size_t ij, size_t NM) ;
|
39
42
|
|
40
43
|
#endif // PATCH_H
|
41
44
|
|
@@ -76,68 +76,60 @@ static double single_init(const model_t* restrict mod, patch_t* restrict world,
|
|
76
76
|
size_t M = mod->M;
|
77
77
|
size_t NM = N * M;
|
78
78
|
size_t max_record = mod->max_record;
|
79
|
-
size_t
|
79
|
+
size_t ij_out = 0; // used to track index i * M + j in double for loops, "out" means not the "looper" in for loop
|
80
80
|
|
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[
|
85
|
-
|
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
|
+
ij_out++;
|
86
86
|
}
|
87
87
|
}
|
88
88
|
|
89
89
|
// init nb_indices
|
90
|
-
|
90
|
+
ij_out = 0;
|
91
91
|
if (mod->boundary) {
|
92
92
|
for (size_t i = 0; i < N; i++) {
|
93
93
|
for (size_t j = 0; j < M; j++) {
|
94
|
-
find_nb_zero_flux(&nb_indices[
|
95
|
-
|
94
|
+
find_nb_zero_flux(&nb_indices[ij_out * 4], i, j, N, M, NM);
|
95
|
+
ij_out++;
|
96
96
|
}
|
97
97
|
}
|
98
98
|
} else {
|
99
99
|
for (size_t i = 0; i < N; i++) {
|
100
100
|
for (size_t j = 0; j < M; j++) {
|
101
|
-
find_nb_periodical(&nb_indices[
|
102
|
-
|
101
|
+
find_nb_periodical(&nb_indices[ij_out * 4], i, j, N, M, NM);
|
102
|
+
ij_out++;
|
103
103
|
}
|
104
104
|
}
|
105
105
|
}
|
106
106
|
|
107
107
|
|
108
108
|
// set nb pointers for patches
|
109
|
-
ij = 0;
|
110
|
-
|
111
|
-
for (size_t j = 0; j < M; j++) {
|
112
|
-
set_nb(world, &nb_indices[ij * 4], ij, NM);
|
113
|
-
ij++;
|
114
|
-
}
|
109
|
+
for (size_t ij = 0; ij < NM; ij++) {
|
110
|
+
set_nb(world, &nb_indices[ij * 4], ij, NM);
|
115
111
|
}
|
116
112
|
|
117
113
|
//////// Begin Running ////////
|
118
114
|
|
119
115
|
// init payoff & natural death rates
|
120
|
-
ij = 0;
|
121
|
-
|
122
|
-
for (size_t j = 0; j < M; j++) {
|
123
|
-
update_pi_k(&world[ij], &(mod->X[ij * 4]), &(mod->P[ij * 6]));
|
124
|
-
ij++;
|
125
|
-
}
|
116
|
+
for (size_t ij = 0; ij < N; ij++) {
|
117
|
+
update_pi_k(&world[ij]);
|
126
118
|
}
|
127
119
|
|
128
120
|
// init migration rates & store patch rates
|
129
|
-
|
121
|
+
ij_out = 0;
|
130
122
|
for (size_t i = 0; i < N; i++) {
|
131
123
|
for (size_t j = 0; j < M; j++) {
|
132
|
-
uint8_t mig_result = init_mig(&world[
|
124
|
+
uint8_t mig_result = init_mig(&world[ij_out]); // init mig rates for all 4 directions
|
133
125
|
if (mig_result == SIM_OVERFLOW) {
|
134
126
|
return -1 * SIM_OVERFLOW;
|
135
127
|
}
|
136
|
-
double ij_rates = world[
|
137
|
-
patch_rates[
|
128
|
+
double ij_rates = world[ij_out].sum_pi_death_rates + world[ij_out].sum_mig_rates;
|
129
|
+
patch_rates[ij_out] = ij_rates;
|
138
130
|
sum_rates_by_row[i] += ij_rates;
|
139
131
|
*sum_rates_p = *sum_rates_p + ij_rates; // can't do *sum_rates_p += ij_rates
|
140
|
-
|
132
|
+
ij_out++;
|
141
133
|
}
|
142
134
|
}
|
143
135
|
|
@@ -172,22 +164,20 @@ static double single_init(const model_t* restrict mod, patch_t* restrict world,
|
|
172
164
|
// maxtime too small
|
173
165
|
return -1 * SMALL_MAXTIME;
|
174
166
|
}
|
175
|
-
|
167
|
+
|
176
168
|
// store data
|
177
169
|
if (time > mod->record_itv) {
|
178
170
|
size_t recod_idx = (size_t) (time / mod->record_itv);
|
179
|
-
|
180
|
-
for (size_t
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
}
|
188
|
-
ij++;
|
171
|
+
|
172
|
+
for (size_t ij = 0; ij < NM; ij++) {
|
173
|
+
size_t ij_max_record = ij * max_record;
|
174
|
+
for (size_t k = 0; k < recod_idx; k++) {
|
175
|
+
mod->U1d[ij_max_record + k] += world[ij].U;
|
176
|
+
mod->V1d[ij_max_record + k] += world[ij].V;
|
177
|
+
mod->Upi_1d[ij_max_record + k] += world[ij].U_pi;
|
178
|
+
mod->Vpi_1d[ij_max_record + k] += world[ij].V_pi;
|
189
179
|
}
|
190
|
-
}
|
180
|
+
}
|
191
181
|
}
|
192
182
|
|
193
183
|
return time;
|
@@ -204,29 +194,20 @@ static uint8_t single_test(model_t* restrict mod, char* message) {
|
|
204
194
|
size_t max_record = mod->max_record;
|
205
195
|
double record_itv = mod->record_itv;
|
206
196
|
bool boundary = mod->boundary;
|
207
|
-
|
208
|
-
|
209
|
-
double
|
210
|
-
double
|
211
|
-
if (mod->print_pct != -1) {
|
212
|
-
one_progress = maxtime * mod->print_pct / 100.0;
|
213
|
-
fprintf(stdout, "\r ");
|
214
|
-
fprintf(stdout, "\r%s: 0 %%", message);
|
215
|
-
fflush(stdout);
|
216
|
-
} else {
|
217
|
-
one_progress = 2.0 * maxtime;
|
218
|
-
}
|
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;
|
219
201
|
|
220
202
|
// update sum of rates every 1e5 rounds
|
221
203
|
// many rates are updated each time, rather than re-calculated.
|
222
204
|
// So need to re-calculate from scratch every some rounds to reduce numerical errors
|
223
205
|
size_t curr_update_sum_round = 0; // current round
|
224
|
-
size_t
|
206
|
+
size_t update_sum_freq = UPDATE_SUM_ROUNDS_SM; // recalculate sum every this many rounds
|
225
207
|
|
226
|
-
//
|
208
|
+
// core containers
|
227
209
|
patch_t* world = (patch_t*) calloc(NM, sizeof(patch_t));
|
228
210
|
size_t* nb_indices = (size_t*) calloc(NM * 4, sizeof(size_t));
|
229
|
-
|
230
211
|
double* patch_rates = (double*) calloc(NM, sizeof(double));
|
231
212
|
double* sum_rates_by_row = (double*) calloc(N, sizeof(double));
|
232
213
|
double sum_rates = 0;
|
@@ -234,6 +215,17 @@ static uint8_t single_test(model_t* restrict mod, char* message) {
|
|
234
215
|
signal_t signal;
|
235
216
|
patch_picked_t picked;
|
236
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
|
237
229
|
double time = single_init(mod, world, nb_indices, patch_rates, sum_rates_by_row, &sum_rates, &signal, &picked);
|
238
230
|
if (time == -1 * SMALL_MAXTIME) {
|
239
231
|
// time too small
|
@@ -251,32 +243,36 @@ static uint8_t single_test(model_t* restrict mod, char* message) {
|
|
251
243
|
fflush(stdout);
|
252
244
|
single_test_free(&world, &nb_indices, &patch_rates, &sum_rates_by_row);
|
253
245
|
return ACCURACY_ERROR;
|
254
|
-
|
255
|
-
size_t record_index = time / mod->record_itv;
|
246
|
+
}
|
247
|
+
size_t record_index = (size_t) (time / mod->record_itv);
|
256
248
|
double record_time = time - record_index * record_itv;
|
257
249
|
|
250
|
+
//////// while loop ////////
|
258
251
|
|
259
252
|
while (time < maxtime) {
|
260
253
|
|
261
|
-
//
|
262
|
-
if (time > current_progress) {
|
263
|
-
uint8_t curr_prog = (uint8_t)(time * 100 / maxtime);
|
264
|
-
if (curr_prog < 10) {
|
265
|
-
fprintf(stdout, "\r%s: %d %%", message, (int)(time * 100 / maxtime));
|
266
|
-
} else {
|
267
|
-
fprintf(stdout, "\r%s: %d%%", message, (int)(time * 100 / maxtime));
|
268
|
-
}
|
269
|
-
fflush(stdout);
|
270
|
-
//fflush(stdout); // Make sure it prints immediately
|
271
|
-
current_progress += one_progress;
|
272
|
-
}
|
273
|
-
|
274
|
-
// update sums
|
254
|
+
// update sums and print progress
|
275
255
|
curr_update_sum_round++;
|
276
|
-
if (curr_update_sum_round >
|
256
|
+
if (curr_update_sum_round > update_sum_freq) {
|
277
257
|
curr_update_sum_round = 0;
|
278
258
|
|
279
|
-
|
259
|
+
// Print progress
|
260
|
+
if (time > current_progress) {
|
261
|
+
uint8_t curr_prog = (uint8_t)(time * 100 / maxtime);
|
262
|
+
if (curr_prog < 10) {
|
263
|
+
fprintf(stdout, "\r%s: %d %%", message, (int)(time * 100 / maxtime));
|
264
|
+
} else {
|
265
|
+
fprintf(stdout, "\r%s: %d%%", message, (int)(time * 100 / maxtime));
|
266
|
+
}
|
267
|
+
fflush(stdout);
|
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);
|
271
|
+
current_progress += one_progress;
|
272
|
+
}
|
273
|
+
|
274
|
+
// update sum
|
275
|
+
update_sum_freq = UPDATE_SUM_ROUNDS_LG; // assume can make it larger
|
280
276
|
for (size_t ij = 0; ij < NM; ij++) {
|
281
277
|
double sum_U_weight = 0;
|
282
278
|
double sum_V_weight = 0;
|
@@ -285,19 +281,19 @@ static uint8_t single_test(model_t* restrict mod, char* message) {
|
|
285
281
|
sum_V_weight += world[ij].V_weight[k];
|
286
282
|
}
|
287
283
|
if (sum_U_weight > ACCURATE_BOUND || sum_V_weight > ACCURATE_BOUND) {
|
288
|
-
|
284
|
+
update_sum_freq = UPDATE_SUM_ROUNDS_SM; // values too large, put back the small update frequency
|
289
285
|
}
|
290
286
|
world[ij].sum_U_weight = sum_U_weight;
|
291
287
|
world[ij].sum_V_weight = sum_V_weight;
|
292
288
|
// patch_rates are updated every time a patch is changed
|
293
289
|
}
|
294
|
-
size_t
|
290
|
+
size_t ij_out = 0;
|
295
291
|
sum_rates = 0;
|
296
292
|
for (size_t i = 0; i < N; i++) {
|
297
293
|
double sum_rates_by_row_i = 0;
|
298
294
|
for (size_t j = 0; j < M; j++) {
|
299
|
-
sum_rates_by_row_i += patch_rates[
|
300
|
-
|
295
|
+
sum_rates_by_row_i += patch_rates[ij_out];
|
296
|
+
ij_out++;
|
301
297
|
}
|
302
298
|
sum_rates_by_row[i] = sum_rates_by_row_i;
|
303
299
|
sum_rates += sum_rates_by_row_i;
|
@@ -318,8 +314,8 @@ static uint8_t single_test(model_t* restrict mod, char* message) {
|
|
318
314
|
sum_rates_by_row[si1] -= patch_rates[sij1];
|
319
315
|
sum_rates -= patch_rates[sij1];
|
320
316
|
|
321
|
-
update_pi_k(&world[sij1]
|
322
|
-
update_mig_just_rate(&world[sij1]
|
317
|
+
update_pi_k(&world[sij1]);
|
318
|
+
update_mig_just_rate(&world[sij1]);
|
323
319
|
|
324
320
|
patch_rates[sij1] = world[sij1].sum_pi_death_rates + world[sij1].sum_mig_rates;
|
325
321
|
sum_rates_by_row[si1] += patch_rates[sij1];
|
@@ -331,11 +327,11 @@ static uint8_t single_test(model_t* restrict mod, char* message) {
|
|
331
327
|
sum_rates -= patch_rates[sij1];
|
332
328
|
sum_rates -= patch_rates[sij2];
|
333
329
|
|
334
|
-
update_pi_k(&world[sij1]
|
335
|
-
update_pi_k(&world[sij2]
|
330
|
+
update_pi_k(&world[sij1]); // update both patches' payoffs first
|
331
|
+
update_pi_k(&world[sij2]);
|
336
332
|
|
337
|
-
if (update_mig_weight_rate(&world[sij1],
|
338
|
-
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) {
|
339
335
|
|
340
336
|
fprintf(stdout, "\nError: overflow at t = %f\n", time);
|
341
337
|
fflush(stdout);
|
@@ -357,7 +353,7 @@ static uint8_t single_test(model_t* restrict mod, char* message) {
|
|
357
353
|
size_t nb_idx = nb_indices[sij1 * 4 + k];
|
358
354
|
if (nb_idx == NM) { continue; } // invalid neighbor
|
359
355
|
// all neighbors, as long as exists, need to change
|
360
|
-
if (update_mig_weight_rate(&world[nb_idx],
|
356
|
+
if (update_mig_weight_rate(&world[nb_idx], k ^ 1) == SIM_OVERFLOW) {
|
361
357
|
fprintf(stdout, "\nError: overflow at t = %f\n", time);
|
362
358
|
fflush(stdout);
|
363
359
|
single_test_free(&world, &nb_indices, &patch_rates, &sum_rates_by_row);
|
@@ -372,7 +368,7 @@ static uint8_t single_test(model_t* restrict mod, char* message) {
|
|
372
368
|
if (nb_idx == NM) { continue; }
|
373
369
|
if (k != rela_loc) {
|
374
370
|
// nb_idx isn't the second last-changed patch
|
375
|
-
if (update_mig_weight_rate(&world[nb_idx],
|
371
|
+
if (update_mig_weight_rate(&world[nb_idx], k ^ 1) == SIM_OVERFLOW) {
|
376
372
|
fprintf(stdout, "\nError: overflow at t = %f\n", time);
|
377
373
|
fflush(stdout);
|
378
374
|
single_test_free(&world, &nb_indices, &patch_rates, &sum_rates_by_row);
|
@@ -386,7 +382,7 @@ static uint8_t single_test(model_t* restrict mod, char* message) {
|
|
386
382
|
if (nb_idx == NM) { continue; }
|
387
383
|
if (k != (rela_loc ^ 1)) {
|
388
384
|
// nb_idx isn't the first last-changed patch
|
389
|
-
if (update_mig_weight_rate(&world[nb_idx],
|
385
|
+
if (update_mig_weight_rate(&world[nb_idx], k ^ 1) == SIM_OVERFLOW) {
|
390
386
|
fprintf(stdout, "\nError: overflow at t = %f\n", time);
|
391
387
|
fflush(stdout);
|
392
388
|
single_test_free(&world, &nb_indices, &patch_rates, &sum_rates_by_row);
|
@@ -396,7 +392,6 @@ static uint8_t single_test(model_t* restrict mod, char* message) {
|
|
396
392
|
}
|
397
393
|
}
|
398
394
|
|
399
|
-
|
400
395
|
// pick a random event
|
401
396
|
double expected_sum = random01() * sum_rates;
|
402
397
|
find_patch(&picked, expected_sum, patch_rates, sum_rates_by_row, sum_rates, N, M);
|
@@ -416,7 +411,7 @@ static uint8_t single_test(model_t* restrict mod, char* message) {
|
|
416
411
|
make_signal_periodical(N, M, picked.i, picked.j, e0, &signal);
|
417
412
|
}
|
418
413
|
signal.ij1 = signal.i1 * M + signal.j1;
|
419
|
-
signal.ij2 = signal.i2 * M + signal.j2;
|
414
|
+
signal.ij2 = signal.i2 * M + signal.j2;
|
420
415
|
|
421
416
|
// let the event happenn
|
422
417
|
change_popu(&world[signal.ij1], signal.e1);
|
@@ -437,11 +432,12 @@ static uint8_t single_test(model_t* restrict mod, char* message) {
|
|
437
432
|
size_t upper = record_index + multi_records;
|
438
433
|
|
439
434
|
for (size_t ij = 0; ij < NM; ij++) {
|
435
|
+
size_t ij_max_record = ij * max_record;
|
440
436
|
for (size_t k = record_index; k < upper; k++) {
|
441
|
-
|
442
|
-
|
443
|
-
|
444
|
-
|
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;
|
445
441
|
}
|
446
442
|
}
|
447
443
|
record_index += multi_records;
|
@@ -450,11 +446,12 @@ static uint8_t single_test(model_t* restrict mod, char* message) {
|
|
450
446
|
} else {
|
451
447
|
// if already exceeds maxtime
|
452
448
|
for (size_t ij = 0; ij < NM; ij++) {
|
449
|
+
size_t ij_max_record = ij * max_record;
|
453
450
|
for (size_t k = record_index; k < max_record; k++) {
|
454
|
-
|
455
|
-
|
456
|
-
|
457
|
-
|
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;
|
458
455
|
}
|
459
456
|
}
|
460
457
|
}
|
@@ -514,27 +511,33 @@ uint8_t run(model_t* restrict mod, char* message, size_t msg_len) {
|
|
514
511
|
|
515
512
|
if (mod->print_pct == 0) {
|
516
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
|
517
519
|
}
|
518
520
|
|
519
|
-
size_t
|
521
|
+
size_t round = 0;
|
520
522
|
|
521
|
-
while (
|
523
|
+
while (round < mod->sim_time) {
|
522
524
|
char curr_msg[100 + msg_len]; // message for current round
|
523
525
|
strcpy(curr_msg, message);
|
524
526
|
strcat(curr_msg, "round ");
|
525
|
-
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);
|
526
528
|
|
527
|
-
|
528
|
-
|
529
|
-
|
530
|
-
|
531
|
-
|
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
|
+
}
|
532
535
|
|
533
536
|
uint8_t result = single_test(mod, curr_msg);
|
534
537
|
|
535
538
|
switch (result) {
|
536
539
|
case SUCCESS:
|
537
|
-
|
540
|
+
round++;
|
538
541
|
break;
|
539
542
|
case SMALL_MAXTIME:
|
540
543
|
// error message is handled by single_test
|
@@ -550,10 +553,12 @@ uint8_t run(model_t* restrict mod, char* message, size_t msg_len) {
|
|
550
553
|
|
551
554
|
calculate_ave(mod);
|
552
555
|
|
553
|
-
|
554
|
-
|
555
|
-
|
556
|
-
|
556
|
+
if ((mod->print_pct != -1) || (print_round != 0)) {
|
557
|
+
// print runtime if the original mod->print_pct != -1
|
558
|
+
double stop = clock();
|
559
|
+
fprintf(stdout, "\r%sruntime: %.3fs \n", message, (double)(stop - start) / CLOCKS_PER_SEC);
|
560
|
+
fflush(stdout);
|
561
|
+
}
|
557
562
|
return SUCCESS;
|
558
563
|
}
|
559
564
|
|