|
@@ -1,15 +1,22 @@ |
|
|
|
|
|
""" |
|
|
|
|
|
Enumerates the 24 elements of the local Clifford group, providing multiplication and conjugation tables |
|
|
|
|
|
permutations = (id, ha, ph, ha*ph, ha*ph*ha, ha*ph*ha*ph) |
|
|
|
|
|
signs = (id, px, py, pz) |
|
|
|
|
|
unitaries = [p*s for p in permutations for s in signs] |
|
|
|
|
|
""" |
|
|
|
|
|
|
|
|
import numpy as np |
|
|
import numpy as np |
|
|
from tqdm import tqdm |
|
|
from tqdm import tqdm |
|
|
import os |
|
|
|
|
|
from qi import * |
|
|
from qi import * |
|
|
import cPickle |
|
|
|
|
|
|
|
|
from functools import reduce |
|
|
|
|
|
from util import cache_to_disk |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def find_up_to_phase(u): |
|
|
def find_up_to_phase(u): |
|
|
""" Find the index of a given u within a list of unitaries, up to a global phase """ |
|
|
""" Find the index of a given u within a list of unitaries, up to a global phase """ |
|
|
global unitaries |
|
|
|
|
|
for i, t in enumerate(unitaries): |
|
|
for i, t in enumerate(unitaries): |
|
|
for phase in range(8): |
|
|
for phase in range(8): |
|
|
if np.allclose(t, np.exp(1j*phase*np.pi/4.)*u): |
|
|
|
|
|
|
|
|
if np.allclose(t, np.exp(1j * phase * np.pi / 4.) * u): |
|
|
return i, phase |
|
|
return i, phase |
|
|
raise IndexError |
|
|
raise IndexError |
|
|
|
|
|
|
|
@@ -20,30 +27,20 @@ def compose_u(decomposition): |
|
|
return np.matrix(reduce(np.dot, us), dtype=complex) |
|
|
return np.matrix(reduce(np.dot, us), dtype=complex) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@cache_to_disk("tables.pkl") |
|
|
def construct_tables(): |
|
|
def construct_tables(): |
|
|
""" Constructs multiplication and conjugation tables """ |
|
|
|
|
|
conjugation_table = [find_up_to_phase(u.H)[0] for i, u in enumerate(unitaries)] |
|
|
|
|
|
times_table = [[find_up_to_phase(u*v)[0] for v in unitaries] |
|
|
|
|
|
for u in tqdm(unitaries, "Building times-table")] |
|
|
|
|
|
with open("tables.pkl", "w") as f: |
|
|
|
|
|
cPickle.dump((conjugation_table, times_table), f) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#permutations = (id, ha, ph, ha*ph, ha*ph*ha, ha*ph*ha*ph) |
|
|
|
|
|
#signs = (id, px, py, pz) |
|
|
|
|
|
#unitaries = [p*s for p in permutations for s in signs] |
|
|
|
|
|
decompositions = \ |
|
|
|
|
|
("xxxx", "xx", "zzxx", "zz", "zxx", "z", "zzz", "xxz", |
|
|
|
|
|
"xzx", "xzxxx", "xzzzx", "xxxzx", "xzz", "zzx", "xxx", "x", |
|
|
|
|
|
"zzzx", "xxzx", "zx", "zxxx", "xxxz", "xzzz", "xz", "xzxx") |
|
|
|
|
|
|
|
|
""" Constructs / caches multiplication and conjugation tables """ |
|
|
|
|
|
conjugation_table = [find_up_to_phase(u.H)[0] |
|
|
|
|
|
for i, u in enumerate(unitaries)] |
|
|
|
|
|
times_table = [[find_up_to_phase(u * v)[0] for v in unitaries] |
|
|
|
|
|
for u in tqdm(unitaries)] |
|
|
|
|
|
return conjugation_table, times_table |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# Various useful tables |
|
|
|
|
|
decompositions = ("xxxx", "xx", "zzxx", "zz", "zxx", "z", "zzz", "xxz", |
|
|
|
|
|
"xzx", "xzxxx", "xzzzx", "xxxzx", "xzz", "zzx", "xxx", "x", |
|
|
|
|
|
"zzzx", "xxzx", "zx", "zxxx", "xxxz", "xzzz", "xz", "xzxx") |
|
|
elements = {"x": sqx, "z": msqz} |
|
|
elements = {"x": sqx, "z": msqz} |
|
|
unitaries = [compose_u(d) for d in decompositions] |
|
|
unitaries = [compose_u(d) for d in decompositions] |
|
|
|
|
|
|
|
|
# Build / reload lookup tables |
|
|
|
|
|
if not os.path.exists("tables.pkl"): |
|
|
|
|
|
construct_tables() |
|
|
|
|
|
with open("tables.pkl") as f: |
|
|
|
|
|
conjugation_table, times_table = cPickle.load(f) |
|
|
|
|
|
|
|
|
|
|
|
if __name__ == '__main__': |
|
|
|
|
|
pass |
|
|
|
|
|
|
|
|
conjugation_table, times_table = construct_tables() |