Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
632 changes: 632 additions & 0 deletions research/bit-three-register-lower-bound/README.md

Large diffs are not rendered by default.

185 changes: 185 additions & 0 deletions research/bit-three-register-lower-bound/catalogue.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,185 @@
"""Enumerate the complete scalar catalogue with explicit binary subspaces."""

from collections import Counter
from itertools import combinations, combinations_with_replacement, permutations, product
from math import factorial, prod
from pathlib import Path
import argparse
import json

VECTORS = tuple(product(range(2), repeat=3))
POSITIONS = ((0, 1), (0, 2), (1, 0), (1, 2), (2, 0), (2, 1))


def xor(a, b):
return tuple(x ^ y for x, y in zip(a, b))


def closure(vectors, zero):
space = {zero}
for vector in vectors:
space.update([xor(vector, other) for other in space])
return frozenset(space)


def multiply(a, b):
return tuple(sum(a[3 * i + k] * b[3 * k + j] for k in range(3)) % 2
for i in range(3) for j in range(3))


def action(matrix, vector):
return tuple(sum(matrix[3 * i + j] * vector[j] for j in range(3)) % 2
for i in range(3))


def encode(matrix):
return sum(value << i for i, value in enumerate(matrix))


def off(matrix):
return tuple(matrix[3 * i + j] for i, j in POSITIONS)


def transpose(matrix):
return tuple(matrix[3 * j + i] for i in range(3) for j in range(3))


def conjugate(matrix, permutation):
return tuple(matrix[3 * permutation[i] + permutation[j]]
for i in range(3) for j in range(3))


def catalogue():
projectors = tuple(sorted(
(matrix for matrix in product(range(2), repeat=9)
if len({action(matrix, v) for v in VECTORS}) == 2
and multiply(matrix, matrix) == matrix), key=encode))
by_code = {encode(matrix): matrix for matrix in projectors}
patterns = set(map(off, projectors)) - {(0,) * 6}
lines = [frozenset(((0, 0, 0), v)) for v in VECTORS[1:]]
planes = {closure((v, w), (0, 0, 0)) for v, w in combinations(VECTORS[1:], 2)}
subspaces = set(lines) | planes
flags = [(line, plane) for line in lines for plane in planes if line <= plane]
invariant = {matrix: {space for space in subspaces
if all(action(matrix, v) in space for v in space)}
for matrix in projectors}

def preserved(pool):
return set.intersection(subspaces, *(invariant[matrix] for matrix in pool))

def has_flag(pool):
common = preserved(pool)
return any(line in common and plane in common for line, plane in flags)

def transforms(pool):
return [tuple(encode(conjugate(transpose(matrix) if turn else matrix, permutation))
for matrix in pool)
for permutation in permutations(range(3)) for turn in (False, True)]

spaces = {frozenset(((0,) * 6,))}
for _ in range(3):
spaces |= {closure(tuple(space) + (pattern,), (0,) * 6)
for space in spaces for pattern in patterns}
records = []
for space in spaces:
pool = tuple(matrix for matrix in projectors if off(matrix) in space)
noncoordinate = tuple(matrix for matrix in pool if any(off(matrix)))
records.append((len(space).bit_length() - 1, pool, noncoordinate))

# This complete classification is the finite step in the span-six proof.
exceptions = []
for dimension, _, pool in records:
if dimension == 2 and not has_flag(pool):
assert len(pool) == 3
assert all(has_flag(pool[:i] + pool[i + 1:]) for i in range(3))
exceptions.append(tuple(sorted(map(encode, pool))))
representative = tuple(by_code[code] for code in (3, 18, 360))
expected_exceptions = {tuple(sorted(encode(conjugate(matrix, permutation))
for matrix in representative))
for permutation in permutations(range(3))}
assert set(exceptions) == expected_exceptions and len(exceptions) == 6
basis = (1, 1, 0, 0, 1, 0, 0, 0, 1)
assert [encode(multiply(multiply(basis, matrix), basis))
for matrix in representative] == [1, 16, 511]

