diff --git a/clifford.py b/clifford.py index 452c355..25a5c93 100644 --- a/clifford.py +++ b/clifford.py @@ -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 from tqdm import tqdm -import os from qi import * -import cPickle +from functools import reduce +from util import cache_to_disk + def find_up_to_phase(u): """ 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 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 raise IndexError @@ -20,30 +27,20 @@ def compose_u(decomposition): return np.matrix(reduce(np.dot, us), dtype=complex) +@cache_to_disk("tables.pkl") 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} 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() diff --git a/util.py b/util.py new file mode 100644 index 0000000..3886083 --- /dev/null +++ b/util.py @@ -0,0 +1,17 @@ +""" +Provides a decorator to cache function output to disk +""" +import cPickle + +def cache_to_disk(file_name): + def wrap(func): + def modified(*args, **kwargs): + try: + output = cPickle.load(open(file_name, "r")) + except (IOError, ValueError): + output = func(*args, **kwargs) + with open(file_name, "w") as f: + cPickle.dump(output, f) + return output + return modified + return wrap