piegy 2.3.8__tar.gz → 2.3.9__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.8/src/piegy.egg-info → piegy-2.3.9}/PKG-INFO +1 -1
- {piegy-2.3.8 → piegy-2.3.9}/pyproject.toml +1 -1
- {piegy-2.3.8 → piegy-2.3.9}/src/piegy/C_core/model.c +8 -9
- {piegy-2.3.8 → piegy-2.3.9}/src/piegy/C_core/patch.c +0 -3
- piegy-2.3.9/src/piegy/C_core/random.h +77 -0
- {piegy-2.3.8 → piegy-2.3.9}/src/piegy/C_core/sim_funcs.c +14 -15
- {piegy-2.3.8 → piegy-2.3.9}/src/piegy/C_core/sim_funcs.h +14 -26
- {piegy-2.3.8 → piegy-2.3.9}/src/piegy/__version__.py +2 -1
- {piegy-2.3.8 → piegy-2.3.9}/src/piegy/data_tools.py +18 -9
- {piegy-2.3.8 → piegy-2.3.9}/src/piegy/simulation.py +5 -14
- {piegy-2.3.8 → piegy-2.3.9}/src/piegy/simulation_py.py +17 -9
- {piegy-2.3.8 → piegy-2.3.9/src/piegy.egg-info}/PKG-INFO +1 -1
- {piegy-2.3.8 → piegy-2.3.9}/src/piegy.egg-info/SOURCES.txt +1 -0
- {piegy-2.3.8 → piegy-2.3.9}/LICENSE.txt +0 -0
- {piegy-2.3.8 → piegy-2.3.9}/MANIFEST.in +0 -0
- {piegy-2.3.8 → piegy-2.3.9}/README.md +0 -0
- {piegy-2.3.8 → piegy-2.3.9}/setup.cfg +0 -0
- {piegy-2.3.8 → piegy-2.3.9}/setup.py +0 -0
- {piegy-2.3.8 → piegy-2.3.9}/src/piegy/C_core/Makefile +0 -0
- {piegy-2.3.8 → piegy-2.3.9}/src/piegy/C_core/model.h +0 -0
- {piegy-2.3.8 → piegy-2.3.9}/src/piegy/C_core/patch.h +0 -0
- {piegy-2.3.8 → piegy-2.3.9}/src/piegy/__init__.py +0 -0
- {piegy-2.3.8 → piegy-2.3.9}/src/piegy/analysis.py +0 -0
- {piegy-2.3.8 → piegy-2.3.9}/src/piegy/build_info.py +0 -0
- {piegy-2.3.8 → piegy-2.3.9}/src/piegy/figures.py +0 -0
- {piegy-2.3.8 → piegy-2.3.9}/src/piegy/test_var.py +0 -0
- {piegy-2.3.8 → piegy-2.3.9}/src/piegy/tools/__init__.py +0 -0
- {piegy-2.3.8 → piegy-2.3.9}/src/piegy/tools/figure_tools.py +0 -0
- {piegy-2.3.8 → piegy-2.3.9}/src/piegy/tools/file_tools.py +0 -0
- {piegy-2.3.8 → piegy-2.3.9}/src/piegy/tools/find_C.py +0 -0
- {piegy-2.3.8 → piegy-2.3.9}/src/piegy/videos.py +0 -0
- {piegy-2.3.8 → piegy-2.3.9}/src/piegy.egg-info/dependency_links.txt +0 -0
- {piegy-2.3.8 → piegy-2.3.9}/src/piegy.egg-info/requires.txt +0 -0
- {piegy-2.3.8 → piegy-2.3.9}/src/piegy.egg-info/top_level.txt +0 -0
@@ -79,17 +79,16 @@ void mod_free(model_t* mod) {
|
|
79
79
|
|
80
80
|
void mod_free_py(model_t* mod) {
|
81
81
|
// free function for python
|
82
|
-
|
82
|
+
// the same as mod_free except for not having free(mod)
|
83
83
|
if (!mod) return;
|
84
|
-
if (mod->I) { free(mod->I); }
|
85
|
-
if (mod->X) { free(mod->X); }
|
86
|
-
if (mod->P) { free(mod->P); }
|
87
|
-
if (mod->U1d) { free(mod->U1d); }
|
88
|
-
if (mod->V1d) { free(mod->V1d); }
|
89
|
-
if (mod->Upi_1d) { free(mod->Upi_1d); }
|
90
|
-
if (mod->Vpi_1d) { free(mod->Vpi_1d); }
|
91
|
-
// if (mod) { free(mod); }
|
92
84
|
|
85
|
+
free(mod->I);
|
86
|
+
free(mod->X);
|
87
|
+
free(mod->P);
|
88
|
+
free(mod->U1d);
|
89
|
+
free(mod->V1d);
|
90
|
+
free(mod->Upi_1d);
|
91
|
+
free(mod->Vpi_1d);
|
93
92
|
mod->I = NULL;
|
94
93
|
mod->X = mod->P = mod->U1d = mod->V1d = mod->Upi_1d = mod->Vpi_1d = NULL;
|
95
94
|
}
|
@@ -17,9 +17,6 @@ void patch_init(patch_t* p, uint32_t U, uint32_t V, size_t row, size_t col, doub
|
|
17
17
|
|
18
18
|
memcpy(p->X, X_start, 4 * sizeof(double));
|
19
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
20
|
|
24
21
|
for (size_t i = 0; i < 4; i++) {
|
25
22
|
p->U_weight[i] = 0;
|
@@ -0,0 +1,77 @@
|
|
1
|
+
/**
|
2
|
+
* The Random Number Generation module
|
3
|
+
* Returns a random double in (0, 1) with 2^-53 resolution, 0 and 1 not included
|
4
|
+
*
|
5
|
+
* First initialize xoshiro256+ states with Splitmix64
|
6
|
+
* Then use xoshiro256+ for random number generation
|
7
|
+
*
|
8
|
+
* Referrence:
|
9
|
+
* xoshiro256++ code: https://prng.di.unimi.it
|
10
|
+
* Splitmix64 code: https://rosettacode.org/wiki/Pseudo-random_numbers/Splitmix64
|
11
|
+
*
|
12
|
+
*/
|
13
|
+
|
14
|
+
#include <stdint.h>
|
15
|
+
|
16
|
+
|
17
|
+
// resolution of random01 is 2^-53
|
18
|
+
// which is (about) the IEEE 754 double precision
|
19
|
+
#define MAX_53BIT (uint64_t) ((1ULL << 53) - 1)
|
20
|
+
#define RAND_DENOM 1.0 / ((double) (1ULL << 53))
|
21
|
+
// xor_state
|
22
|
+
static uint64_t xor_state[4];
|
23
|
+
static uint64_t splitmix64_state;
|
24
|
+
|
25
|
+
|
26
|
+
|
27
|
+
static inline uint64_t Splitmix64_rand() {
|
28
|
+
// used to seed PCG initial states
|
29
|
+
splitmix64_state += 0x9e3779b97f4a7c15ULL;
|
30
|
+
uint64_t z = splitmix64_state;
|
31
|
+
z = (z ^ (z >> 30)) * 0xbf58476d1ce4e5b9ULL;
|
32
|
+
z = (z ^ (z >> 27)) * 0x94d049bb133111ebULL;
|
33
|
+
return z ^ (z >> 31);
|
34
|
+
}
|
35
|
+
|
36
|
+
|
37
|
+
static inline uint64_t rot23(const uint64_t x) {
|
38
|
+
// 23 and 64 - 23
|
39
|
+
// Not used here, part of xoshiro256++
|
40
|
+
return (x << 23) | (x >> 41);
|
41
|
+
}
|
42
|
+
|
43
|
+
|
44
|
+
static inline uint64_t rot45(const uint64_t x) {
|
45
|
+
// 45 and 64 - 45
|
46
|
+
return (x << 45) | (x >> 19);
|
47
|
+
}
|
48
|
+
|
49
|
+
|
50
|
+
static inline double random01() {
|
51
|
+
// return a random number in (0, 1) with 2^-53 resolution. 0 and 1 not included.
|
52
|
+
|
53
|
+
const uint64_t result = xor_state[0] + xor_state[3];
|
54
|
+
const uint64_t t = xor_state[1] << 17;
|
55
|
+
|
56
|
+
xor_state[2] ^= xor_state[0];
|
57
|
+
xor_state[3] ^= xor_state[1];
|
58
|
+
xor_state[1] ^= xor_state[2];
|
59
|
+
xor_state[0] ^= xor_state[3];
|
60
|
+
|
61
|
+
xor_state[2] ^= t;
|
62
|
+
xor_state[3] = rot45(xor_state[3]);
|
63
|
+
|
64
|
+
return ((double) (result & MAX_53BIT) + 0.5) * RAND_DENOM;
|
65
|
+
}
|
66
|
+
|
67
|
+
|
68
|
+
static inline void rand_init(const uint64_t seed) {
|
69
|
+
// initialize PCG random
|
70
|
+
splitmix64_state = seed;
|
71
|
+
for (int i = 0; i < 4; i++) {
|
72
|
+
xor_state[i] = Splitmix64_rand();
|
73
|
+
}
|
74
|
+
(void) random01();
|
75
|
+
}
|
76
|
+
|
77
|
+
|
@@ -144,7 +144,7 @@ static double single_init(const model_t* restrict mod, patch_t* restrict world,
|
|
144
144
|
|
145
145
|
// make signal
|
146
146
|
if (mod->boundary) {
|
147
|
-
make_signal_zero_flux(picked_p->i, picked_p->j, e0, sig_p);
|
147
|
+
make_signal_zero_flux(N, M, picked_p->i, picked_p->j, e0, sig_p);
|
148
148
|
} else {
|
149
149
|
make_signal_periodical(N, M, picked_p->i, picked_p->j, e0, sig_p);
|
150
150
|
}
|
@@ -205,6 +205,14 @@ static uint8_t single_test(model_t* restrict mod, char* message) {
|
|
205
205
|
size_t curr_update_sum_round = 0; // current round
|
206
206
|
size_t update_sum_freq = UPDATE_SUM_ROUNDS_SM; // recalculate sum every this many rounds
|
207
207
|
|
208
|
+
// set make_signal function based on boundary conditions
|
209
|
+
void (*make_signal)(size_t, size_t, size_t, size_t, uint8_t, signal_t*);
|
210
|
+
if (mod->boundary) {
|
211
|
+
make_signal = &make_signal_zero_flux;
|
212
|
+
} else {
|
213
|
+
make_signal = &make_signal_periodical;
|
214
|
+
}
|
215
|
+
|
208
216
|
// core containers
|
209
217
|
patch_t* world = (patch_t*) calloc(NM, sizeof(patch_t));
|
210
218
|
size_t* nb_indices = (size_t*) calloc(NM * 4, sizeof(size_t));
|
@@ -261,10 +269,11 @@ static uint8_t single_test(model_t* restrict mod, char* message) {
|
|
261
269
|
uint8_t curr_prog = (uint8_t)(time * 100 / maxtime);
|
262
270
|
if (curr_prog < 10) {
|
263
271
|
fprintf(stdout, "\r%s: %d %%", message, (int)(time * 100 / maxtime));
|
272
|
+
fflush(stdout);
|
264
273
|
} else {
|
265
274
|
fprintf(stdout, "\r%s: %d%%", message, (int)(time * 100 / maxtime));
|
275
|
+
fflush(stdout);
|
266
276
|
}
|
267
|
-
fflush(stdout);
|
268
277
|
//fprintf(stdout, "\n99: %d, %d, %f, %f\n100: %d, %d, %f, %f\n",
|
269
278
|
//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
279
|
//fflush(stdout);
|
@@ -405,11 +414,7 @@ static uint8_t single_test(model_t* restrict mod, char* message) {
|
|
405
414
|
}
|
406
415
|
|
407
416
|
// make signal
|
408
|
-
|
409
|
-
make_signal_zero_flux(picked.i, picked.j, e0, &signal);
|
410
|
-
} else {
|
411
|
-
make_signal_periodical(N, M, picked.i, picked.j, e0, &signal);
|
412
|
-
}
|
417
|
+
(*make_signal)(N, M, picked.i, picked.j, e0, &signal);
|
413
418
|
signal.ij1 = signal.i1 * M + signal.j1;
|
414
419
|
signal.ij2 = signal.i2 * M + signal.j2;
|
415
420
|
|
@@ -498,15 +503,9 @@ uint8_t run(model_t* restrict mod, char* message, size_t msg_len) {
|
|
498
503
|
|
499
504
|
// initialize random
|
500
505
|
if (mod->seed != -1) {
|
501
|
-
|
502
|
-
} else {
|
503
|
-
srand(time(NULL));
|
504
|
-
}
|
505
|
-
|
506
|
-
if (mod->seed == -1){
|
507
|
-
srand(time(NULL));
|
506
|
+
rand_init((uint64_t) mod->seed);
|
508
507
|
} else {
|
509
|
-
|
508
|
+
rand_init((uint64_t) time(NULL));
|
510
509
|
}
|
511
510
|
|
512
511
|
if (mod->print_pct == 0) {
|
@@ -15,11 +15,11 @@
|
|
15
15
|
|
16
16
|
#include "patch.h"
|
17
17
|
#include "model.h"
|
18
|
+
#include "random.h"
|
19
|
+
|
18
20
|
|
19
21
|
|
20
22
|
|
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
|
@@ -55,8 +55,6 @@
|
|
55
55
|
#define UPDATE_SUM_ROUNDS_SM 100 // small, more frequent if some rate is larger than ACCURATE_BOUND
|
56
56
|
#define UPDATE_SUM_ROUNDS_LG 10000
|
57
57
|
|
58
|
-
|
59
|
-
|
60
58
|
|
61
59
|
/**
|
62
60
|
* index of patch in find_patch
|
@@ -105,19 +103,6 @@ uint8_t run(model_t* restrict mod, char* message, size_t msg_len);
|
|
105
103
|
|
106
104
|
|
107
105
|
|
108
|
-
/**
|
109
|
-
* Inline Functions
|
110
|
-
*/
|
111
|
-
|
112
|
-
static inline double random01() {
|
113
|
-
// generate a 24 bit random int, then convert to a (0, 1) ranged double
|
114
|
-
uint32_t r1 = rand() & 0x7fff; // RAND_MAX is different across machines, ensure 15 bits
|
115
|
-
uint32_t r2 = rand() & 0x7fff;
|
116
|
-
|
117
|
-
double r_combined = (r1 << 15) + r2;
|
118
|
-
return (r_combined + 1) / RAND_UPPER_PLUS_2;
|
119
|
-
}
|
120
|
-
|
121
106
|
/**
|
122
107
|
* patch functions
|
123
108
|
*/
|
@@ -127,10 +112,10 @@ static inline void update_pi_k(patch_t* restrict p) {
|
|
127
112
|
uint32_t U = p->U;
|
128
113
|
uint32_t V = p->V;
|
129
114
|
double sum = U + V;
|
130
|
-
double U_ratio = U / sum;
|
131
|
-
double V_ratio = V / sum;
|
132
115
|
|
133
116
|
if (sum > 0) {
|
117
|
+
double U_ratio = U / sum;
|
118
|
+
double V_ratio = V / sum;
|
134
119
|
if (U > 0) {
|
135
120
|
p->U_pi = U_ratio * p->X[0] + V_ratio * p->X[1];
|
136
121
|
} else {
|
@@ -182,7 +167,7 @@ static inline void update_mig_just_rate(patch_t* restrict p) {
|
|
182
167
|
}
|
183
168
|
|
184
169
|
|
185
|
-
static inline uint8_t update_mig_weight_rate(patch_t* restrict p, uint8_t loc) {
|
170
|
+
static inline uint8_t update_mig_weight_rate(patch_t* restrict p, const uint8_t loc) {
|
186
171
|
// update migration weight as well as rates, in one direction
|
187
172
|
// used by neighbors of last-changed patches
|
188
173
|
// also used by last-changed patches themselve, when there are two patch changed, to update mig rates of in each other's direction
|
@@ -288,7 +273,7 @@ static inline uint8_t init_mig(patch_t* restrict p) {
|
|
288
273
|
|
289
274
|
|
290
275
|
|
291
|
-
static inline uint8_t find_event(const patch_t* restrict p, double expected_sum) {
|
276
|
+
static inline uint8_t find_event(const patch_t* restrict p, const double expected_sum) {
|
292
277
|
size_t event = 0;
|
293
278
|
double current_sum;
|
294
279
|
|
@@ -318,7 +303,7 @@ static inline uint8_t find_event(const patch_t* restrict p, double expected_sum)
|
|
318
303
|
}
|
319
304
|
|
320
305
|
|
321
|
-
static inline void change_popu(patch_t* restrict p, uint8_t s) {
|
306
|
+
static inline void change_popu(patch_t* restrict p, const uint8_t s) {
|
322
307
|
switch (s) {
|
323
308
|
case 0:
|
324
309
|
// Migration IN for U
|
@@ -360,8 +345,8 @@ static inline void change_popu(patch_t* restrict p, uint8_t s) {
|
|
360
345
|
* Main Simulation Functions
|
361
346
|
*/
|
362
347
|
|
363
|
-
static inline void find_patch(patch_picked_t* restrict picked, double expected_sum,
|
364
|
-
const double* restrict patch_rates, const double* restrict sum_rates_by_row, double sum_rates, size_t N, size_t M) {
|
348
|
+
static inline void find_patch(patch_picked_t* restrict picked, const double expected_sum,
|
349
|
+
const double* restrict patch_rates, const double* restrict sum_rates_by_row, const double sum_rates, const size_t N, const size_t M) {
|
365
350
|
double current_sum = 0;
|
366
351
|
size_t row = 0;
|
367
352
|
size_t col = 0;
|
@@ -416,7 +401,10 @@ static inline void find_patch(patch_picked_t* restrict picked, double expected_s
|
|
416
401
|
|
417
402
|
|
418
403
|
|
419
|
-
static inline void make_signal_zero_flux(size_t i, size_t j, uint8_t e, signal_t* restrict signal) {
|
404
|
+
static inline void make_signal_zero_flux(const size_t N, const size_t M, const size_t i, const size_t j, const uint8_t e, signal_t* restrict signal) {
|
405
|
+
// pass in N & M as well to match the param set of make_signal_periodical
|
406
|
+
(void) N;
|
407
|
+
(void) M;
|
420
408
|
// this is always the case for the first one
|
421
409
|
signal->i1 = i;
|
422
410
|
signal->j1 = j;
|
@@ -499,7 +487,7 @@ static inline void make_signal_zero_flux(size_t i, size_t j, uint8_t e, signal_t
|
|
499
487
|
|
500
488
|
|
501
489
|
|
502
|
-
static inline void make_signal_periodical(size_t N, size_t M, size_t i, size_t j, uint8_t e, signal_t* restrict signal) {
|
490
|
+
static inline void make_signal_periodical(const size_t N, const size_t M, const size_t i, const size_t j, const uint8_t e, signal_t* restrict signal) {
|
503
491
|
// this is always the case for the first one
|
504
492
|
signal->i1 = i;
|
505
493
|
signal->j1 = j;
|
@@ -1,4 +1,4 @@
|
|
1
|
-
__version__ = '2.3.
|
1
|
+
__version__ = '2.3.9'
|
2
2
|
|
3
3
|
'''
|
4
4
|
version history:
|
@@ -45,4 +45,5 @@ version history:
|
|
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
47
|
2.3.8: bug fix for 2.3.7 update.
|
48
|
+
2.3.9: now use xoshiro256+ as RNG.
|
48
49
|
'''
|
@@ -12,6 +12,7 @@ from . import simulation
|
|
12
12
|
import json
|
13
13
|
import gzip
|
14
14
|
import os
|
15
|
+
import numpy as np
|
15
16
|
|
16
17
|
|
17
18
|
def save(mod, dirs = '', print_msg = True):
|
@@ -46,7 +47,6 @@ def save(mod, dirs = '', print_msg = True):
|
|
46
47
|
inputs.append(mod.P.tolist())
|
47
48
|
inputs.append(mod.print_pct)
|
48
49
|
inputs.append(mod.seed)
|
49
|
-
inputs.append(mod.check_overflow)
|
50
50
|
data.append(inputs)
|
51
51
|
|
52
52
|
# skipped rng
|
@@ -54,11 +54,17 @@ def save(mod, dirs = '', print_msg = True):
|
|
54
54
|
outputs = []
|
55
55
|
outputs.append(mod.max_record)
|
56
56
|
outputs.append(mod.compress_itv)
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
57
|
+
if not mod.data_empty:
|
58
|
+
outputs.append(mod.U.tolist())
|
59
|
+
outputs.append(mod.V.tolist())
|
60
|
+
outputs.append(mod.Upi.tolist())
|
61
|
+
outputs.append(mod.Vpi.tolist())
|
62
|
+
else:
|
63
|
+
outputs.append(None)
|
64
|
+
outputs.append(None)
|
65
|
+
outputs.append(None)
|
66
|
+
outputs.append(None)
|
67
|
+
|
62
68
|
data.append(outputs)
|
63
69
|
|
64
70
|
data_dirs = os.path.join(dirs, 'data.json.gz')
|
@@ -96,16 +102,19 @@ def load(dirs):
|
|
96
102
|
try:
|
97
103
|
mod = simulation.model(N = data[0][0], M = data[0][1], maxtime = data[0][2], record_itv = data[0][3],
|
98
104
|
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 =
|
105
|
+
print_pct = data[0][9], seed = data[0][10], check_overflow = False)
|
100
106
|
except:
|
101
|
-
raise ValueError('Invalid input parameters
|
107
|
+
raise ValueError('Invalid input parameters stored in data')
|
102
108
|
|
103
109
|
# outputs
|
104
110
|
try:
|
105
111
|
mod.set_data(data_empty = False, max_record = data[1][0], compress_itv = data[1][1],
|
106
112
|
U = data[1][2], V = data[1][3], Upi = data[1][4], Vpi = data[1][5])
|
113
|
+
if (mod.U is None) or (isinstance(mod.U, np.ndarray) and mod.U.shape == () and mod.U.item() is None):
|
114
|
+
# if data is None
|
115
|
+
mod.data_empty = True
|
107
116
|
except:
|
108
|
-
raise ValueError('Invalid
|
117
|
+
raise ValueError('Invalid simulation results stored in data')
|
109
118
|
|
110
119
|
return mod
|
111
120
|
|
@@ -164,22 +164,11 @@ class model:
|
|
164
164
|
if check_overflow:
|
165
165
|
check_overflow_func(self)
|
166
166
|
|
167
|
-
|
168
|
-
|
167
|
+
# initialize storage bins.
|
168
|
+
self.set_data(data_empty = True, max_record = int(maxtime / record_itv), compress_itv = 1,
|
169
|
+
U = None, V = None, Upi = None, Vpi = None)
|
169
170
|
|
170
171
|
|
171
|
-
def init_storage(self):
|
172
|
-
# initialize storage bins
|
173
|
-
self.data_empty = True # whether data storage bins are empty. model.run will refuse to run (raise error) if not empty.
|
174
|
-
self.max_record = int(self.maxtime / self.record_itv) # int, how many data points to store sin total
|
175
|
-
self.compress_itv = 1 # int, intended to reduce size of data (if not 1). Updated by compress_data function
|
176
|
-
# if set to an int, say 20, mod will take average over every 20 data points and save them as new data.
|
177
|
-
# May be used over and over again to recursively reduce data size.
|
178
|
-
# Default is 1, not to take average.
|
179
|
-
self.U = None # initialized by simulation.run or data_tools.load
|
180
|
-
self.V = None
|
181
|
-
self.Upi = None
|
182
|
-
self.Vpi = None
|
183
172
|
|
184
173
|
|
185
174
|
def check_valid_input(self, N, M, maxtime, record_itv, sim_time, boundary, I, X, P, print_pct, seed, check_overflow):
|
@@ -319,6 +308,8 @@ class model:
|
|
319
308
|
|
320
309
|
if copy_data:
|
321
310
|
# copy data as well
|
311
|
+
if self.data_empty:
|
312
|
+
print("Warning: model has empty data")
|
322
313
|
sim2.set_data(self.data_empty, self.max_record, self.compress_itv, self.U, self.V, self.Upi, self.Vpi)
|
323
314
|
|
324
315
|
return sim2
|
@@ -93,7 +93,13 @@ class patch:
|
|
93
93
|
def set_nb_pointers(self, nb):
|
94
94
|
# nb is a list of pointers (point to patches)
|
95
95
|
# nb is passed from the model class
|
96
|
+
nb_count = 0
|
97
|
+
for nb_i in nb:
|
98
|
+
if nb_i != None:
|
99
|
+
nb_count += 1
|
96
100
|
self.nb = nb
|
101
|
+
self.mu1 *= (0.25 * nb_count)
|
102
|
+
self.mu2 *= (0.25 * nb_count)
|
97
103
|
|
98
104
|
|
99
105
|
def update_pi_k(self):
|
@@ -101,19 +107,21 @@ class patch:
|
|
101
107
|
|
102
108
|
U = self.U # bring the values to front
|
103
109
|
V = self.V
|
104
|
-
|
110
|
+
sum_UV = U + V # this value is used several times
|
105
111
|
|
106
|
-
if
|
112
|
+
if sum_UV > 0:
|
107
113
|
# interaction happens only if there is more than 1 individual
|
114
|
+
U_ratio = U / sum_UV
|
115
|
+
V_ratio = V / sum_UV
|
108
116
|
|
109
117
|
if U != 0:
|
110
118
|
# no payoff if U == 0
|
111
|
-
self.Upi =
|
119
|
+
self.Upi = U_ratio * self.matrix[0] + V_ratio * self.matrix[1]
|
112
120
|
else:
|
113
121
|
self.Upi = 0
|
114
122
|
|
115
123
|
if V != 0:
|
116
|
-
self.Vpi =
|
124
|
+
self.Vpi = U_ratio * self.matrix[2] + V_ratio * self.matrix[3]
|
117
125
|
else:
|
118
126
|
self.Vpi = 0
|
119
127
|
|
@@ -127,8 +135,8 @@ class patch:
|
|
127
135
|
self.pi_death_rates[1] = abs(V * self.Vpi)
|
128
136
|
|
129
137
|
# update natural death rates
|
130
|
-
self.pi_death_rates[2] = self.kappa1 * U *
|
131
|
-
self.pi_death_rates[3] = self.kappa2 * V *
|
138
|
+
self.pi_death_rates[2] = self.kappa1 * U * sum_UV
|
139
|
+
self.pi_death_rates[3] = self.kappa2 * V * sum_UV
|
132
140
|
|
133
141
|
# update sum of rates
|
134
142
|
self.sum_pi_death_rates = sum(self.pi_death_rates)
|
@@ -143,8 +151,8 @@ class patch:
|
|
143
151
|
|
144
152
|
for i in range(4):
|
145
153
|
if self.nb[i] != None:
|
146
|
-
U_weight[i] =
|
147
|
-
V_weight[i] =
|
154
|
+
U_weight[i] = pow(math.e, self.w1 * self.nb[i].Upi)
|
155
|
+
V_weight[i] = pow(math.e, self.w2 * self.nb[i].Vpi)
|
148
156
|
|
149
157
|
mu1_U = self.mu1 * self.U
|
150
158
|
mu2_V = self.mu2 * self.V
|
@@ -746,7 +754,7 @@ def single_test(mod, front_info, end_info, update_sum_frequency, rng):
|
|
746
754
|
|
747
755
|
|
748
756
|
|
749
|
-
def
|
757
|
+
def run(mod, predict_runtime = False, message = ''):
|
750
758
|
'''
|
751
759
|
Main function. Recursively calls single_test to run many models and then takes the average.
|
752
760
|
|
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
|