| @@ -0,0 +1,229 @@ | |||||
| """ | |||||
| This program computes lookup tables and stores them as tables.py and tables.js | |||||
| # TODO: clifford naming discrepancy | |||||
| """ | |||||
| import numpy as np | |||||
| from tqdm import tqdm | |||||
| import itertools as it | |||||
| from functools import reduce | |||||
| from os.path import dirname, join, split | |||||
| import json | |||||
| import qi, clifford | |||||
| 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") | |||||
| JS_TEMPLATE = """\ | |||||
| var tables = {{ | |||||
| decompositions : {decompositions}, | |||||
| conjugation_table : {conjugation_table}, | |||||
| times_table : {times_table}, | |||||
| cz_table : {cz_table}, | |||||
| clifford : {by_name}, | |||||
| measurement_table_real : {measurement_table_real}, | |||||
| measurement_table_imag : {measurement_table_imag} | |||||
| }}; | |||||
| """ | |||||
| PY_TEMPLATE = """\ | |||||
| import numpy as np | |||||
| # Define lookup tables | |||||
| ir2 = 1/np.sqrt(2) | |||||
| decompositions = {decompositions} | |||||
| conjugation_table = np.array({conjugation_table}, dtype=int) | |||||
| times_table = np.array({times_table}, dtype=int) | |||||
| cz_table = np.array({cz_table}, dtype=int) | |||||
| by_name = {by_name} | |||||
| measurement_table_real = np.array({measurement_table_real}, dtype=complex) | |||||
| measurement_table_imag = np.array({measurement_table_imag}, dtype=complex) | |||||
| unitaries_real = np.array({unitaries_real}, dtype=complex) | |||||
| unitaries_imag = np.array({unitaries_imag}, dtype=complex) | |||||
| # Reconstruct | |||||
| measurement_table = measurement_table_real + 1j*measurement_table_imag | |||||
| unitaries = unitaries_real + 1j*unitaries_imag | |||||
| """ | |||||
| def find_clifford(needle, haystack): | |||||
| """ Find the index of a given u within a list of unitaries, up to a global phase """ | |||||
| needle = qi.normalize_global_phase(needle) | |||||
| for i, t in enumerate(haystack): | |||||
| if np.allclose(t, needle): | |||||
| return i | |||||
| raise IndexError | |||||
| def find_cz(bond, c1, c2, commuters, state_table): | |||||
| """ Find the output of a CZ operation """ | |||||
| # Figure out the target state | |||||
| target = qi.cz.dot(state_table[bond, c1, c2]) | |||||
| target = qi.normalize_global_phase(target) | |||||
| # Choose the sets to search over | |||||
| s1 = commuters if c1 in commuters else xrange(24) | |||||
| s2 = commuters if c2 in commuters else xrange(24) | |||||
| # Find a match | |||||
| for bondp, c1p, c2p in it.product([0, 1], s1, s2): | |||||
| if np.allclose(target, state_table[bondp, c1p, c2p]): | |||||
| return bondp, c1p, c2p | |||||
| # Didn't find anything - this should never happen | |||||
| raise IndexError | |||||
| def compose_u(decomposition): | |||||
| """ Get the unitary representation of a particular decomposition """ | |||||
| matrices = ({"x": qi.msqx, "z": qi.sqz}[c] for c in decomposition) | |||||
| output = reduce(np.dot, matrices, np.eye(2, dtype=complex)) | |||||
| return qi.normalize_global_phase(output) | |||||
| def get_unitaries(): | |||||
| """ The Clifford group """ | |||||
| return [compose_u(d) for d in DECOMPOSITIONS] | |||||
| def get_by_name(unitaries): | |||||
| """ Get a lookup table of cliffords by name """ | |||||
| a = {name: find_clifford(u, unitaries) | |||||
| for name, u in qi.by_name.items()} | |||||
| a.update({clifford.get_name(i): i for i in range(24)}) | |||||
| a.update({i: i for i in range(24)}) | |||||
| return a | |||||
| def get_conjugation_table(unitaries): | |||||
| """ Construct the conjugation table """ | |||||
| return np.array([find_clifford(qi.hermitian_conjugate(u), unitaries) for u in unitaries], dtype=int) | |||||
| def get_times_table(unitaries): | |||||
| """ Construct the times-table """ | |||||
| return np.array([[find_clifford(u.dot(v), unitaries) for v in unitaries] | |||||
| for u in tqdm(unitaries, desc="Building times-table")], dtype=int) | |||||
| def get_state_table(unitaries): | |||||
| """ Cache a table of state to speed up a little bit """ | |||||
| state_table = np.zeros((2, 24, 24, 4), dtype=complex) | |||||
| params = list(it.product([0, 1], range(24), range(24))) | |||||
| for bond, i, j in tqdm(params, desc="Building state table"): | |||||
| state = qi.bond if bond else qi.nobond | |||||
| kp = np.kron(unitaries[i], unitaries[j]) | |||||
| state_table[bond, i, j, :] = qi.normalize_global_phase( | |||||
| np.dot(kp, state).T) | |||||
| return state_table | |||||
| def get_measurement_entry(operator, unitary): | |||||
| """ | |||||
| Any Clifford group unitary will map an operator A in {I, X, Y, Z} | |||||
| to an operator B in +-{I, X, Y, Z}. This finds that mapping. | |||||
| """ | |||||
| matrices = ({"x": qi.msqx, "z": qi.sqz}[c] | |||||
| for c in DECOMPOSITIONS[unitary]) | |||||
| unitary = reduce(np.dot, matrices, np.eye(2, dtype=complex)) | |||||
| operator = qi.operators[operator] | |||||
| new_operator = reduce(np.dot, | |||||
| (unitary, operator, qi.hermitian_conjugate(unitary))) | |||||
| for i, o in enumerate(qi.operators): | |||||
| if np.allclose(o, new_operator): | |||||
| return i, 1 | |||||
| elif np.allclose(o, -new_operator): | |||||
| return i, -1 | |||||
| raise IndexError | |||||
| def get_measurement_table(): | |||||
| """ | |||||
| Compute a table of transform * operation * transform^dagger | |||||
| This is pretty unintelligible right now, we should probably compute the phase from unitaries instead | |||||
| """ | |||||
| measurement_table = np.zeros((4, 24, 2), dtype=complex) | |||||
| for operator, unitary in it.product(range(4), range(24)): | |||||
| measurement_table[operator, unitary] = get_measurement_entry( | |||||
| operator, unitary) | |||||
| return measurement_table | |||||
| def get_commuters(unitaries): | |||||
| """ Get the indeces of gates which commute with CZ """ | |||||
| commuters = (qi.id, qi.pz, qi.ph, qi.hermitian_conjugate(qi.ph)) | |||||
| return [find_clifford(u, unitaries) for u in commuters] | |||||
| def get_cz_table(unitaries): | |||||
| """ Compute the lookup table for the CZ (A&B eq. 9) """ | |||||
| # Get a cached state table and a list of gates which commute with CZ | |||||
| commuters = get_commuters(unitaries) | |||||
| state_table = get_state_table(unitaries) | |||||
| # And now build the CZ table | |||||
| cz_table = np.zeros((2, 24, 24, 3), dtype=int) | |||||
| rows = list( | |||||
| it.product([0, 1], it.combinations_with_replacement(range(24), 2))) | |||||
| # CZ is symmetric so we only need combinations | |||||
| for bond, (c1, c2) in tqdm(rows, desc="Building CZ table"): | |||||
| newbond, c1p, c2p = find_cz( | |||||
| bond, c1, c2, commuters, state_table) | |||||
| cz_table[bond, c1, c2] = [newbond, c1p, c2p] | |||||
| cz_table[bond, c2, c1] = [newbond, c2p, c1p] | |||||
| return cz_table | |||||
| def compute_everything(): | |||||
| """ Compute all lookup tables """ | |||||
| unitaries = get_unitaries() | |||||
| return {"decompositions": DECOMPOSITIONS, | |||||
| "unitaries": unitaries, | |||||
| "by_name": get_by_name(unitaries), | |||||
| "conjugation_table": get_conjugation_table(unitaries), | |||||
| "times_table": get_times_table(unitaries), | |||||
| "cz_table": get_cz_table(unitaries), | |||||
| "measurement_table": get_measurement_table()} | |||||
| def human_readable(data): | |||||
| """ Format the data """ | |||||
| unitaries = np.array(data["unitaries"]) | |||||
| return {"decompositions": json.dumps(DECOMPOSITIONS), | |||||
| "unitaries_real": json.dumps(unitaries.real.round(5).tolist()).replace("0.70711", "ir2"), | |||||
| "unitaries_imag": json.dumps(unitaries.imag.round(5).tolist()).replace("0.70711", "ir2"), | |||||
| "conjugation_table": json.dumps(data["conjugation_table"].tolist()), | |||||
| "times_table": json.dumps(data["times_table"].tolist()), | |||||
| "cz_table": json.dumps(data["cz_table"].tolist()), | |||||
| "by_name": json.dumps(data["by_name"]), | |||||
| "measurement_table_real": json.dumps(data["measurement_table"].real.tolist()), | |||||
| "measurement_table_imag": json.dumps(data["measurement_table"].imag.tolist())} | |||||
| def write_python(data): | |||||
| """ Write the tables to a python module """ | |||||
| path = join(dirname(__file__), "tables.py") | |||||
| content = PY_TEMPLATE.format(**data) | |||||
| with open(path, "w") as f: | |||||
| f.write(content) | |||||
| def write_javascript(data): | |||||
| """ Write the tables to javascript files for consumption in the browser """ | |||||
| path = join(split(dirname(__file__))[0], "static/scripts/tables.js") | |||||
| content = JS_TEMPLATE.format(**data) | |||||
| with open(path, "w") as f: | |||||
| f.write(content) | |||||
| if __name__ == '__main__': | |||||
| data = compute_everything() | |||||
| data = human_readable(data) | |||||
| write_python(data) | |||||
| write_javascript(data) | |||||
| @@ -6,236 +6,23 @@ It provides tables for Clifford group multiplication and conjugation, | |||||
| as well as CZ and decompositions of the 2x2 Cliffords. | as well as CZ and decompositions of the 2x2 Cliffords. | ||||
| """ | """ | ||||
| import os, json, tempfile, json | |||||
| from functools import reduce | |||||
| import itertools as it | |||||
| import numpy as np | |||||
| from tqdm import tqdm | |||||
| import qi | |||||
| 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") | |||||
| from tables import * | |||||
| def conjugate(operator, unitary): | def conjugate(operator, unitary): | ||||
| """ Returns transform * vop * transform^dagger and a phase in {+1, -1} """ | """ Returns transform * vop * transform^dagger and a phase in {+1, -1} """ | ||||
| return measurement_table[operator, unitary] | return measurement_table[operator, unitary] | ||||
| def use_old_cz(): | def use_old_cz(): | ||||
| """ Use the CZ table from A&B's code """ | """ Use the CZ table from A&B's code """ | ||||
| global cz_table | global cz_table | ||||
| from anders_cz import cz_table | from anders_cz import cz_table | ||||
| def get_name(i): | def get_name(i): | ||||
| """ Get the human-readable name of this clifford """ | """ Get the human-readable name of this clifford """ | ||||
| return "IXYZ"[i & 0x03] + "ABCDEF"[i / 4] | return "IXYZ"[i & 0x03] + "ABCDEF"[i / 4] | ||||
| def find_clifford(needle, haystack): | |||||
| """ Find the index of a given u within a list of unitaries, up to a global phase """ | |||||
| needle = qi.normalize_global_phase(needle) | |||||
| for i, t in enumerate(haystack): | |||||
| if np.allclose(t, needle): | |||||
| return i | |||||
| raise IndexError | |||||
| def find_cz(bond, c1, c2, commuters, state_table): | |||||
| """ Find the output of a CZ operation """ | |||||
| # Figure out the target state | |||||
| target = qi.cz.dot(state_table[bond, c1, c2]) | |||||
| target = qi.normalize_global_phase(target) | |||||
| # Choose the sets to search over | |||||
| s1 = commuters if c1 in commuters else xrange(24) | |||||
| s2 = commuters if c2 in commuters else xrange(24) | |||||
| # Find a match | |||||
| for bondp, c1p, c2p in it.product([0, 1], s1, s2): | |||||
| if np.allclose(target, state_table[bondp, c1p, c2p]): | |||||
| return bondp, c1p, c2p | |||||
| # Didn't find anything - this should never happen | |||||
| raise IndexError | |||||
| def compose_u(decomposition): | |||||
| """ Get the unitary representation of a particular decomposition """ | |||||
| matrices = ({"x": qi.msqx, "z": qi.sqz}[c] for c in decomposition) | |||||
| output = reduce(np.dot, matrices, np.eye(2, dtype=complex)) | |||||
| return qi.normalize_global_phase(output) | |||||
| def get_unitaries(): | |||||
| """ The Clifford group """ | |||||
| return [compose_u(d) for d in decompositions] | |||||
| def get_by_name(unitaries): | |||||
| """ Get a lookup table of cliffords by name """ | |||||
| a = {name: find_clifford(u, unitaries) | |||||
| for name, u in qi.by_name.items()} | |||||
| a.update({get_name(i): i for i in range(24)}) | |||||
| a.update({i: i for i in range(24)}) | |||||
| return a | |||||
| def get_conjugation_table(unitaries): | |||||
| """ Construct the conjugation table """ | |||||
| return np.array([find_clifford(qi.hermitian_conjugate(u), unitaries) for u in unitaries], dtype=int) | |||||
| def get_times_table(unitaries): | |||||
| """ Construct the times-table """ | |||||
| return np.array([[find_clifford(u.dot(v), unitaries) for v in unitaries] | |||||
| for u in tqdm(unitaries, desc="Building times-table")], dtype=int) | |||||
| def get_state_table(unitaries): | |||||
| """ Cache a table of state to speed up a little bit """ | |||||
| state_table = np.zeros((2, 24, 24, 4), dtype=complex) | |||||
| params = list(it.product([0, 1], range(24), range(24))) | |||||
| for bond, i, j in tqdm(params, desc="Building state table"): | |||||
| state = qi.bond if bond else qi.nobond | |||||
| kp = np.kron(unitaries[i], unitaries[j]) | |||||
| state_table[bond, i, j, :] = qi.normalize_global_phase( | |||||
| np.dot(kp, state).T) | |||||
| return state_table | |||||
| def get_measurement_entry(operator, unitary): | |||||
| """ | |||||
| Any Clifford group unitary will map an operator A in {I, X, Y, Z} | |||||
| to an operator B in +-{I, X, Y, Z}. This finds that mapping. | |||||
| """ | |||||
| matrices = ({"x": qi.msqx, "z": qi.sqz}[c] | |||||
| for c in decompositions[unitary]) | |||||
| unitary = reduce(np.dot, matrices, np.eye(2, dtype=complex)) | |||||
| operator = qi.operators[operator] | |||||
| new_operator = reduce( | |||||
| np.dot, (unitary, operator, qi.hermitian_conjugate(unitary))) | |||||
| for i, o in enumerate(qi.operators): | |||||
| if np.allclose(o, new_operator): | |||||
| return i, 1 | |||||
| elif np.allclose(o, -new_operator): | |||||
| return i, -1 | |||||
| raise IndexError | |||||
| def get_measurement_table(): | |||||
| """ | |||||
| Compute a table of transform * operation * transform^dagger | |||||
| This is pretty unintelligible right now, we should probably compute the phase from unitaries instead | |||||
| """ | |||||
| measurement_table = np.zeros((4, 24, 2), dtype=complex) | |||||
| for operator, unitary in it.product(range(4), range(24)): | |||||
| measurement_table[operator, unitary] = get_measurement_entry( | |||||
| operator, unitary) | |||||
| return measurement_table | |||||
| def get_commuters(unitaries): | |||||
| """ Get the indeces of gates which commute with CZ """ | |||||
| commuters = (qi.id, qi.pz, qi.ph, qi.hermitian_conjugate(qi.ph)) | |||||
| return [find_clifford(u, unitaries) for u in commuters] | |||||
| def get_cz_table(unitaries): | |||||
| """ Compute the lookup table for the CZ (A&B eq. 9) """ | |||||
| # Get a cached state table and a list of gates which commute with CZ | |||||
| commuters = get_commuters(unitaries) | |||||
| state_table = get_state_table(unitaries) | |||||
| # And now build the CZ table | |||||
| cz_table = np.zeros((2, 24, 24, 3), dtype=int) | |||||
| rows = list( | |||||
| it.product([0, 1], it.combinations_with_replacement(range(24), 2))) | |||||
| # CZ is symmetric so we only need combinations | |||||
| for bond, (c1, c2) in tqdm(rows, desc="Building CZ table"): | |||||
| newbond, c1p, c2p = find_cz( | |||||
| bond, c1, c2, commuters, state_table) | |||||
| cz_table[bond, c1, c2] = [newbond, c1p, c2p] | |||||
| cz_table[bond, c2, c1] = [newbond, c2p, c1p] | |||||
| return cz_table | |||||
| def write_javascript_tables(): | |||||
| """ Write the tables to javascript files for consumption in the browser """ | |||||
| path = os.path.dirname(__file__) | |||||
| path = os.path.split(path)[0] | |||||
| with open(os.path.join(path, "static/scripts/tables.js"), "w") as f: | |||||
| f.write("var tables = {\n") | |||||
| f.write("\tdecompositions : {},\n" | |||||
| .format(json.dumps(decompositions))) | |||||
| f.write("\tconjugation_table : {},\n" | |||||
| .format(json.dumps(conjugation_table.tolist()))) | |||||
| f.write("\ttimes_table : {},\n" | |||||
| .format(json.dumps(times_table.tolist()))) | |||||
| f.write("\tcz_table : {},\n" | |||||
| .format(json.dumps(cz_table.tolist()))) | |||||
| f.write("\tclifford : {}\n" | |||||
| .format(json.dumps(by_name))) | |||||
| f.write("};") | |||||
| def temp(filename): | |||||
| """ Get a temporary path """ | |||||
| # TODO: this STILL fucking fails sometimes. WHY | |||||
| tempdir = tempfile.gettempdir() | |||||
| return os.path.join(tempdir, filename) | |||||
| def compute_everything(): | |||||
| """ Compute all lookup tables """ | |||||
| global unitaries, by_name, conjugation_table, times_table, cz_table, measurement_table | |||||
| unitaries = get_unitaries() | |||||
| by_name = get_by_name(unitaries) | |||||
| conjugation_table = get_conjugation_table(unitaries) | |||||
| times_table = get_times_table(unitaries) | |||||
| cz_table = get_cz_table(unitaries) | |||||
| measurement_table = get_measurement_table() | |||||
| def save_to_disk(): | |||||
| """ Save all tables to disk """ | |||||
| global unitaries, by_name, conjugation_table, times_table, cz_table, measurement_table | |||||
| np.save(temp("unitaries.npy"), unitaries) | |||||
| np.save(temp("conjugation_table.npy"), conjugation_table) | |||||
| np.save(temp("times_table.npy"), times_table) | |||||
| np.save(temp("cz_table.npy"), cz_table) | |||||
| np.save(temp("measurement_table.npy"), measurement_table) | |||||
| write_javascript_tables() | |||||
| with open(temp("by_name.json"), "wb") as f: | |||||
| json.dump(by_name, f) | |||||
| def load_from_disk(): | |||||
| """ Load all the tables from disk """ | |||||
| global unitaries, by_name, conjugation_table, times_table, cz_table, measurement_table | |||||
| unitaries = np.load(temp("unitaries.npy")) | |||||
| conjugation_table = np.load(temp("conjugation_table.npy")) | |||||
| times_table = np.load(temp("times_table.npy")) | |||||
| measurement_table = np.load(temp("measurement_table.npy")) | |||||
| cz_table = np.load(temp("cz_table.npy")) | |||||
| with open(temp("by_name.json")) as f: | |||||
| by_name = json.load(f) | |||||
| def is_diagonal(v): | def is_diagonal(v): | ||||
| """ TODO: remove this. Checks if a VOP is diagonal or not """ | """ TODO: remove this. Checks if a VOP is diagonal or not """ | ||||
| return v in {0, 3, 5, 6} | return v in {0, 3, 5, 6} | ||||
| if __name__ == "__main__": | |||||
| compute_everything() | |||||
| save_to_disk() | |||||
| else: | |||||
| try: | |||||
| load_from_disk() | |||||
| except IOError: | |||||
| compute_everything() | |||||
| save_to_disk() | |||||
| @@ -101,7 +101,7 @@ def test_with_cphase_gates_hadamard_only(N=10): | |||||
| assert_equal(a, b) | assert_equal(a, b) | ||||
| def _test_cz_hadamard(N=3): | |||||
| def test_cz_hadamard(N=3): | |||||
| """ Test CZs and Hadamards at random """ | """ Test CZs and Hadamards at random """ | ||||
| clifford.use_old_cz() | clifford.use_old_cz() | ||||
| @@ -2,6 +2,7 @@ from numpy import * | |||||
| from tqdm import tqdm | from tqdm import tqdm | ||||
| import itertools as it | import itertools as it | ||||
| from abp import clifford | from abp import clifford | ||||
| from abp import build_tables | |||||
| from abp import qi | from abp import qi | ||||
| from nose.tools import raises | from nose.tools import raises | ||||
| @@ -16,14 +17,14 @@ def identify_pauli(m): | |||||
| def test_find_clifford(): | def test_find_clifford(): | ||||
| """ Test that slightly suspicious function """ | """ Test that slightly suspicious function """ | ||||
| assert clifford.find_clifford(qi.id, clifford.unitaries) == 0 | |||||
| assert clifford.find_clifford(qi.px, clifford.unitaries) == 1 | |||||
| assert build_tables.find_clifford(qi.id, clifford.unitaries) == 0 | |||||
| assert build_tables.find_clifford(qi.px, clifford.unitaries) == 1 | |||||
| @raises(IndexError) | @raises(IndexError) | ||||
| def test_find_non_clifford(): | def test_find_non_clifford(): | ||||
| """ Test that looking for a non-Clifford gate fails """ | """ Test that looking for a non-Clifford gate fails """ | ||||
| clifford.find_clifford(qi.t, clifford.unitaries) | |||||
| build_tables.find_clifford(qi.t, clifford.unitaries) | |||||
| def get_action(u): | def get_action(u): | ||||
| @@ -44,14 +45,14 @@ def test_we_have_24_matrices(): | |||||
| def test_we_have_all_useful_gates(): | def test_we_have_all_useful_gates(): | ||||
| """ Check that all the interesting gates are included up to a global phase """ | """ Check that all the interesting gates are included up to a global phase """ | ||||
| for name, u in qi.by_name.items(): | for name, u in qi.by_name.items(): | ||||
| clifford.find_clifford(u, clifford.unitaries) | |||||
| build_tables.find_clifford(u, clifford.unitaries) | |||||
| def test_group(): | def test_group(): | ||||
| """ Test we are really in a group """ | """ Test we are really in a group """ | ||||
| matches = set() | matches = set() | ||||
| for a, b in tqdm(it.combinations(clifford.unitaries, 2), "Testing this is a group"): | for a, b in tqdm(it.combinations(clifford.unitaries, 2), "Testing this is a group"): | ||||
| i = clifford.find_clifford(a.dot(b), clifford.unitaries) | |||||
| i = build_tables.find_clifford(a.dot(b), clifford.unitaries) | |||||
| matches.add(i) | matches.add(i) | ||||
| assert len(matches) == 24 | assert len(matches) == 24 | ||||
| @@ -76,4 +77,4 @@ def test_cz_table_makes_sense(): | |||||
| def test_commuters(): | def test_commuters(): | ||||
| """ Test that commutation is good """ | """ Test that commutation is good """ | ||||
| assert len(clifford.get_commuters(clifford.unitaries)) == 4 | |||||
| assert len(build_tables.get_commuters(clifford.unitaries)) == 4 | |||||
| @@ -4,11 +4,11 @@ import sys | |||||
| import os | import os | ||||
| import itertools as it | import itertools as it | ||||
| from string import maketrans | from string import maketrans | ||||
| from abp import clifford, qi, anders_cz | |||||
| from abp import clifford, qi, anders_cz, build_tables | |||||
| def test_cz_table(): | def test_cz_table(): | ||||
| """ Does our clifford code work with anders & briegel's table? """ | """ Does our clifford code work with anders & briegel's table? """ | ||||
| state_table = clifford.get_state_table(clifford.unitaries) | |||||
| state_table = build_tables.get_state_table(clifford.unitaries) | |||||
| ab_cz_table = anders_cz.cz_table | ab_cz_table = anders_cz.cz_table | ||||
| rows = it.product([0, 1], it.combinations_with_replacement(range(24), 2)) | rows = it.product([0, 1], it.combinations_with_replacement(range(24), 2)) | ||||
| @@ -1,10 +1,10 @@ | |||||
| import numpy as np | import numpy as np | ||||
| from abp import clifford, qi | |||||
| from abp import clifford, qi, build_tables | |||||
| import itertools as it | import itertools as it | ||||
| def test_cz_table(): | def test_cz_table(): | ||||
| """ Does the CZ code work good? """ | """ Does the CZ code work good? """ | ||||
| state_table = clifford.get_state_table(clifford.unitaries) | |||||
| state_table = build_tables.get_state_table(clifford.unitaries) | |||||
| rows = it.product([0, 1], it.combinations_with_replacement(range(24), 2)) | rows = it.product([0, 1], it.combinations_with_replacement(range(24), 2)) | ||||