piegy 2.3.6__tar.gz → 2.3.7__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.7}/MANIFEST.in +1 -0
- {piegy-2.3.6/src/piegy.egg-info → piegy-2.3.7}/PKG-INFO +1 -1
- {piegy-2.3.6 → piegy-2.3.7}/pyproject.toml +1 -1
- {piegy-2.3.6 → piegy-2.3.7}/src/piegy/C_core/patch.c +8 -4
- {piegy-2.3.6 → piegy-2.3.7}/src/piegy/C_core/patch.h +5 -5
- {piegy-2.3.6 → piegy-2.3.7}/src/piegy/C_core/sim_funcs.c +80 -79
- {piegy-2.3.6 → piegy-2.3.7}/src/piegy/C_core/sim_funcs.h +18 -16
- {piegy-2.3.6 → piegy-2.3.7}/src/piegy/__version__.py +2 -1
- {piegy-2.3.6 → piegy-2.3.7}/src/piegy/data_tools.py +29 -41
- {piegy-2.3.6 → piegy-2.3.7}/src/piegy/figures.py +3 -3
- {piegy-2.3.6 → piegy-2.3.7}/src/piegy/simulation.py +4 -4
- {piegy-2.3.6 → piegy-2.3.7}/src/piegy/test_var.py +15 -9
- {piegy-2.3.6 → piegy-2.3.7}/src/piegy/tools/figure_tools.py +1 -1
- {piegy-2.3.6 → piegy-2.3.7}/src/piegy/tools/find_C.py +3 -4
- {piegy-2.3.6 → piegy-2.3.7}/src/piegy/videos.py +14 -11
- {piegy-2.3.6 → piegy-2.3.7/src/piegy.egg-info}/PKG-INFO +1 -1
- {piegy-2.3.6 → piegy-2.3.7}/src/piegy.egg-info/SOURCES.txt +0 -1
- piegy-2.3.6/src/piegy/C_core/runner.c +0 -61
- {piegy-2.3.6 → piegy-2.3.7}/LICENSE.txt +0 -0
- {piegy-2.3.6 → piegy-2.3.7}/README.md +0 -0
- {piegy-2.3.6 → piegy-2.3.7}/setup.cfg +0 -0
- {piegy-2.3.6 → piegy-2.3.7}/setup.py +0 -0
- {piegy-2.3.6 → piegy-2.3.7}/src/piegy/C_core/Makefile +0 -0
- {piegy-2.3.6 → piegy-2.3.7}/src/piegy/C_core/model.c +0 -0
- {piegy-2.3.6 → piegy-2.3.7}/src/piegy/C_core/model.h +0 -0
- {piegy-2.3.6 → piegy-2.3.7}/src/piegy/__init__.py +0 -0
- {piegy-2.3.6 → piegy-2.3.7}/src/piegy/analysis.py +0 -0
- {piegy-2.3.6 → piegy-2.3.7}/src/piegy/build_info.py +0 -0
- {piegy-2.3.6 → piegy-2.3.7}/src/piegy/simulation_py.py +0 -0
- {piegy-2.3.6 → piegy-2.3.7}/src/piegy/tools/__init__.py +0 -0
- {piegy-2.3.6 → piegy-2.3.7}/src/piegy/tools/file_tools.py +0 -0
- {piegy-2.3.6 → piegy-2.3.7}/src/piegy.egg-info/dependency_links.txt +0 -0
- {piegy-2.3.6 → piegy-2.3.7}/src/piegy.egg-info/requires.txt +0 -0
- {piegy-2.3.6 → piegy-2.3.7}/src/piegy.egg-info/top_level.txt +0 -0
@@ -5,10 +5,10 @@
|
|
5
5
|
|
6
6
|
#include "patch.h"
|
7
7
|
|
8
|
-
void patch_init(patch_t* p, uint32_t U, uint32_t V, size_t
|
8
|
+
void patch_init(patch_t* p, uint32_t U, uint32_t V, size_t row, size_t col) {
|
9
9
|
if (p == NULL) return;
|
10
|
-
p->
|
11
|
-
p->
|
10
|
+
p->row = row;
|
11
|
+
p->col = col;
|
12
12
|
|
13
13
|
p->U = U;
|
14
14
|
p->V = V;
|
@@ -30,14 +30,18 @@ void patch_init(patch_t* p, uint32_t U, uint32_t V, size_t i, size_t j) {
|
|
30
30
|
}
|
31
31
|
|
32
32
|
|
33
|
-
void set_nb(patch_t* world, size_t* nb_start, size_t ij, size_t NM) {
|
33
|
+
void set_nb(patch_t* world, double* P_start, size_t* nb_start, size_t ij, size_t NM) {
|
34
34
|
// nb_start is the where patch ij's neighbor indices start
|
35
|
+
size_t num_nb = 0;
|
35
36
|
for (size_t k = 0; k < 4; k++) {
|
36
37
|
if (nb_start[k] != NM) {
|
37
38
|
// neighbor is valid
|
38
39
|
world[ij].nb[k] = &world[nb_start[k]];
|
40
|
+
num_nb += 1;
|
39
41
|
} else {
|
40
42
|
world[ij].nb[k] = NULL;
|
41
43
|
}
|
42
44
|
}
|
45
|
+
P_start[0] *= (0.25 * num_nb); // scale total migration rates by how many neighbors the patch has
|
46
|
+
P_start[1] *= (0.25 * num_nb);
|
43
47
|
}
|
@@ -14,10 +14,10 @@
|
|
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;
|
@@ -34,8 +34,8 @@ typedef struct patch_t {
|
|
34
34
|
} patch_t;
|
35
35
|
|
36
36
|
// 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);
|
37
|
+
void patch_init(patch_t* p, uint32_t U, uint32_t V, size_t row, size_t col);
|
38
|
+
void set_nb(patch_t* world, double* P_start, size_t* nb_start, size_t ij, size_t NM) ;
|
39
39
|
|
40
40
|
#endif // PATCH_H
|
41
41
|
|
@@ -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);
|
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, &(mod->P[ij * 6]), &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], &(mod->X[ij * 4]), &(mod->P[ij * 6]));
|
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], &(mod->P[ij_out * 6])); // 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
|
|
@@ -176,18 +168,16 @@ static double single_init(const model_t* restrict mod, patch_t* restrict world,
|
|
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,10 +194,15 @@ 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;
|
197
|
+
double* X = mod->X;
|
198
|
+
double* P = mod->P;
|
199
|
+
double* U1d = mod->U1d;
|
200
|
+
double* V1d = mod->V1d;
|
201
|
+
double* Upi_1d = mod->Upi_1d;
|
202
|
+
double* Vpi_1d = mod->Vpi_1d;
|
207
203
|
|
208
204
|
// print progress
|
209
205
|
double one_progress = 0.0;
|
210
|
-
double current_progress = one_progress;
|
211
206
|
if (mod->print_pct != -1) {
|
212
207
|
one_progress = maxtime * mod->print_pct / 100.0;
|
213
208
|
fprintf(stdout, "\r ");
|
@@ -216,12 +211,13 @@ static uint8_t single_test(model_t* restrict mod, char* message) {
|
|
216
211
|
} else {
|
217
212
|
one_progress = 2.0 * maxtime;
|
218
213
|
}
|
214
|
+
double current_progress = one_progress;
|
219
215
|
|
220
216
|
// update sum of rates every 1e5 rounds
|
221
217
|
// many rates are updated each time, rather than re-calculated.
|
222
218
|
// So need to re-calculate from scratch every some rounds to reduce numerical errors
|
223
219
|
size_t curr_update_sum_round = 0; // current round
|
224
|
-
size_t
|
220
|
+
size_t update_sum_freq = UPDATE_SUM_ROUNDS_SM; // recalculate sum every this many rounds
|
225
221
|
|
226
222
|
// Initialize simulation
|
227
223
|
patch_t* world = (patch_t*) calloc(NM, sizeof(patch_t));
|
@@ -251,32 +247,33 @@ static uint8_t single_test(model_t* restrict mod, char* message) {
|
|
251
247
|
fflush(stdout);
|
252
248
|
single_test_free(&world, &nb_indices, &patch_rates, &sum_rates_by_row);
|
253
249
|
return ACCURACY_ERROR;
|
254
|
-
|
255
|
-
size_t record_index = time / mod->record_itv;
|
250
|
+
}
|
251
|
+
size_t record_index = (size_t) (time / mod->record_itv);
|
256
252
|
double record_time = time - record_index * record_itv;
|
257
253
|
|
258
254
|
|
259
255
|
while (time < maxtime) {
|
260
|
-
|
261
|
-
// Print progress
|
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
256
|
|
274
|
-
// update sums
|
257
|
+
// update sums and print progress
|
275
258
|
curr_update_sum_round++;
|
276
|
-
if (curr_update_sum_round >
|
259
|
+
if (curr_update_sum_round > update_sum_freq) {
|
277
260
|
curr_update_sum_round = 0;
|
278
261
|
|
279
|
-
|
262
|
+
// Print progress
|
263
|
+
if (time > current_progress) {
|
264
|
+
uint8_t curr_prog = (uint8_t)(time * 100 / maxtime);
|
265
|
+
if (curr_prog < 10) {
|
266
|
+
fprintf(stdout, "\r%s: %d %%", message, (int)(time * 100 / maxtime));
|
267
|
+
} else {
|
268
|
+
fprintf(stdout, "\r%s: %d%%", message, (int)(time * 100 / maxtime));
|
269
|
+
}
|
270
|
+
fflush(stdout);
|
271
|
+
//fflush(stdout); // Make sure it prints immediately
|
272
|
+
current_progress += one_progress;
|
273
|
+
}
|
274
|
+
|
275
|
+
// update sum
|
276
|
+
update_sum_freq = UPDATE_SUM_ROUNDS_LG; // assume can make it larger
|
280
277
|
for (size_t ij = 0; ij < NM; ij++) {
|
281
278
|
double sum_U_weight = 0;
|
282
279
|
double sum_V_weight = 0;
|
@@ -285,19 +282,19 @@ static uint8_t single_test(model_t* restrict mod, char* message) {
|
|
285
282
|
sum_V_weight += world[ij].V_weight[k];
|
286
283
|
}
|
287
284
|
if (sum_U_weight > ACCURATE_BOUND || sum_V_weight > ACCURATE_BOUND) {
|
288
|
-
|
285
|
+
update_sum_freq = UPDATE_SUM_ROUNDS_SM; // values too large, put back the small update frequency
|
289
286
|
}
|
290
287
|
world[ij].sum_U_weight = sum_U_weight;
|
291
288
|
world[ij].sum_V_weight = sum_V_weight;
|
292
289
|
// patch_rates are updated every time a patch is changed
|
293
290
|
}
|
294
|
-
size_t
|
291
|
+
size_t ij_out = 0;
|
295
292
|
sum_rates = 0;
|
296
293
|
for (size_t i = 0; i < N; i++) {
|
297
294
|
double sum_rates_by_row_i = 0;
|
298
295
|
for (size_t j = 0; j < M; j++) {
|
299
|
-
sum_rates_by_row_i += patch_rates[
|
300
|
-
|
296
|
+
sum_rates_by_row_i += patch_rates[ij_out];
|
297
|
+
ij_out++;
|
301
298
|
}
|
302
299
|
sum_rates_by_row[i] = sum_rates_by_row_i;
|
303
300
|
sum_rates += sum_rates_by_row_i;
|
@@ -318,8 +315,8 @@ static uint8_t single_test(model_t* restrict mod, char* message) {
|
|
318
315
|
sum_rates_by_row[si1] -= patch_rates[sij1];
|
319
316
|
sum_rates -= patch_rates[sij1];
|
320
317
|
|
321
|
-
update_pi_k(&world[sij1], &(
|
322
|
-
update_mig_just_rate(&world[sij1], &(
|
318
|
+
update_pi_k(&world[sij1], &(X[sij1 * 4]), &(P[sij1 * 6]));
|
319
|
+
update_mig_just_rate(&world[sij1], &(P[sij1 * 6]));
|
323
320
|
|
324
321
|
patch_rates[sij1] = world[sij1].sum_pi_death_rates + world[sij1].sum_mig_rates;
|
325
322
|
sum_rates_by_row[si1] += patch_rates[sij1];
|
@@ -331,11 +328,11 @@ static uint8_t single_test(model_t* restrict mod, char* message) {
|
|
331
328
|
sum_rates -= patch_rates[sij1];
|
332
329
|
sum_rates -= patch_rates[sij2];
|
333
330
|
|
334
|
-
update_pi_k(&world[sij1], &(
|
335
|
-
update_pi_k(&world[sij2], &(
|
331
|
+
update_pi_k(&world[sij1], &(X[sij1 * 4]), &(P[sij1 * 6])); // update both patches' payoffs first
|
332
|
+
update_pi_k(&world[sij2], &(X[sij2 * 4]), &(P[sij2 * 6]));
|
336
333
|
|
337
|
-
if (update_mig_weight_rate(&world[sij1], &(
|
338
|
-
update_mig_weight_rate(&world[sij2], &(
|
334
|
+
if (update_mig_weight_rate(&world[sij1], &(P[sij1 * 6]), rela_loc) == SIM_OVERFLOW ||
|
335
|
+
update_mig_weight_rate(&world[sij2], &(P[sij2 * 6]), rela_loc ^ 1) == SIM_OVERFLOW) {
|
339
336
|
|
340
337
|
fprintf(stdout, "\nError: overflow at t = %f\n", time);
|
341
338
|
fflush(stdout);
|
@@ -357,7 +354,7 @@ static uint8_t single_test(model_t* restrict mod, char* message) {
|
|
357
354
|
size_t nb_idx = nb_indices[sij1 * 4 + k];
|
358
355
|
if (nb_idx == NM) { continue; } // invalid neighbor
|
359
356
|
// all neighbors, as long as exists, need to change
|
360
|
-
if (update_mig_weight_rate(&world[nb_idx], &(
|
357
|
+
if (update_mig_weight_rate(&world[nb_idx], &(P[nb_idx * 6]), k ^ 1) == SIM_OVERFLOW) {
|
361
358
|
fprintf(stdout, "\nError: overflow at t = %f\n", time);
|
362
359
|
fflush(stdout);
|
363
360
|
single_test_free(&world, &nb_indices, &patch_rates, &sum_rates_by_row);
|
@@ -372,7 +369,7 @@ static uint8_t single_test(model_t* restrict mod, char* message) {
|
|
372
369
|
if (nb_idx == NM) { continue; }
|
373
370
|
if (k != rela_loc) {
|
374
371
|
// nb_idx isn't the second last-changed patch
|
375
|
-
if (update_mig_weight_rate(&world[nb_idx], &(
|
372
|
+
if (update_mig_weight_rate(&world[nb_idx], &(P[nb_idx * 6]), k ^ 1) == SIM_OVERFLOW) {
|
376
373
|
fprintf(stdout, "\nError: overflow at t = %f\n", time);
|
377
374
|
fflush(stdout);
|
378
375
|
single_test_free(&world, &nb_indices, &patch_rates, &sum_rates_by_row);
|
@@ -386,7 +383,7 @@ static uint8_t single_test(model_t* restrict mod, char* message) {
|
|
386
383
|
if (nb_idx == NM) { continue; }
|
387
384
|
if (k != (rela_loc ^ 1)) {
|
388
385
|
// nb_idx isn't the first last-changed patch
|
389
|
-
if (update_mig_weight_rate(&world[nb_idx], &(
|
386
|
+
if (update_mig_weight_rate(&world[nb_idx], &(P[nb_idx * 6]), k ^ 1) == SIM_OVERFLOW) {
|
390
387
|
fprintf(stdout, "\nError: overflow at t = %f\n", time);
|
391
388
|
fflush(stdout);
|
392
389
|
single_test_free(&world, &nb_indices, &patch_rates, &sum_rates_by_row);
|
@@ -437,11 +434,12 @@ static uint8_t single_test(model_t* restrict mod, char* message) {
|
|
437
434
|
size_t upper = record_index + multi_records;
|
438
435
|
|
439
436
|
for (size_t ij = 0; ij < NM; ij++) {
|
437
|
+
size_t ij_max_record = ij * max_record;
|
440
438
|
for (size_t k = record_index; k < upper; k++) {
|
441
|
-
|
442
|
-
|
443
|
-
|
444
|
-
|
439
|
+
U1d[ij_max_record + k] += world[ij].U;
|
440
|
+
V1d[ij_max_record + k] += world[ij].V;
|
441
|
+
Upi_1d[ij_max_record + k] += world[ij].U_pi;
|
442
|
+
Vpi_1d[ij_max_record + k] += world[ij].V_pi;
|
445
443
|
}
|
446
444
|
}
|
447
445
|
record_index += multi_records;
|
@@ -450,11 +448,12 @@ static uint8_t single_test(model_t* restrict mod, char* message) {
|
|
450
448
|
} else {
|
451
449
|
// if already exceeds maxtime
|
452
450
|
for (size_t ij = 0; ij < NM; ij++) {
|
451
|
+
size_t ij_max_record = ij * max_record;
|
453
452
|
for (size_t k = record_index; k < max_record; k++) {
|
454
|
-
|
455
|
-
|
456
|
-
|
457
|
-
|
453
|
+
U1d[ij_max_record + k] += world[ij].U;
|
454
|
+
V1d[ij_max_record + k] += world[ij].V;
|
455
|
+
Upi_1d[ij_max_record + k] += world[ij].U_pi;
|
456
|
+
Vpi_1d[ij_max_record + k] += world[ij].V_pi;
|
458
457
|
}
|
459
458
|
}
|
460
459
|
}
|
@@ -552,8 +551,10 @@ uint8_t run(model_t* restrict mod, char* message, size_t msg_len) {
|
|
552
551
|
|
553
552
|
double stop = clock();
|
554
553
|
|
555
|
-
|
556
|
-
|
554
|
+
if (mod->print_pct != -1) {
|
555
|
+
fprintf(stdout, "\r%sruntime: %.3fs \n", message, (double)(stop - start) / CLOCKS_PER_SEC);
|
556
|
+
fflush(stdout);
|
557
|
+
}
|
557
558
|
return SUCCESS;
|
558
559
|
}
|
559
560
|
|
@@ -18,8 +18,8 @@
|
|
18
18
|
|
19
19
|
|
20
20
|
|
21
|
-
// upper bound for RNG is 2^
|
22
|
-
#define RAND_UPPER_PLUS_2 (double) (
|
21
|
+
// upper bound for RNG is 2^30 + 1
|
22
|
+
#define RAND_UPPER_PLUS_2 (double) ((1LL << 30) + 1)
|
23
23
|
|
24
24
|
// directions of migration
|
25
25
|
// so that 3 - mig_dir = reflection of it. Used to track neighbors
|
@@ -37,19 +37,24 @@
|
|
37
37
|
#define SIM_OVERFLOW 3
|
38
38
|
#define ACCURACY_ERROR 4
|
39
39
|
|
40
|
+
|
41
|
+
/**
|
42
|
+
* Handling Numerical Errors:
|
43
|
+
* half of the rates / values related to rates are calculated on a cumulative basis. i.e., updated over time instead of re-calculating from scratch
|
44
|
+
* numerival errors might explode in this case, so need to re-calculate every sometime
|
45
|
+
*/
|
46
|
+
|
40
47
|
// where exp(x) is considered overflow
|
41
48
|
// below the actual bound (709) to preserve accuracy
|
42
49
|
#define EXP_OVERFLOW_BOUND 500
|
43
|
-
|
50
|
+
|
51
|
+
// Compare current rates with this bound
|
52
|
+
#define ACCURATE_BOUND 1LL << 33 // about 8.6 * 10^9
|
44
53
|
|
45
54
|
// how frequent to update rates & sum of rates in single test (recalculate)
|
46
|
-
#define UPDATE_SUM_ROUNDS_SM 100
|
55
|
+
#define UPDATE_SUM_ROUNDS_SM 100 // small, more frequent if some rate is larger than ACCURATE_BOUND
|
47
56
|
#define UPDATE_SUM_ROUNDS_LG 10000
|
48
57
|
|
49
|
-
|
50
|
-
static uint64_t pcg_state = 0;
|
51
|
-
static uint64_t pcg_inc = 0;
|
52
|
-
|
53
58
|
|
54
59
|
|
55
60
|
|
@@ -109,7 +114,7 @@ static inline double random01() {
|
|
109
114
|
uint32_t r1 = rand() & 0x7fff; // RAND_MAX is different across machines, ensure 15 bits
|
110
115
|
uint32_t r2 = rand() & 0x7fff;
|
111
116
|
|
112
|
-
double r_combined = (r1 << 15) + r2;
|
117
|
+
double r_combined = (r1 << 15) + r2;
|
113
118
|
return (r_combined + 1) / RAND_UPPER_PLUS_2;
|
114
119
|
}
|
115
120
|
|
@@ -121,8 +126,8 @@ static inline void update_pi_k(patch_t* restrict p, const double* restrict M_sta
|
|
121
126
|
// M_start: start index of patch (i, j)'s matrix
|
122
127
|
// P_start: start index of p's patch variables, i.e., ij * 6
|
123
128
|
|
124
|
-
|
125
|
-
|
129
|
+
uint32_t U = p->U;
|
130
|
+
uint32_t V = p->V;
|
126
131
|
double sum = U + V;
|
127
132
|
double U_ratio = U / sum;
|
128
133
|
double V_ratio = V / sum;
|
@@ -165,8 +170,8 @@ static inline void update_mig_just_rate(patch_t* restrict p, const double* restr
|
|
165
170
|
double* p_U_weight = p->U_weight;
|
166
171
|
double* p_V_weight = p->V_weight;
|
167
172
|
|
168
|
-
double mu1_U = P_start[0] *
|
169
|
-
double mu2_V = P_start[1] *
|
173
|
+
double mu1_U = P_start[0] * p->U;
|
174
|
+
double mu2_V = P_start[1] * p->V;
|
170
175
|
|
171
176
|
double mu1_U_divide_sum = mu1_U / p->sum_U_weight;
|
172
177
|
double mu2_V_divide_sum = mu2_V / p->sum_V_weight;
|
@@ -349,9 +354,6 @@ static inline void change_popu(patch_t* restrict p, uint8_t s) {
|
|
349
354
|
p->V -= 1;
|
350
355
|
}
|
351
356
|
return;
|
352
|
-
//default:
|
353
|
-
// fprintf(stderr, "Bug: invalid event number in change_popu: %hhu\n", s);
|
354
|
-
// return;
|
355
357
|
}
|
356
358
|
}
|
357
359
|
|
@@ -1,4 +1,4 @@
|
|
1
|
-
__version__ = '2.3.
|
1
|
+
__version__ = '2.3.7'
|
2
2
|
|
3
3
|
'''
|
4
4
|
version history:
|
@@ -43,4 +43,5 @@ version history:
|
|
43
43
|
2.3.4: change back to the mig & payoff rules in version 2.3.2
|
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
|
+
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.
|
46
47
|
'''
|
@@ -29,12 +29,8 @@ def save_data(mod, dirs = '', print_msg = True):
|
|
29
29
|
except AttributeError:
|
30
30
|
raise ValueError('mod is not a model object')
|
31
31
|
|
32
|
-
if dirs
|
33
|
-
|
34
|
-
if dirs[:-1] != '/':
|
35
|
-
dirs += '/'
|
36
|
-
if not os.path.exists(dirs):
|
37
|
-
os.makedirs(dirs)
|
32
|
+
if not os.path.exists(dirs):
|
33
|
+
os.makedirs(dirs)
|
38
34
|
|
39
35
|
data = []
|
40
36
|
|
@@ -64,14 +60,11 @@ def save_data(mod, dirs = '', print_msg = True):
|
|
64
60
|
outputs.append(mod.Vpi.tolist())
|
65
61
|
# H&Vpi_total are not saved, will be calculated when reading the data
|
66
62
|
data.append(outputs)
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
with gzip.open(data_dirs, 'w') as f:
|
73
|
-
f.write(data_bytes)
|
74
|
-
|
63
|
+
|
64
|
+
data_dirs = os.path.join(dirs, 'data.json.gz')
|
65
|
+
with gzip.open(data_dirs, 'wb') as f:
|
66
|
+
f.write(json.dumps(data).encode('utf-8'))
|
67
|
+
|
75
68
|
if print_msg:
|
76
69
|
print('data saved: ' + data_dirs)
|
77
70
|
|
@@ -89,35 +82,30 @@ def read_data(dirs):
|
|
89
82
|
- mod: a piegy.model.model object read from the data.
|
90
83
|
'''
|
91
84
|
|
92
|
-
if dirs
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
raise FileNotFoundError('dirs not found: ' + dirs)
|
98
|
-
|
99
|
-
if not os.path.isfile(dirs + 'data.json.gz'):
|
85
|
+
if not os.path.exists(dirs):
|
86
|
+
raise FileNotFoundError('dirs not found: ' + dirs)
|
87
|
+
|
88
|
+
data_dirs = os.path.join(dirs, 'data.json.gz')
|
89
|
+
if not os.path.isfile(data_dirs):
|
100
90
|
raise FileNotFoundError('data not found in ' + dirs)
|
101
91
|
|
102
|
-
with gzip.open(
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
except:
|
120
|
-
raise ValueError('Invalid model results saved in data')
|
92
|
+
with gzip.open(data_dirs, 'rb') as f:
|
93
|
+
data = json.loads(f.read().decode('utf-8'))
|
94
|
+
|
95
|
+
# inputs
|
96
|
+
try:
|
97
|
+
mod = simulation.model(N = data[0][0], M = data[0][1], maxtime = data[0][2], record_itv = data[0][3],
|
98
|
+
sim_time = data[0][4], boundary = data[0][5], I = data[0][6], X = data[0][7], P = data[0][8],
|
99
|
+
print_pct = data[0][9], seed = data[0][10], check_overflow = data[0][11])
|
100
|
+
except:
|
101
|
+
raise ValueError('Invalid input parameters saved in data')
|
102
|
+
|
103
|
+
# outputs
|
104
|
+
try:
|
105
|
+
mod.set_data(data_empty = False, max_record = data[1][0], compress_itv = data[1][1],
|
106
|
+
U = data[1][2], V = data[1][3], Upi = data[1][4], Vpi = data[1][5])
|
107
|
+
except:
|
108
|
+
raise ValueError('Invalid model results saved in data')
|
121
109
|
|
122
110
|
return mod
|
123
111
|
|
@@ -332,15 +332,15 @@ def pi_bar(mod, ax_U = None, ax_V = None, U_color = 'violet', V_color = 'yellowg
|
|
332
332
|
end_index = int(mod.max_record * end)
|
333
333
|
|
334
334
|
Upi_ave = figure_t.ave_interval_1D(mod.Upi, start_index, end_index)
|
335
|
-
|
335
|
+
Vpi_ave = figure_t.ave_interval_1D(mod.Vpi, start_index, end_index)
|
336
336
|
|
337
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
339
|
V_title = figure_t.gen_title(r'$p_D$', start, end)
|
340
|
-
V_text = figure_t.gen_text(np.mean(
|
340
|
+
V_text = figure_t.gen_text(np.mean(Vpi_ave), np.std(Vpi_ave))
|
341
341
|
|
342
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(
|
343
|
+
ax_V = figure_t.bar(Vpi_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
|
|
@@ -450,11 +450,11 @@ def run(mod, message = ""):
|
|
450
450
|
elif result == SIM_OVERFLOW:
|
451
451
|
LIB.mod_free_py(ctypes.byref(mod_c))
|
452
452
|
del mod_c
|
453
|
-
raise OverflowError('Overflow in simulation. Possibly due to too large w1, w2, or payoff
|
453
|
+
raise OverflowError('Overflow in simulation. Possibly due to too large w1, w2, or payoff.')
|
454
454
|
elif result == ACCURACY_ERROR:
|
455
455
|
LIB.mod_free_py(ctypes.byref(mod_c))
|
456
456
|
del mod_c
|
457
|
-
raise RuntimeError('Accuracy dropped catastrophically during simulation. Possibly due to too large w1, w2, or payoff
|
457
|
+
raise RuntimeError('Accuracy dropped catastrophically during simulation. Possibly due to too large w1, w2, or payoff.')
|
458
458
|
else:
|
459
459
|
LIB.mod_free_py(ctypes.byref(mod_c))
|
460
460
|
del mod_c
|
@@ -529,9 +529,9 @@ def check_overflow_func(mod):
|
|
529
529
|
w1_pi = pi_expected[i][j] * mod.P[i][j][2] # w1 * U_pi
|
530
530
|
w2_pi = pi_expected[i][j] * mod.P[i][j][3] # w2 * V_pi
|
531
531
|
if ((w1_pi > EXP_OVERFLOW_BOUND) or (w2_pi > EXP_OVERFLOW_BOUND)):
|
532
|
-
print("Warning: might cause overflow in simulation.
|
532
|
+
print("Warning: might cause overflow in simulation. w1, w2, or payoff matrix values too large")
|
533
533
|
return
|
534
534
|
if ((w1_pi > EXP_TOO_LARGE_BOUND) or (w2_pi > EXP_TOO_LARGE_BOUND)):
|
535
|
-
print("Warning: might have low accuracy in simulation.
|
535
|
+
print("Warning: might have low accuracy in simulation. w1, w2, or payoff matrix values too large")
|
536
536
|
return
|
537
537
|
|
@@ -92,6 +92,7 @@ def test_var1(mod, var, values, dirs, compress_itv = None):
|
|
92
92
|
if compress_itv != None:
|
93
93
|
sim2.compress_data(compress_itv)
|
94
94
|
data_t.save_data(sim2, var_dirs[k], print_msg = False)
|
95
|
+
del sim2
|
95
96
|
except (OverflowError, RuntimeError):
|
96
97
|
print(current_var_str + ' raised error, skipped')
|
97
98
|
continue
|
@@ -139,6 +140,7 @@ def test_var2(mod, var1, var2, values1, values2, dirs, compress_itv = None):
|
|
139
140
|
if compress_itv != None:
|
140
141
|
sim2.compress_data(compress_itv)
|
141
142
|
data_t.save_data(sim2, var_dirs[k1][k2], print_msg = False)
|
143
|
+
del sim2
|
142
144
|
except (OverflowError, RuntimeError):
|
143
145
|
print(current_var_str + ' raised error, skipped')
|
144
146
|
continue
|
@@ -185,6 +187,7 @@ def var_UV1(var, values, var_dirs, ax_U = None, ax_V = None, start = 0.95, end =
|
|
185
187
|
|
186
188
|
U_ave.append(sum(figure_t.ave_interval_1D(simk.U, start_index, end_index)) / NM)
|
187
189
|
V_ave.append(sum(figure_t.ave_interval_1D(simk.V, start_index, end_index)) / NM)
|
190
|
+
del simk
|
188
191
|
|
189
192
|
#### plot ####
|
190
193
|
if ax_U == None:
|
@@ -253,6 +256,7 @@ def var_UV2(var1, var2, values1, values2, var_dirs, ax_U = None, ax_V = None, va
|
|
253
256
|
|
254
257
|
U_ave[k1].append(sum(figure_t.ave_interval_1D(simk.U, start_index, end_index)) / NM)
|
255
258
|
V_ave[k1].append(sum(figure_t.ave_interval_1D(simk.V, start_index, end_index)) / NM)
|
259
|
+
del simk
|
256
260
|
|
257
261
|
U_ave = np.array(U_ave)
|
258
262
|
V_ave = np.array(V_ave)
|
@@ -340,7 +344,6 @@ def var_pi1(var, values, var_dirs, ax_U = None, ax_V = None, start = 0.95, end =
|
|
340
344
|
|
341
345
|
U_ave.append(np.sum(figure_t.ave_interval(simk.Upi, start_index, end_index)) / NM)
|
342
346
|
V_ave.append(np.sum(figure_t.ave_interval(simk.Vpi, start_index, end_index)) / NM)
|
343
|
-
|
344
347
|
del simk
|
345
348
|
|
346
349
|
#### plot ####
|
@@ -406,8 +409,7 @@ def var_pi2(var1, var2, values1, values2, var_dirs, ax_U = None, ax_V = None, va
|
|
406
409
|
|
407
410
|
U_ave[k1].append(np.sum(figure_t.ave_interval(simk.Upi, start_index, end_index)) / NM)
|
408
411
|
V_ave[k1].append(np.sum(figure_t.ave_interval(simk.Vpi, start_index, end_index)) / NM)
|
409
|
-
|
410
|
-
del simk # manually delete this large object
|
412
|
+
del simk
|
411
413
|
|
412
414
|
U_ave = np.array(U_ave)
|
413
415
|
V_ave = np.array(V_ave)
|
@@ -507,14 +509,16 @@ def var_convergence1(var_dirs, interval = 20, start = 0.8, fluc = 0.07):
|
|
507
509
|
|
508
510
|
diverge_list = []
|
509
511
|
|
510
|
-
for
|
512
|
+
for k in range(len(var_dirs)):
|
513
|
+
dirs = var_dirs[k]
|
511
514
|
try:
|
512
|
-
|
515
|
+
simk = data_t.read_data(dirs)
|
513
516
|
except FileNotFoundError:
|
514
517
|
print(dirs + ' data not found, skipped')
|
515
518
|
continue
|
516
|
-
if not analysis.check_convergence(
|
519
|
+
if not analysis.check_convergence(simk, interval, start, fluc):
|
517
520
|
diverge_list.append(dirs)
|
521
|
+
del simk
|
518
522
|
|
519
523
|
return diverge_list
|
520
524
|
|
@@ -574,14 +578,16 @@ def var_convergence2(var_dirs, interval = 20, start = 0.8, fluc = 0.07):
|
|
574
578
|
diverge_list = []
|
575
579
|
|
576
580
|
for sublist in var_dirs:
|
577
|
-
for
|
581
|
+
for k in range(len(sublist)):
|
582
|
+
dirs = sublist[k]
|
578
583
|
try:
|
579
|
-
|
584
|
+
simk = data_t.read_data(dirs)
|
580
585
|
except FileNotFoundError:
|
581
586
|
print(dirs + ' data not found, skipped')
|
582
587
|
continue
|
583
|
-
if not analysis.check_convergence(
|
588
|
+
if not analysis.check_convergence(simk, interval, start, fluc):
|
584
589
|
diverge_list.append(dirs)
|
590
|
+
del simk
|
585
591
|
|
586
592
|
return diverge_list
|
587
593
|
|
@@ -9,9 +9,8 @@ def find_C():
|
|
9
9
|
C_core_path = os.path.join(os.path.dirname(os.path.dirname(__file__)), 'C_core')
|
10
10
|
C_list = os.listdir(C_core_path)
|
11
11
|
for file in C_list:
|
12
|
-
if file[-3:] == '.so':
|
13
|
-
|
14
|
-
|
15
|
-
return C_core_path + '/' + file
|
12
|
+
if (file[-3:] == '.so') or (file[-4:] == '.pyd') or (file[-4:] == '.dll') or (file[-4:] == '.lib'):
|
13
|
+
if 'piegyc' in file:
|
14
|
+
return C_core_path + '/' + file
|
16
15
|
|
17
16
|
raise FileNotFoundError('C computation core not found. You can either compile manully or use the Python core instead. Please see docs.')
|
@@ -27,7 +27,6 @@ import matplotlib.style as mplstyle
|
|
27
27
|
import numpy as np
|
28
28
|
import os
|
29
29
|
from cv2 import imread, VideoWriter, VideoWriter_fourcc
|
30
|
-
from moviepy import ImageSequenceClip
|
31
30
|
|
32
31
|
|
33
32
|
# a list of supported figures
|
@@ -144,7 +143,7 @@ def frame_lim(mod, func, frames):
|
|
144
143
|
U_ylim = get_max_lim(U_ylist)
|
145
144
|
V_xlim = get_max_lim(V_xlist)
|
146
145
|
V_ylim = get_max_lim(V_ylist)
|
147
|
-
|
146
|
+
|
148
147
|
return U_xlim, U_ylim, V_xlim, V_ylim
|
149
148
|
|
150
149
|
|
@@ -200,14 +199,15 @@ def make_mp4(video_dir, frame_dir, fps):
|
|
200
199
|
if (file[-4:] == '.png') and ('frame' in file):
|
201
200
|
frame_path.append(os.path.join(frame_dir, file))
|
202
201
|
|
202
|
+
# setup cv2 video writer
|
203
203
|
first_frame = imread(frame_path[0])
|
204
204
|
height, width, _ = first_frame.shape
|
205
205
|
fourcc = VideoWriter_fourcc(*'mp4v')
|
206
206
|
video_writer = VideoWriter(video_dir, fourcc, fps, (width, height))
|
207
207
|
|
208
208
|
for file in frame_path:
|
209
|
-
|
210
|
-
|
209
|
+
frame = imread(file)
|
210
|
+
video_writer.write(frame)
|
211
211
|
video_writer.release()
|
212
212
|
|
213
213
|
|
@@ -236,9 +236,9 @@ def make_video(mod, func_name = 'UV_hmap', frames = 100, dpi = 200, fps = 30, U_
|
|
236
236
|
# convert color if invalid colors are given
|
237
237
|
U_color, V_color = convert_color(func_name, U_color, V_color)
|
238
238
|
|
239
|
-
# set
|
240
|
-
|
241
|
-
|
239
|
+
# set Agg backend for faster speed
|
240
|
+
original_backend = mpl.get_backend()
|
241
|
+
mpl.use("Agg")
|
242
242
|
|
243
243
|
# print progress
|
244
244
|
one_progress = frames / 100
|
@@ -267,7 +267,7 @@ def make_video(mod, func_name = 'UV_hmap', frames = 100, dpi = 200, fps = 30, U_
|
|
267
267
|
|
268
268
|
#### for loop ####
|
269
269
|
|
270
|
-
for i in range(frames
|
270
|
+
for i in range(frames):
|
271
271
|
if i > current_progress:
|
272
272
|
print('making frames', round(i / frames * 100), '%', end = '\r')
|
273
273
|
current_progress += one_progress
|
@@ -277,9 +277,9 @@ def make_video(mod, func_name = 'UV_hmap', frames = 100, dpi = 200, fps = 30, U_
|
|
277
277
|
fig_U, ax_U = plt.subplots(figsize = figsize)
|
278
278
|
fig_V, ax_V = plt.subplots(figsize = figsize)
|
279
279
|
else:
|
280
|
-
fig_U, ax_U = plt.subplots(figsize = figsize)
|
281
|
-
fig_V, ax_V = plt.subplots(figsize = figsize)
|
282
|
-
|
280
|
+
fig_U, ax_U = plt.subplots(figsize = figsize)
|
281
|
+
fig_V, ax_V = plt.subplots(figsize = figsize)
|
282
|
+
|
283
283
|
if 'hmap' in func_name:
|
284
284
|
func(mod, ax_U = ax_U, ax_V = ax_V, U_color = U_color, V_color = V_color, start = i / frames, end = (i + 1) / frames, vrange_U = U_clim, vrange_V = V_clim)
|
285
285
|
else:
|
@@ -304,6 +304,9 @@ def make_video(mod, func_name = 'UV_hmap', frames = 100, dpi = 200, fps = 30, U_
|
|
304
304
|
plt.close(fig_V)
|
305
305
|
|
306
306
|
#### for loop ends ####
|
307
|
+
|
308
|
+
# reset to original backend
|
309
|
+
mpl.use(original_backend)
|
307
310
|
|
308
311
|
# frames done
|
309
312
|
print('making mp4... ', end = '\r')
|
@@ -1,61 +0,0 @@
|
|
1
|
-
#include <stdbool.h>
|
2
|
-
#include <stdlib.h>
|
3
|
-
#include <stdint.h>
|
4
|
-
#include <stdio.h>
|
5
|
-
|
6
|
-
#include "model.h"
|
7
|
-
#include "patch.h"
|
8
|
-
#include "sim_funcs.h"
|
9
|
-
|
10
|
-
|
11
|
-
int main() {
|
12
|
-
size_t N = 1;
|
13
|
-
size_t M = 100;
|
14
|
-
double maxtime = 300;
|
15
|
-
double record_itv = 0.1;
|
16
|
-
size_t sim_time = 1;
|
17
|
-
bool boundary = true;
|
18
|
-
uint32_t I_single[2] = {3, 3};
|
19
|
-
double X_single[4] = {-1, 4, 0, 2};
|
20
|
-
double P_single[6] = {0.5, 0.5, 80, 80, 0.001, 0.001};
|
21
|
-
int32_t print_pct = 1;
|
22
|
-
int32_t seed = 36; // -1 for None
|
23
|
-
|
24
|
-
uint32_t I[N * M * 2];
|
25
|
-
double X[N * M * 4];
|
26
|
-
double P[N * M * 6];
|
27
|
-
|
28
|
-
//printf("sizeof(patch_t) = %zu bytes\n", sizeof(patch_t));
|
29
|
-
size_t ij = 0;
|
30
|
-
for (size_t i = 0; i < N; i++) {
|
31
|
-
for (size_t j = 0; j < M; j++) {
|
32
|
-
I[ij * 2] = I_single[0];
|
33
|
-
I[ij * 2 + 1] = I_single[1];
|
34
|
-
|
35
|
-
for (size_t k = 0; k < 4; k++) {
|
36
|
-
X[ij * 4 + k] = X_single[k];
|
37
|
-
}
|
38
|
-
for (size_t k = 0; k < 6; k++) {
|
39
|
-
P[ij * 6 + k] = P_single[k];
|
40
|
-
}
|
41
|
-
++ij;
|
42
|
-
}
|
43
|
-
}
|
44
|
-
|
45
|
-
model_t* mod = malloc(sizeof(model_t));
|
46
|
-
mod_init(mod, N, M, maxtime, record_itv, sim_time, boundary, I, X, P, print_pct, seed);
|
47
|
-
|
48
|
-
char message[20] = ""; // writable buffer with enough space
|
49
|
-
uint8_t result = run(mod, message, 20);
|
50
|
-
|
51
|
-
/*for (size_t i = 0; i < mod->max_record; i++) {
|
52
|
-
fprintf(stdout, "%f ", mod->U1d[i]);
|
53
|
-
}
|
54
|
-
fprintf(stdout, "\n");
|
55
|
-
for (size_t i = 0; i < mod->max_record; i++) {
|
56
|
-
fprintf(stdout, "%f ", mod->Upi_1d[i]);
|
57
|
-
}*/
|
58
|
-
mod_free(mod);
|
59
|
-
mod = NULL;
|
60
|
-
}
|
61
|
-
|
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
|