Skip to content

Commit e20440c

Browse files
authored
Merge pull request #13 from gjbex/development
Development
2 parents d701b23 + 137bc83 commit e20440c

File tree

2 files changed

+92
-0
lines changed

2 files changed

+92
-0
lines changed

Diff for: source-code/profiling/README.md

+1
Original file line numberDiff line numberDiff line change
@@ -21,3 +21,4 @@ functions use memory.
2121
of time.
2222
1. `run_memory_prof.sh`: Bash shell script to create a memory profile.
2323
Note that this generates a lot of overhead in terms of CPU time.
24+
1. `cellular_automata.py`: example code to illustrate snakeviz.

Diff for: source-code/profiling/cellular_automata.py

+91
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
#!/usr/bin/env python
2+
# coding: utf-8
3+
4+
# # Requirements
5+
6+
import argparse
7+
import random
8+
import sys
9+
10+
# # Implementation
11+
12+
# First we define a class to evolve the cellular autotomaton. A runner is created for a specific rule, specified by a number between 0 and 255. For instance, rule 47 would translate to:
13+
# * $000 \mapsto 1$
14+
# * $001 \mapsto 1$
15+
# * $010 \mapsto 1$
16+
# * $011 \mapsto 1$
17+
# * $100 \mapsto 0$
18+
# * $101 \mapsto 1$
19+
# * $110 \mapsto 0$
20+
# * $111 \mapsto 0$
21+
22+
class AutomatonRunner:
23+
24+
def __init__(self, rule_nr):
25+
self._compute_rules(rule_nr)
26+
27+
def _compute_rules(self, rule_nr):
28+
self._rules = []
29+
for _ in range(8):
30+
self._rules.append(rule_nr % 2)
31+
rule_nr //= 2
32+
33+
def _apply_rule(self, environment):
34+
env_nr = 4*environment[0] + 2*environment[1] + environment[2]
35+
return self._rules[env_nr]
36+
37+
def _make_environment(self, automaton, i):
38+
if 0 < i < len(automaton) - 1:
39+
return automaton[i - 1:i + 2]
40+
elif i == 0:
41+
return [automaton[-1]] + automaton[:2]
42+
elif i == len(automaton) - 1:
43+
return automaton[i - 1:] + [automaton[0]]
44+
45+
def next_generation(self, automaton):
46+
ng_automaton = []
47+
for i in range(len(automaton)):
48+
environment = self._make_environment(automaton, i)
49+
ng_automaton.append(self._apply_rule(environment))
50+
return ng_automaton
51+
52+
def evolve(self, automaton, nr_generations):
53+
generations = [automaton]
54+
for _ in range(nr_generations):
55+
generations.append(self.next_generation(generations[-1]))
56+
return generations
57+
58+
def __str__(self):
59+
auto_str = ''
60+
for i, result in enumerate(self._rules):
61+
auto_str += f'{i//4 % 2}{i//2 % 2}{i % 2} -> {result}\n'
62+
return auto_str
63+
64+
65+
def automaton2str(automaton):
66+
return ''.join(str(c) for c in automaton).replace('0', ' ').replace('1', 'X')
67+
68+
69+
if __name__ == '__main__':
70+
arg_parser = argparse.ArgumentParser(description='run cellular automaton')
71+
arg_parser.add_argument('--nr_cells', type=int, default=10,
72+
help='number of cells in automaton')
73+
arg_parser.add_argument('--nr_steps', type=int, default=50,
74+
help='number of evolution steps')
75+
arg_parser.add_argument('--rule_nr', type=int, default=129,
76+
help='number between 0 and 255 that defines the rul')
77+
arg_parser.add_argument('--seed', type=int, help='random number generator seed')
78+
arg_parser.add_argument('--verbose', action='store_true',
79+
help='verbose output for debugging')
80+
options = arg_parser.parse_args()
81+
if options.seed:
82+
random.seed(options.seed)
83+
runner = AutomatonRunner(options.rule_nr)
84+
if options.verbose:
85+
print(runner, file=sys.stderr)
86+
automaton = random.choices((0, 1), k=options.nr_cells)
87+
if options.verbose:
88+
print(automaton2str(automaton), file=sys.stderr)
89+
generations = runner.evolve(automaton, options.nr_steps)
90+
for generation in generations:
91+
print(automaton2str(generation))

0 commit comments

Comments
 (0)