canonical = {min(tuple(sorted(row)) for row in transforms(pool)): dimension
for dimension, pool, _ in records}
counts = Counter()
passing = []
dimensions = Counter()
for key, dimension in sorted(canonical.items(), key=lambda item: (item[1], item[0])):
if dimension == 0:
continue
pool = tuple(by_code[code] for code in key)
stabilizers = [tuple(key.index(code) for code in row)
for row in transforms(pool) if set(row) == set(key)]
support_cache = {}
# Precompute the seven row and seven column incidence tests.
incidence = []
for vector in VECTORS[1:]:
for turn in (False, True):
images = []
for matrix in pool:
matrix = transpose(matrix) if turn else matrix
image = next(action(matrix, v) for v in VECTORS if any(action(matrix, v)))
images.append(sum(a * b for a, b in zip(vector, image)) % 2)
incidence.append(images)
for gates in combinations_with_replacement(range(len(pool)), 8):
support = tuple(sorted(set(gates)))
if support not in support_cache:
occurring = tuple(pool[i] for i in support)
full = len(closure(map(off, occurring), (0,) * 6)) == 2 ** dimension
irreducible = not preserved(occurring)
flag = dimension < 3 or not has_flag(tuple(m for m in occurring if any(off(m))))
support_cache[support] = full, irreducible, flag
full, irreducible, flag = support_cache[support]
if not full:
continue
counts['full_rank_multiplicities'] += 1
if not irreducible:
continue
counts['irreducible'] += 1
if not flag:
continue
counts['nonzero_flag_pass'] += 1
multiplicity = tuple(gates.count(i) for i in range(len(pool)))
if any(sum(a * b for a, b in zip(multiplicity, row)) < 3 for row in incidence):
continue
counts['distance_pass'] += 1
variants = []
for symmetry in stabilizers:
transformed = [0] * len(pool)
for i, j in enumerate(symmetry):
transformed[j] = multiplicity[i]
variants.append(tuple(transformed))
if multiplicity != min(variants):
continue
counts['canonical_pass'] += 1
dimensions[dimension] += 1
passing.append(tuple(key[i] for i in gates))
passing.sort()
assert len(passing) == len(set(passing))
summary = {
'projectors': len(projectors), 'nonzero_patterns': len(patterns),
'pattern_spaces': dict(sorted(Counter(dimension for dimension, _, _ in records).items())),
'complete_flags': len(flags), 'plane_exceptions': len(exceptions),
'canonical_pools': len(canonical), 'filter_counts': dict(counts),
'families_by_dimension': dict(sorted(dimensions.items())), 'families': len(passing),
'orders': sum(factorial(8) // prod(factorial(c) for c in Counter(word).values())
for word in passing),
}
return passing, summary


def main():
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument('output', type=Path)
args = parser.parse_args()
words, summary = catalogue()
args.output.write_text(str(len(words)) + '\n' + ''.join(
' '.join(map(str, (index, *word))) + '\n' for index, word in enumerate(words)))
print(json.dumps(summary, indent=2))


if __name__ == '__main__':
main()
89 changes: 89 additions & 0 deletions research/bit-three-register-lower-bound/controls.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
"""Check formal identities and the full-rank target boundary independently."""

from fractions import Fraction
from itertools import combinations

from catalogue import multiply

IDENTITY = (1, 0, 0, 0, 1, 0, 0, 0, 1)
ZERO = (0,) * 9


def unit(row, column):
return tuple(int((i, j) == (row, column)) for i in range(3) for j in range(3))


