|
@@ -15,15 +15,17 @@ decompositions = ("xxxx", "xx", "zzxx", "zz", "zxx", "z", "zzz", "xxz", |
|
|
"xzx", "xzxxx", "xzzzx", "xxxzx", "xzz", "zzx", "xxx", "x", |
|
|
"xzx", "xzxxx", "xzzzx", "xxxzx", "xzz", "zzx", "xxx", "x", |
|
|
"zzzx", "xxzx", "zx", "zxxx", "xxxz", "xzzz", "xz", "xzxx") |
|
|
"zzzx", "xxzx", "zx", "zxxx", "xxxz", "xzzz", "xz", "xzxx") |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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 """ |
|
@@ -101,15 +103,18 @@ def get_state_table(unitaries): |
|
|
np.dot(kp, state).T) |
|
|
np.dot(kp, state).T) |
|
|
return state_table |
|
|
return state_table |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def get_measurement_entry(operator, unitary): |
|
|
def get_measurement_entry(operator, unitary): |
|
|
""" |
|
|
|
|
|
Any Clifford group unitary will map an operator A in {I, X, Y, Z} |
|
|
|
|
|
|
|
|
""" |
|
|
|
|
|
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. |
|
|
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]) |
|
|
|
|
|
|
|
|
matrices = ({"x": qi.msqx, "z": qi.sqz}[c] |
|
|
|
|
|
for c in decompositions[unitary]) |
|
|
unitary = reduce(np.dot, matrices, np.eye(2, dtype=complex)) |
|
|
unitary = reduce(np.dot, matrices, np.eye(2, dtype=complex)) |
|
|
operator = qi.operators[operator] |
|
|
operator = qi.operators[operator] |
|
|
new_operator = reduce(np.dot, (unitary, operator, qi.hermitian_conjugate(unitary))) |
|
|
|
|
|
|
|
|
new_operator = reduce( |
|
|
|
|
|
np.dot, (unitary, operator, qi.hermitian_conjugate(unitary))) |
|
|
|
|
|
|
|
|
for i, o in enumerate(qi.operators): |
|
|
for i, o in enumerate(qi.operators): |
|
|
if np.allclose(o, new_operator): |
|
|
if np.allclose(o, new_operator): |
|
@@ -119,14 +124,16 @@ def get_measurement_entry(operator, unitary): |
|
|
|
|
|
|
|
|
raise IndexError |
|
|
raise IndexError |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def get_measurement_table(): |
|
|
def get_measurement_table(): |
|
|
""" |
|
|
|
|
|
Compute a table of transform * operation * transform^dagger |
|
|
|
|
|
|
|
|
""" |
|
|
|
|
|
Compute a table of transform * operation * transform^dagger |
|
|
This is pretty unintelligible right now, we should probably compute the phase from unitaries instead |
|
|
This is pretty unintelligible right now, we should probably compute the phase from unitaries instead |
|
|
""" |
|
|
""" |
|
|
measurement_table = np.zeros((4, 24, 2), dtype=complex) |
|
|
measurement_table = np.zeros((4, 24, 2), dtype=complex) |
|
|
for operator, unitary in it.product(range(4), range(24)): |
|
|
for operator, unitary in it.product(range(4), range(24)): |
|
|
measurement_table[operator, unitary] = [operator, unitary] |
|
|
|
|
|
|
|
|
measurement_table[operator, unitary] = get_measurement_entry( |
|
|
|
|
|
operator, unitary) |
|
|
return measurement_table |
|
|
return measurement_table |
|
|
|
|
|
|
|
|
|
|
|
|
|
@@ -160,24 +167,26 @@ def write_javascript_tables(): |
|
|
path = os.path.dirname(sys.argv[0]) |
|
|
path = os.path.dirname(sys.argv[0]) |
|
|
path = os.path.split(path)[0] |
|
|
path = os.path.split(path)[0] |
|
|
with open(os.path.join(path, "static/scripts/tables.js"), "w") as f: |
|
|
with open(os.path.join(path, "static/scripts/tables.js"), "w") as f: |
|
|
f.write("var tables = {\n"); |
|
|
|
|
|
f.write("\tdecompositions : {},\n"\ |
|
|
|
|
|
|
|
|
f.write("var tables = {\n") |
|
|
|
|
|
f.write("\tdecompositions : {},\n" |
|
|
.format(json.dumps(decompositions))) |
|
|
.format(json.dumps(decompositions))) |
|
|
f.write("\tconjugation_table : {},\n"\ |
|
|
|
|
|
|
|
|
f.write("\tconjugation_table : {},\n" |
|
|
.format(json.dumps(conjugation_table.tolist()))) |
|
|
.format(json.dumps(conjugation_table.tolist()))) |
|
|
f.write("\ttimes_table : {},\n"\ |
|
|
|
|
|
|
|
|
f.write("\ttimes_table : {},\n" |
|
|
.format(json.dumps(times_table.tolist()))) |
|
|
.format(json.dumps(times_table.tolist()))) |
|
|
f.write("\tcz_table : {},\n"\ |
|
|
|
|
|
|
|
|
f.write("\tcz_table : {},\n" |
|
|
.format(json.dumps(cz_table.tolist()))) |
|
|
.format(json.dumps(cz_table.tolist()))) |
|
|
f.write("\tclifford : {}\n"\ |
|
|
|
|
|
|
|
|
f.write("\tclifford : {}\n" |
|
|
.format(json.dumps(by_name))) |
|
|
.format(json.dumps(by_name))) |
|
|
f.write("};"); |
|
|
|
|
|
|
|
|
f.write("};") |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def temp(filename): |
|
|
def temp(filename): |
|
|
""" Get a temporary path """ |
|
|
""" Get a temporary path """ |
|
|
tempdir = tempfile.gettempdir() |
|
|
tempdir = tempfile.gettempdir() |
|
|
return os.path.join(tempdir, filename) |
|
|
return os.path.join(tempdir, filename) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def compute_everything(): |
|
|
def compute_everything(): |
|
|
""" Compute all lookup tables """ |
|
|
""" Compute all lookup tables """ |
|
|
global unitaries, by_name, conjugation_table, times_table, cz_table, measurement_table |
|
|
global unitaries, by_name, conjugation_table, times_table, cz_table, measurement_table |
|
@@ -188,6 +197,7 @@ def compute_everything(): |
|
|
cz_table = get_cz_table(unitaries) |
|
|
cz_table = get_cz_table(unitaries) |
|
|
measurement_table = get_measurement_table() |
|
|
measurement_table = get_measurement_table() |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def save_to_disk(): |
|
|
def save_to_disk(): |
|
|
""" Save all tables to disk """ |
|
|
""" Save all tables to disk """ |
|
|
global unitaries, by_name, conjugation_table, times_table, cz_table, measurement_table |
|
|
global unitaries, by_name, conjugation_table, times_table, cz_table, measurement_table |
|
@@ -200,6 +210,7 @@ def save_to_disk(): |
|
|
with open(temp("by_name.json"), "wb") as f: |
|
|
with open(temp("by_name.json"), "wb") as f: |
|
|
json.dump(by_name, f) |
|
|
json.dump(by_name, f) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def load_from_disk(): |
|
|
def load_from_disk(): |
|
|
""" Load all the tables from disk """ |
|
|
""" Load all the tables from disk """ |
|
|
global unitaries, by_name, conjugation_table, times_table, cz_table, measurement_table |
|
|
global unitaries, by_name, conjugation_table, times_table, cz_table, measurement_table |
|
|