Browse Source

Amalgamate and tidy

master
Pete Shadbolt 8 years ago
parent
commit
9f7177fad4
9 changed files with 76 additions and 144 deletions
  1. +1
    -1
      .gitignore
  2. +1
    -6
      clifford.py
  3. +0
    -48
      cz.py
  4. +14
    -0
      cz_table.py
  5. +30
    -0
      graph.py
  6. +0
    -55
      pseudocode.txt
  7. +1
    -3
      tests/test_cz.py
  8. +29
    -1
      util.py
  9. +0
    -30
      viz.py

+ 1
- 1
.gitignore View File

@@ -1,4 +1,4 @@
tables.pkl
*.pkl
*.pdf
papers/
# Project-specific


+ 1
- 6
clifford.py View File

@@ -32,7 +32,7 @@ def name_of(vop):
return "%s" % get_name[vop] if vop in get_name else "VOP%d" % vop


@cache_to_disk("tables.pkl")
@cache_to_disk("clifford_tables.pkl")
def construct_tables():
""" Constructs / caches multiplication and conjugation tables """
by_name = {name: find_up_to_phase(u)[0] for name, u in qi.by_name.items()}
@@ -51,8 +51,3 @@ elements = {"x": qi.sqx, "z": qi.msqz}
unitaries = [compose_u(d) for d in decompositions]
by_name, get_name, conjugation_table, times_table = construct_tables()


if __name__ == '__main__':
print by_name
print get_name


+ 0
- 48
cz.py View File

@@ -1,48 +0,0 @@
from graph import *
import viz
import itertools as it
import clifford

def cphase(g, vops, a, b):
""" Act a controlled-phase gate on two qubits """
if g[a]-{b}: remove_vop(g, vops, a, b)
if g[b]-{a}: remove_vop(g, vops, b, a)
if g[a]-{b}: remove_vop(g, vops, a, b)
edge = has_edge(g, a, b)
new_edge, vops[a], vops[b] = cphase_table[edge, vops[a], vops[b]]
if new_edge != edge:
toggle_edge(g, a, b)

def remove_vop(g, vops, a, avoid):
""" Reduces VOP[a] to the identity, avoiding (if possible) the use of vertex b as a swapping partner """
others = g[a] - {avoid}
swap_qubit = others.pop() if others else avoid
for v in reversed(clifford.decompositions[vops[a]]):
local_complementation(g, vops, a if v == "x" else swap_qubit)


def local_complementation(g, vops, v):
""" As defined in LISTING 1 of Anders & Briegel """
for i, j in it.combinations(g[v], 2):
toggle_edge(g, i, j)

# Update VOPs
vops[v] = clifford.times_table[vops[v]][clifford.by_name["sqx"]]
for i in g[v]:
vops[i] = clifford.times_table[vops[i]][clifford.by_name["msqz"]]


if __name__ == '__main__':
g, vops = graph()
add_edge(g, 0, 1)
add_edge(g, 1, 2)
add_edge(g, 0, 2)
add_edge(g, 0, 3)
add_edge(g, 6, 7)

pos = viz.draw(g, vops, "out.pdf")
remove_vop(g, vops, 0, 1)
remove_vop(g, vops, 1, 2)
cphase(g, vops, 0, 1)
viz.draw(g, vops, "out2.pdf", pos)

+ 14
- 0
cz_table.py View File

@@ -0,0 +1,14 @@
""" This part computes the CZ table """

from util import cache_to_disk
import qi
import numpy as np
from tqdm import tqdm
import clifford

#@cache_to_disk("cz_table.pkl")
def construct_table():
print "awd"
return "awd"

cz_table = construct_table()

+ 30
- 0
graph.py View File

