|
@@ -5,15 +5,13 @@ |
|
|
This program generates lookup tables |
|
|
This program generates lookup tables |
|
|
""" |
|
|
""" |
|
|
|
|
|
|
|
|
|
|
|
import os, json |
|
|
|
|
|
from functools import reduce |
|
|
|
|
|
import itertools as it |
|
|
import qi |
|
|
import qi |
|
|
import numpy as np |
|
|
import numpy as np |
|
|
from tqdm import tqdm |
|
|
from tqdm import tqdm |
|
|
from functools import reduce |
|
|
|
|
|
import itertools as it |
|
|
|
|
|
|
|
|
|
|
|
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 clifford import decompositions |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def find_clifford(needle, haystack): |
|
|
def find_clifford(needle, haystack): |
|
@@ -52,19 +50,20 @@ def compose_u(decomposition): |
|
|
return reduce(np.dot, matrices, np.matrix(np.eye(2, dtype=complex))) |
|
|
return reduce(np.dot, matrices, np.matrix(np.eye(2, dtype=complex))) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def get_unitaries(decompositions): |
|
|
|
|
|
|
|
|
def get_unitaries(): |
|
|
""" The Clifford group """ |
|
|
""" The Clifford group """ |
|
|
return [compose_u(d) for d in decompositions] |
|
|
return [compose_u(d) for d in decompositions] |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def hermitian_conjugate(u): |
|
|
|
|
|
""" Get the hermitian conjugate """ |
|
|
|
|
|
return np.conjugate(np.transpose(u)) |
|
|
|
|
|
|
|
|
def get_by_name(unitaries): |
|
|
|
|
|
""" Get a lookup table of cliffords by name """ |
|
|
|
|
|
return {name: find_clifford(u, unitaries) |
|
|
|
|
|
for name, u in qi.by_name.items()} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def get_conjugation_table(unitaries): |
|
|
def get_conjugation_table(unitaries): |
|
|
""" Construct the conjugation table """ |
|
|
""" Construct the conjugation table """ |
|
|
return np.array([find_clifford(hermitian_conjugate(u), unitaries) for u in unitaries]) |
|
|
|
|
|
|
|
|
return np.array([find_clifford(qi.hermitian_conjugate(u), unitaries) for u in unitaries]) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def get_times_table(unitaries): |
|
|
def get_times_table(unitaries): |
|
@@ -73,10 +72,11 @@ def get_times_table(unitaries): |
|
|
for u in tqdm(unitaries, desc="Building times-table")]) |
|
|
for u in tqdm(unitaries, desc="Building times-table")]) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def get_state_table(): |
|
|
|
|
|
|
|
|
def get_state_table(unitaries): |
|
|
""" Cache a table of state to speed up a little bit """ |
|
|
""" Cache a table of state to speed up a little bit """ |
|
|
state_table = np.zeros((2, 24, 24, 4), dtype=complex) |
|
|
state_table = np.zeros((2, 24, 24, 4), dtype=complex) |
|
|
for bond, i, j in it.product([0, 1], range(24), range(24)): |
|
|
|
|
|
|
|
|
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 |
|
|
state = qi.bond if bond else qi.nobond |
|
|
kp = np.kron(unitaries[i], unitaries[j]) |
|
|
kp = np.kron(unitaries[i], unitaries[j]) |
|
|
state_table[bond, i, j, :] = np.dot(kp, state).T |
|
|
state_table[bond, i, j, :] = np.dot(kp, state).T |
|
@@ -85,10 +85,11 @@ def get_state_table(): |
|
|
|
|
|
|
|
|
def get_cz_table(unitaries): |
|
|
def get_cz_table(unitaries): |
|
|
""" Compute the lookup table for the CZ (A&B eq. 9) """ |
|
|
""" Compute the lookup table for the CZ (A&B eq. 9) """ |
|
|
commuters = (qi.id, qi.px, qi.pz, qi.ph, hermitian_conjugate(qi.ph)) |
|
|
|
|
|
|
|
|
commuters = (qi.id, qi.px, qi.pz, qi.ph, qi.hermitian_conjugate(qi.ph)) |
|
|
commuters = [find_clifford(u, unitaries) for u in commuters] |
|
|
commuters = [find_clifford(u, unitaries) for u in commuters] |
|
|
state_table = get_state_table() |
|
|
|
|
|
|
|
|
state_table = get_state_table(unitaries) |
|
|
|
|
|
|
|
|
|
|
|
# TODO: it's symmetric. this can be much faster |
|
|
cz_table = np.zeros((2, 24, 24, 3)) |
|
|
cz_table = np.zeros((2, 24, 24, 3)) |
|
|
rows = list(it.product([0, 1], range(24), range(24))) |
|
|
rows = list(it.product([0, 1], range(24), range(24))) |
|
|
for bond, c1, c2 in tqdm(rows, desc="Building CZ table"): |
|
|
for bond, c1, c2 in tqdm(rows, desc="Building CZ table"): |
|
@@ -96,23 +97,23 @@ def get_cz_table(unitaries): |
|
|
return cz_table |
|
|
return cz_table |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if not __name__ == "__main__": |
|
|
|
|
|
try: |
|
|
|
|
|
unitaries = np.load("tables/unitaries.npy") |
|
|
|
|
|
conjugation_table = np.load("tables/conjugation_table.npy") |
|
|
|
|
|
times_table = np.load("tables/times_table.npy") |
|
|
|
|
|
cz_table = np.load("tables/cz_table.npy") |
|
|
|
|
|
except IOError: |
|
|
|
|
|
print "Precomputed tables not found, try running `python make_tables.py`" |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if __name__ == "__main__": |
|
|
if __name__ == "__main__": |
|
|
unitaries = get_unitaries(decompositions) |
|
|
|
|
|
|
|
|
# Spend time loading the stuff |
|
|
|
|
|
unitaries = get_unitaries() |
|
|
|
|
|
by_name = get_by_name(unitaries) |
|
|
conjugation_table = get_conjugation_table(unitaries) |
|
|
conjugation_table = get_conjugation_table(unitaries) |
|
|
times_table = get_times_table(unitaries) |
|
|
times_table = get_times_table(unitaries) |
|
|
cz_table = get_cz_table(unitaries) |
|
|
|
|
|
|
|
|
#cz_table = get_cz_table(unitaries) |
|
|
|
|
|
|
|
|
|
|
|
# Write it all to disk |
|
|
|
|
|
directory = os.path.dirname(os.path.abspath(__file__)) |
|
|
|
|
|
where = os.path.join(directory, "tables/") |
|
|
|
|
|
os.chdir(where) |
|
|
|
|
|
np.save("unitaries.npy", unitaries) |
|
|
|
|
|
np.save("conjugation_table.npy", conjugation_table) |
|
|
|
|
|
np.save("times_table.npy", times_table) |
|
|
|
|
|
#np.save("cz_table.npy", cz_table) |
|
|
|
|
|
|
|
|
|
|
|
with open("by_name.json", "wb") as f: |
|
|
|
|
|
json.dump(by_name, f) |
|
|
|
|
|
|
|
|
np.save("tables/unitaries.npy", unitaries) |
|
|
|
|
|
np.save("tables/conjugation_table.npy", conjugation_table) |
|
|
|
|
|
np.save("tables/times_table.npy", times_table) |
|
|
|
|
|
np.save("tables/cz_table.npy", cz_table) |
|
|
|