-
Notifications
You must be signed in to change notification settings - Fork 0
/
voter.py
63 lines (48 loc) · 1.76 KB
/
voter.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
import numpy as np
def initialize_state(grid_size, rng):
"""Initialize voter model with an aligned spin grid.
Input:
grid_size:
Length of the side of a square lattice.
rng:
numpy Random Generator (or compatible) object.
Output:
Two dimensional array of [grid_size x grid_size] size filled with
all values either 1 or -1.
"""
if rng.random() < 0.5:
return -np.ones((grid_size, grid_size))
return np.ones((grid_size, grid_size))
def _get_neighbor(state, pos, rng):
"""Get a state of random neighbor from four cardinal neighbors."""
grid_size = state.shape[0]
neigh = pos.copy()
# random cardinal direction
axis = [0, 1][rng.random() < 0.5]
dir = [-1, 1][rng.random() < 0.5]
# pick wraping around the border
neigh[axis] = (neigh[axis] + dir) % grid_size
return state[neigh[0], neigh[1]]
def update_state_voter(state, prob, rng):
"""Update state according to noisy voter model.
Input:
state:
Square [N x N] array encoding the state of the Ising model.
prob:
Probability that selected agent will act randomly instead
of immitating.
rng:
numpy Random Generator (or compatible) object.
Output:
Updated state of the model (square [N x N] array) after N**2 MC
steps.
"""
grid_size = state.shape[0]
n_steps = grid_size**2
for _ in range(n_steps):
pos = rng.integers(0, grid_size, size=2)
if rng.random() < prob:
state[pos[0], pos[1]] = [-1, 1][rng.random() < 0.5]
else:
state[pos[0], pos[1]] = _get_neighbor(state, pos, rng)
return state