浏览代码

Re-organize

master
Pete Shadbolt 8 年前
父节点
当前提交
42d209b27e
共有 2 个文件被更改,包括 138 次插入139 次删除
  1. +138
    -10
      abp/clifford.py
  2. +0
    -129
      abp/make_tables.py

+ 138
- 10
abp/clifford.py 查看文件

@@ -1,18 +1,146 @@
import numpy as np
#!/usr/bin/python
# -*- coding: utf-8 -*-

"""
This program generates lookup tables
"""

import os, json
from functools import reduce
import itertools as it
from . import qi
import numpy as np
import tempfile
from tqdm import tqdm

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")

directory = os.path.dirname(os.path.abspath(__file__))
where = os.path.join(directory, "tables/")
os.chdir(where)
unitaries = np.load("unitaries.npy")
conjugation_table = np.load("conjugation_table.npy")
times_table = np.load("times_table.npy")
cz_table = np.load("cz_table.npy")

with open("by_name.json") as f:
by_name = json.load(f)
def find_clifford(needle, haystack):
""" Find the index of a given u within a list of unitaries, up to a global phase """
needle = normalize_global_phase(needle)
for i, t in enumerate(haystack):
if np.allclose(t, needle):
return i
raise IndexError


def normalize_global_phase(m):
""" Normalize the global phase of a matrix """
v = (x for x in m.flatten() if np.abs(x) > 0.001).next()
phase = np.arctan2(v.imag, v.real) % np.pi
rot = np.exp(-1j * phase)
return rot * m if rot * v > 0 else -rot * m


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 = 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 bond, c1p, c2p in it.product([0, 1], s1, s2):
if np.allclose(target, state_table[bond, c1p, c2p]):
return bond, 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.sqx, "z": qi.msqz}[c] for c in decomposition)
output = reduce(np.dot, matrices, np.eye(2, dtype=complex))
return 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 """
return {name: find_clifford(u, unitaries)
for name, u in qi.by_name.items()}


def get_conjugation_table(unitaries):
""" Construct the conjugation table """
return np.array([find_clifford(qi.hermitian_conjugate(u), unitaries) for u in unitaries])


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")])


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, :] = normalize_global_phase(
np.dot(kp, state).T)
return state_table


def get_cz_table(unitaries):
""" Compute the lookup table for the CZ (A&B eq. 9) """
# This is the set of Cliffords which commute with CZ
commuters = (qi.id, qi.px, qi.pz, qi.ph, qi.hermitian_conjugate(qi.ph))
commuters = [find_clifford(u, unitaries) for u in commuters]

# Get a cached state table
state_table = get_state_table(unitaries)

# And now build the CZ table
cz_table = np.zeros((2, 24, 24, 3))
rows = list(it.product([0, 1], it.combinations(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


# First try to load tables from cache. If that fails, build them from
# scratch and store
os.chdir(tempfile.gettempdir())
try:
unitaries = np.load("unitaries.npy")
conjugation_table = np.load("conjugation_table.npy")
times_table = np.load("times_table.npy")
cz_table = np.load("cz_table.npy")

with open("by_name.json") as f:
by_name = json.load(f)

print "Loaded tables from cache"
except IOError:
# Spend time building the tables
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)

# Write it all to disk
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)

+ 0
- 129
abp/make_tables.py 查看文件

@@ -1,129 +0,0 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-

"""
This program generates lookup tables
"""

import os, json
from functools import reduce
import itertools as it
import qi
import numpy as np
import tempfile
from tqdm import tqdm
from clifford import decompositions


def find_clifford(needle, haystack):
""" Find the index of a given u within a list of unitaries, up to a global phase """
needle = normalize_global_phase(needle)
for i, t in enumerate(haystack):
if np.allclose(t, needle):
return i
raise IndexError


def normalize_global_phase(m):
""" Normalize the global phase of a matrix """
v = (x for x in m.flatten() if np.abs(x)>0.001).next()
phase = np.arctan2(v.imag, v.real) % np.pi
rot = np.exp(-1j*phase)
return rot * m if rot * v > 0 else -rot*m


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 = 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 bond, c1p, c2p in it.product([0, 1], s1, s2):
if np.allclose(target, state_table[bond, c1p, c2p]):
return bond, 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.sqx, "z": qi.msqz}[c] for c in decomposition)
output = reduce(np.dot, matrices, np.eye(2, dtype=complex))
return 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 """
return {name: find_clifford(u, unitaries)
for name, u in qi.by_name.items()}


def get_conjugation_table(unitaries):
""" Construct the conjugation table """
return np.array([find_clifford(qi.hermitian_conjugate(u), unitaries) for u in unitaries])


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")])


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, :] = normalize_global_phase(np.dot(kp, state).T)
return state_table


def get_cz_table(unitaries):
""" Compute the lookup table for the CZ (A&B eq. 9) """
# This is the set of Cliffords which commute with CZ
commuters = (qi.id, qi.px, qi.pz, qi.ph, qi.hermitian_conjugate(qi.ph))
commuters = [find_clifford(u, unitaries) for u in commuters]

# Get a cached state table
state_table = get_state_table(unitaries)

# And now build the CZ table
cz_table = np.zeros((2, 24, 24, 3))
rows = list(it.product([0, 1], it.combinations(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


if __name__ == "__main__":
# Spend time building the tables
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)

# Write it all to disk
where = tempfile.gettempdir()
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)

正在加载...
取消
保存