-
Notifications
You must be signed in to change notification settings - Fork 7
/
Copy pathSmallWorldCA.py
132 lines (98 loc) · 4.64 KB
/
SmallWorldCA.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
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
'''
Created on Feb 3, 2018
@author: aditya
This class can be used to generate spatio temporal patterns of 1D cellular automata
'''
import numpy as np
class CA_SmallWorld:
def __init__(self, rule, p = 1, q = 0.1, world_size = 1080, lifespan = 1920, config = 'regular'):
self.rule = np.array([int(i) for i in '{:08b}'.format(rule)])
self.height_img = world_size
self.width_img = lifespan
self.X = np.zeros((world_size, lifespan), dtype = int)
self.gates = np.zeros(world_size, dtype=int)
self.p = p
self.q = q
if config not in ['regular', 'random']:
raise ValueError('Configurations not present in available options:[\'regular\', \'random\', \'smallworld\']')
self.config = config
# neighbors for periodic boundary conditions
self.left = [world_size-1]+[i for i in range(world_size-1)]
self.right = [i for i in range(1, world_size)]+[0]
self.setup()
def resetworld(self):
self.X = np.zeros((self.height_img, self.width_img), dtype = int)
self.setup()
def setup(self):
if self.config=='regular':
start_life = [i for i in range(int(self.height_img/2-len(self.rule)/2),int(self.height_img/2+len(self.rule)/2))]
self.X[start_life,0]=1
else:
p = np.random.rand(self.height_img)
self.X[p>0.5,0] = 1
def simulation(self):
# This method takes care of cellular automata with given rule and randomness
# Main Logic
for t in range(self.width_img):
world = self.X[:, t]
p_t, q_t = np.random.rand(self.height_img), np.random.rand(self.height_img)
self.gates[p_t<=self.p] = 1
world_future_1 = 4*world[self.left] + 2*world + world[self.right]
world_future_1 = self.rule[world_future_1.astype(int)]
world_future_1 = np.multiply(world_future_1, self.gates)
world_future_2 = np.zeros(self.height_img, dtype=int)
world_future_2[q_t<=self.q]=1
world_future_2 = np.multiply(world_future_2, np.logical_not(self.gates))
world = world_future_1 + world_future_2
if t+1>=self.width_img: break
self.X[:,t+1] = world
image = np.multiply(self.X,255)
image = image.astype(np.uint8)
self.resetworld()
return image
def smallworld(self, f = 0.1):
# This method takes care of small world simulation
left, right = self.setneighbor_smallworld(f)
# Main Logic
for t in range(self.width_img):
world = self.X[:, t]
p_t, q_t = np.random.rand(self.height_img), np.random.rand(self.height_img)
self.gates[p_t<=self.p] = 1
world_future_1 = 4*world[left] + 2*world + world[right]
world_future_1 = self.rule[world_future_1.astype(int)]
world_future_1 = np.multiply(world_future_1, self.gates)
world_future_2 = np.zeros(self.height_img, dtype=int)
world_future_2[q_t<=self.q]=1
world_future_2 = np.multiply(world_future_2, np.logical_not(self.gates))
world = world_future_1 + world_future_2
if t+1>=self.width_img: break
self.X[:,t+1] = world
image = np.multiply(self.X,255)
image = image.astype(np.uint8)
self.resetworld()
return image
def setneighbor_smallworld(self, f):
# randomizing the neighborhood for small world
left = self.left
right = self.right
for i in range(self.height_img):
rand = np.random.rand(2)
if rand[0]<f and rand[1]<0.5:
left[i] = np.random.randint(self.height_img)
elif rand[0]<f and rand[1]>0.5:
right[i] = np.random.randint(self.height_img)
return left, right
if __name__=='__main__':
import matplotlib.pyplot as plt
RULE = 129
CA = CA_SmallWorld(RULE)
image1 = CA.simulation()
im = plt.imshow(image1)
plt.xticks([]), plt.yticks([])
plt.title('Rule {}'.format(RULE))
plt.show()
image2 = CA.smallworld()
im = plt.imshow(image2)
plt.xticks([]), plt.yticks([])
plt.title('Small World Network - Rule {}'.format(RULE))
plt.show()