forked from PlantSimLab/ADAM
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcycle_length_analysis.py
More file actions
86 lines (78 loc) · 2.75 KB
/
cycle_length_analysis.py
File metadata and controls
86 lines (78 loc) · 2.75 KB
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
import json
import itertools as it
import tempfile as tmpf
import subprocess as sp
import csv
from datetime import datetime, timezone
BITS=[1]
LATTICE=list(range(41))
ADAM_LIMIT_CYCLE_SCRIPT = "~/ADAM/lib/M2code/limitCycles"
OUTPUT_FILE = "./adam_cpu.csv"
def generate_ca_rules(states: int, neighborhood: int = 3):
"""Generate all possible cellular automaton rules for a given number of states and neighborhood size."""
yield from it.product(range(states), repeat=neighborhood)
def build_json_model(states: int, l: int, r: tuple) -> str:
states = [f"{i}" for i in range(states)]
variables = list()
updateRules = {}
for i in range(0, l+0):
variables.append(
{
"name:": f"x{i}",
"id": f"x{i}",
"states": states
}
)
updateRules[f"x{i}"] = {
f"x{i}": {
"polynomialFunction": f"{r[0]}*x{(i-1)%l}+{r[1]}*x{i}+{r[2]}*x{(i+1)%l}"
}
}
model = {
"model": {
"variables": variables,
"updateRules": updateRules
}
}
return json.dumps(model, indent=2)
def run_adam(states: int, lattice_size: int, model_json: str) -> list[float]:
total_states = states**lattice_size
next_cl = 1
max_cl = total_states
cycle_lengths = []
total_time = 0
while next_cl <= max_cl:
with tmpf.NamedTemporaryFile(mode="w", suffix=".json", delete=True) as tmp:
tmp.write(model_json)
tmp.flush()
output = sp.run(
[ADAM_LIMIT_CYCLE_SCRIPT, tmp.name],
capture_output=True,
text=True,
check=True
)
result = json.loads(output.stdout)
lc = result["output"]["limitcycles"]
if len(lc) > 0:
cycle_lengths.append(next_cl)
max_cl -= len(lc) * next_cl
total_time += float(result["output"]["time"])
next_cl += 1
return {"sol": cycle_lengths, "time": total_time}
def main():
with open(OUTPUT_FILE, "w") as csvfile:
writer = csv.writer(csvfile)
for l in LATTICE:
for b in BITS:
states = 2^b
for r in generate_ca_rules(states, 3):
print(
f"{datetime.now(tz=timezone.utc).time().strftime("%H:%M:%S")}: "
f"Lattice: {l}, States: {states}, Rule: {r}"
)
model_json = build_json_model(states, l, r)
adam_results = run_adam(states, l, model_json)
row = {"bits": b, "size": l, "neighborhood": 3, "rule": str(r), **adam_results, "total_time": True}
writer.writerow(row)
if __name__ == "__main__":
main()