catalog.py
3.2 kB · python · 115 lines
1import os2import json3import time4from itertools import product, permutations5from .bang import (6 corners,7 code_to_filled,8 algebraic_degree,9 anf_string,10 genus,11 level_set,12 axis_pins,13)14from .complexity import measures1516# THE COMPLEXITY CATALOG - JOIN GEOMETRY TO COMPLEXITY ON THE FULL FINITE FAMILY1718def _perm_maps(dimension):19 cells = corners(dimension)20 index = {c: i for i, c in enumerate(cells)}21 maps = []22 for perm in permutations(range(dimension)):23 for flips in product((0, 1), repeat=dimension):24 m = [0] * len(cells)25 for i, c in enumerate(cells):26 image = tuple(c[perm[k]] ^ flips[k] for k in range(dimension))27 m[i] = index[image]28 maps.append(tuple(m))29 return maps, cells3031def _orbit(code, maps, ncorners):32 images = set()33 for m in maps:34 v = 035 c = code36 i = 037 while c:38 if c & 1:39 v |= 1 << m[i]40 c >>= 141 i += 142 images.add(v)43 return images4445def canonical_codes(dimension):46 maps, cells = _perm_maps(dimension)47 ncorners = len(cells)48 total = 1 << ncorners49 seen = bytearray(total)50 reps = []51 orbit_sizes = {}52 for code in range(total):53 if seen[code]:54 continue55 orbit = _orbit(code, maps, ncorners)56 rep = min(orbit)57 for v in orbit:58 seen[v] = 159 reps.append(rep)60 orbit_sizes[rep] = len(orbit)61 return sorted(reps), maps, cells, orbit_sizes6263def _width(dimension):64 return len(str((1 << (1 << dimension)) - 1))6566def _design_row(code, cells, dimension, orbit_size):67 filled = code_to_filled(code, cells)68 ls = level_set(filled, cells)69 ax = axis_pins(filled, cells)70 m = measures(filled, cells)71 fp = m.pop("fill_fingerprint")72 row = {73 "name": f"mrly_{code:0{_width(dimension)}d}",74 "i": code,75 "dimension": dimension,76 "genus": genus(filled, cells),77 "gf2_degree": algebraic_degree(filled, cells),78 "level_set_S": list(ls) if ls is not None else None,79 "axis_pins": list(ax) if ax is not None else None,80 "anf": anf_string(filled, cells),81 "orbit_size": orbit_size,82 "fill_fingerprint": [str(x) for x in fp],83 }84 row.update(m)85 return row8687def build(dimension):88 reps, maps, cells, orbit_sizes = canonical_codes(dimension)89 rows = []90 for code in reps:91 rows.append(_design_row(code, cells, dimension, orbit_sizes[code]))92 return rows9394def write_catalog(dimension, directory):95 rows = build(dimension)96 os.makedirs(directory, exist_ok=True)97 path = os.path.join(directory, f"complexity_{dimension}d.json")98 with open(path, "w") as fh:99 json.dump(rows, fh, indent=2)100 return path, rows101102def load_catalog(dimension, directory):103 path = os.path.join(directory, f"complexity_{dimension}d.json")104 with open(path) as fh:105 return json.load(fh)106107def _data_dir():108 return os.path.join(os.path.dirname(__file__), "data")109110if __name__ == "__main__":111 here = _data_dir()112 for D in (3, 4):113 t0 = time.time()114 path, rows = write_catalog(D, here)115 print(f"D={D}: {len(rows)} designs -> {path} ({round(time.time()-t0,1)}s)")