def rank(rows):
rows = [list(map(Fraction, row)) for row in rows]
result = 0
for column in range(len(rows[0])):
pivot = next((i for i in range(result, len(rows)) if rows[i][column]), None)
if pivot is None:
continue
rows[result], rows[pivot] = rows[pivot], rows[result]
scale = rows[result][column]
rows[result] = [x / scale for x in rows[result]]
for i in range(result + 1, len(rows)):
scale = rows[i][column]
rows[i] = [x - scale * y for x, y in zip(rows[i], rows[result])]
result += 1
if result == len(rows):
break
return result


def matrix_rank(matrix):
return rank([matrix[3 * row:3 * row + 3] for row in range(3)])


def formal_product(operations):
terms = {ZERO: IDENTITY}
for frame, projector in operations:
updated = {}
complement = tuple(x ^ y for x, y in zip(IDENTITY, projector))
for address, coefficient in terms.items():
for shift, scalar in ((ZERO, complement), (frame, projector)):
exponent = tuple(x + y for x, y in zip(address, shift))
matrix = multiply(coefficient, scalar)
previous = updated.get(exponent, ZERO)
updated[exponent] = tuple(x ^ y for x, y in zip(previous, matrix))
terms = {address: matrix for address, matrix in updated.items() if any(matrix)}
return terms


def scalar(code):
return tuple((code >> i) & 1 for i in range(9))


def check_formal_controls():
baseline = [(unit(i, i), unit(w, w)) for w in range(3) for i in range(3)]
assert formal_product(baseline) == {IDENTITY: IDENTITY}
# This rank-one address change is hidden by an invalid reduction modulo two.
alias = [(tuple(3 * x for x in baseline[0][0]), baseline[0][1]), *baseline[1:]]
assert formal_product(alias) != {IDENTITY: IDENTITY}
assert formal_product([(tuple(x % 2 for x in frame), projector)
for frame, projector in alias]) == {IDENTITY: IDENTITY}

e00, e11, e22, e10, e01 = (unit(i, j) for i, j in ((0, 0), (1, 1), (2, 2), (1, 0), (0, 1)))
plus = lambda a, b: tuple(x + y for x, y in zip(a, b))
minus = lambda a, b: tuple(x - y for x, y in zip(a, b))
frames = [e22, e00, e11, plus(e00, e10), minus(e11, e10),
plus(e00, e01), minus(e11, e01), tuple(-x for x in e22)]
projectors = list(map(scalar, (3, 1, 1, 16, 16, 256, 256, 3)))
assert all(matrix_rank(frame) == 1 for frame in frames)
assert all(matrix_rank(projector) == 1 and multiply(projector, projector) == projector
for projector in projectors)
assert any(multiply(a, b) != multiply(b, a) for a, b in combinations(projectors, 2))
assert rank(frames) == 5
target = plus(e00, e11)
assert matrix_rank(target) == 2
assert formal_product(list(zip(frames, projectors))) == {target: IDENTITY}
return {'nine_call_identity': True, 'modular_alias_rejected': True,
'noncommuting_eight_call_identity': True, 'frame_span': 5, 'target_rank': 2}


# These are search-core controls, not admissible constructions. Code 17 is
# a rank-two scalar projector. A real accepted core example detects a checker
# that rejects every terminal; the mutation removes one target contribution.
CORE_WORDS = ((3, 3, 17, 17, 17, 256, 256, 256),
(3, 3, 17, 17, 1, 256, 256, 256))
23 changes: 23 additions & 0 deletions research/bit-three-register-lower-bound/expected.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"projectors": 28,
"nonzero_patterns": 19,
"pattern_spaces": {
"0": 1,
"1": 19,
"2": 129,
"3": 363
},
"complete_flags": 21,
"plane_exceptions": 6,
"canonical_pools": 67,
"families_by_dimension": {
"1": 4,
"2": 137,
"3": 2135
},
"families": 2276,
"orders": 21317520,
"diagonal_terminals": 415398,
"survivors": 0,
"catalogue_sha256": "8be9e2582199e127b061942cf0fba9156b7560312f20a87dc184fe0010d7cead"
}
Loading