@@ -3,6 +3,7 @@ Provides an extremely basic graph structure, based on neighbour lists
"""

from collections import defaultdict
import itertools as it
import clifford

def graph():
@@ -39,3 +40,32 @@ def edgelist(g):
for n in v)
return [tuple(e) for e in edges]

def cphase(g, vops, a, b):
""" Act a controlled-phase gate on two qubits """
if g[a]-{b}: remove_vop(g, vops, a, b)
if g[b]-{a}: remove_vop(g, vops, b, a)
if g[a]-{b}: remove_vop(g, vops, a, b)
edge = has_edge(g, a, b)
new_edge, vops[a], vops[b] = cphase_table[edge, vops[a], vops[b]]
if new_edge != edge:
toggle_edge(g, a, b)

def remove_vop(g, vops, a, avoid):
""" Reduces VOP[a] to the identity, avoiding (if possible) the use of vertex b as a swapping partner """
others = g[a] - {avoid}
swap_qubit = others.pop() if others else avoid
for v in reversed(clifford.decompositions[vops[a]]):
local_complementation(g, vops, a if v == "x" else swap_qubit)


def local_complementation(g, vops, v):
""" As defined in LISTING 1 of Anders & Briegel """
for i, j in it.combinations(g[v], 2):
toggle_edge(g, i, j)

# Update VOPs
vops[v] = clifford.times_table[vops[v]][clifford.by_name["sqx"]]
for i in g[v]:
vops[i] = clifford.times_table[vops[i]][clifford.by_name["msqz"]]


+ 0
- 55
pseudocode.txt View File

@@ -1,55 +0,0 @@
cphase (vertex a, vertex b):
if ngbh a\{b} =/= {}:
remove VOP (a, b)
end if
if ngbh b\{a} =/= {}:
remove VOP (b, a)
end if
[It may happen that the condition in line 2 has not been fulfilled then, but is now due to the effect of line 5. So we check again:]
if ngbh a\{b} =/= {}:
remove VOP (a, b)
end if
[Now we can be sure that the the condition (ngbh c\{a, b} = {} or VOP[c] ∈ Z) is fulfilled for c = a, b and we may use the lookup table (cf. Eq. (9)).]
if {a, b} ∈ E :
edge ← true
else:
edge ← false
end if
(edge, VOP[a], VOP[b]) ← cphase_table[edge, VOP[a], VOP[b]]


remove_VOP (vertex a, vertex b):
[This reduces VOP[a] to I, avoiding (if possible) to use b as swapping partner.]
[First, we choose a swapping partner c.]
if ngbh a\{b} = {}:
c ← any element of ngbh a\{b}
else:
c←b
end if
d ← decomposition lookup table [a]
[c contains now a decomposition such as Eq. (7)]
for v from last factor of d to first factor of d
if v = −iX:
local complementation (a)
else: ( this means that v = iZ)
local complementation (b)
end if
[Now, VOP[a] = I.]


local complementation (vertex a)
[performs the operation specified in Definition 4]
nv ← ngbh v
for i ∈ nv :
for j ∈ nv :
if i < j:
if (i, j) ∈ E:
remove edge (i, j)
else:
add edge (i, j)
end if
end if
end for
VOP[i] ← VOP[i]sqrt(−iZ)
VOP[v] ← VOP[v]sqrt(iX)
end for

+ 1
- 3
tests/test_cz.py View File

@@ -1,6 +1,4 @@
import cz
from graph import *
import viz

def test_local_complementation():
""" Test that local complementation works as expected """
@@ -9,7 +7,7 @@ def test_local_complementation():
add_edge(g, 0, 2)
add_edge(g, 1, 2)
add_edge(g, 0, 3)
cz.local_complementation(g, vops, 0)
local_complementation(g, vops, 0)
assert has_edge(g, 0, 1)
assert has_edge(g, 0, 2)
assert not has_edge(g, 1, 2)


+ 29
- 1
util.py View File

@@ -1,9 +1,17 @@
"""
Provides a decorator to cache function output to disk
Useful but messy crap
"""
import cPickle
import networkx as nx
from matplotlib import pyplot as plt
from graph import *
import clifford
import numpy as np

VOP_COLORS = ["red", "green", "blue", "orange", "yellow", "purple", "black", "white"]

def cache_to_disk(file_name):
""" A decorator to cache the output of a function to disk """
def wrap(func):
def modified(*args, **kwargs):
try:
@@ -15,3 +23,23 @@ def cache_to_disk(file_name):
return output
return modified
return wrap


def draw(graph, vops, filename="out.pdf", pos=None, ns=500):
""" Draw a graph with networkx layout """
plt.clf()
g = nx.from_edgelist(edgelist(graph))
pos = nx.spring_layout(g) if pos==None else pos
colors = [VOP_COLORS[vop % len(VOP_COLORS)] for vop in vops]
nx.draw_networkx_nodes(g, pos, node_color="white", node_size=ns)
nx.draw_networkx_nodes(g, pos, node_color=colors, node_size=ns, alpha=.4)
nx.draw_networkx_edges(g, pos, edge_color="gray")
nx.draw_networkx_labels(g, pos, font_family="FreeSans")

labels = {i: clifford.name_of(vops[i]) for i in g.nodes()}
pos = {k: v + np.array([0, -.1]) for k, v in pos.items()}
nx.draw_networkx_labels(g, pos, labels, font_family="FreeSans")
plt.axis('off')
plt.savefig(filename)
return pos


+ 0
- 30
viz.py View File

@@ -1,30 +0,0 @@
"""
Utility function for plotting graphs nicely
"""

import networkx as nx
from matplotlib import pyplot as plt
from graph import *
import clifford
import numpy as np

VOP_COLORS = ["red", "green", "blue", "orange", "yellow", "purple", "black", "white"]

def draw(graph, vops, filename="out.pdf", pos=None, ns=500):
""" Draw a graph with networkx layout """
plt.clf()
g = nx.from_edgelist(edgelist(graph))
pos = nx.spring_layout(g) if pos==None else pos
colors = [VOP_COLORS[vop % len(VOP_COLORS)] for vop in vops]
nx.draw_networkx_nodes(g, pos, node_color="white", node_size=ns)
nx.draw_networkx_nodes(g, pos, node_color=colors, node_size=ns, alpha=.4)
nx.draw_networkx_edges(g, pos, edge_color="gray")
nx.draw_networkx_labels(g, pos, font_family="FreeSans")

labels = {i: clifford.name_of(vops[i]) for i in g.nodes()}
pos = {k: v + np.array([0, -.1]) for k, v in pos.items()}
nx.draw_networkx_labels(g, pos, labels, font_family="FreeSans")
plt.axis('off')
plt.savefig(filename)
return pos


Loading…
Cancel
Save