Browse Source

Fixing fixing fixing

master
Pete Shadbolt 8 years ago
parent
commit
faa8d05c3d
3 changed files with 87 additions and 24 deletions
  1. +60
    -7
      abp/graphstate.py
  2. +24
    -15
      scripts/wtf.py
  3. +3
    -2
      tests/test_against_anders_and_briegel.py

+ 60
- 7
abp/graphstate.py View File

@@ -7,6 +7,9 @@ import json
import qi, clifford, util
import random

def debug(x):
pass

class GraphState(object):

def __init__(self, nodes=[]):
@@ -62,15 +65,28 @@ class GraphState(object):

def remove_vop(self, a, avoid):
""" Reduces VOP[a] to the identity """
#TODO: inefficient
others = set(self.adj[a]) - {avoid}
swap_qubit = others.pop() if others else avoid

debug("remove_byprod_op called: (v, avoid, vb):")
self.print_adj_list_line(a)
self.print_adj_list_line(avoid)
self.print_adj_list_line(swap_qubit)
debug("using {}".format(clifford.decompositions[self.node[a]["vop"]]))

for v in reversed(clifford.decompositions[self.node[a]["vop"]]):
self.local_complementation(a if v == "x" else swap_qubit)
assert self.node[a]["vop"]==0

debug("remove_byprod_op: after (v, avoid, vb):")
self.print_adj_list_line(a)
self.print_adj_list_line(avoid)
self.print_adj_list_line(swap_qubit)

def local_complementation(self, v):
""" As defined in LISTING 1 of Anders & Briegel """
debug("V ->Inverting about {}".format(self.get_adj_list_line(v)))
for i, j in it.combinations(self.adj[v], 2):
self.toggle_edge(i, j)

@@ -91,16 +107,23 @@ class GraphState(object):

def act_cz(self, a, b):
""" Act a controlled-phase gate on two qubits """
debug("before cphase between {} and {}".format(a, b))
self.print_adj_list_line(a)
self.print_adj_list_line(b)

ci = self.get_connection_info(a, b)
if ci["non1"]:
debug("cphase: left vertex has NONs -> putting it to Id")
self.remove_vop(a, b)

ci = self.get_connection_info(a, b)
if ci["non2"]:
debug("cphase: right vertex has NONs -> putting it to Id")
self.remove_vop(b, a)

ci = self.get_connection_info(a, b)
if ci["non1"] and not clifford.is_diagonal(self.node[a]["vop"]):
debug("cphase: left one needs treatment again -> putting it to Id")
self.remove_vop(b, a)

self.cz_with_table(a, b)
@@ -108,23 +131,41 @@ class GraphState(object):
def get_connection_info(self, a, b):
if self.has_edge(a, b):
return {"was_edge": True,
"non1": len(self.node.get(a, [])) > 0,
"non2": len(self.node.get(b, [])) > 0}
"non1": len(self.adj.get(a)) > 1,
"non2": len(self.adj.get(b)) > 1}
else:
return {"was_edge": False,
"non1": len(self.node.get(a, [])) > 1,
"non2": len(self.node.get(b, [])) > 1}
"non1": len(self.adj.get(a)) > 0,
"non2": len(self.adj.get(b)) > 0}

def cz_with_table(self, a, b):
""" Run the table """
debug("cphase_with_table called on:")
self.print_adj_list_line(a)
self.print_adj_list_line(b)

ci = self.get_connection_info(a, b)
assert ci["non1"]==False or clifford.is_diagonal(self.node[a]["vop"])
assert ci["non2"]==False or clifford.is_diagonal(self.node[b]["vop"])
try:
assert ci["non1"]==False or clifford.is_diagonal(self.node[a]["vop"])
assert ci["non2"]==False or clifford.is_diagonal(self.node[b]["vop"])
except AssertionError:
print ci
print self.node[a]["vop"]
print self.node[b]["vop"]
edge = self.has_edge(a, b)
new_edge, self.node[a]["vop"], self.node[
b]["vop"] = clifford.cz_table[edge, self.node[a]["vop"], self.node[b]["vop"]]
if new_edge != edge:
self.toggle_edge(a, b)
if new_edge:
debug("adding edge")
else:
debug("deling edge")

debug("cphase_with_table: after")
self.print_adj_list_line(a)
self.print_adj_list_line(b)

ci = self.get_connection_info(a, b)
assert ci["non1"]==False or clifford.is_diagonal(self.node[a]["vop"])
@@ -214,6 +255,18 @@ class GraphState(object):
rows.append(s)
return " \n".join(rows) + " \n"

def get_adj_list_line(self, key):
""" TODO: delete """
node = self.node[key]
adj = " ".join(map(str, sorted(self.adj[key])))
vop = clifford.get_name(node["vop"])
s = "Vertex {}: VOp {}, neighbors {}".format(key, vop, adj)
return s

def print_adj_list_line(self, key):
debug(self.get_adj_list_line(key))


def __eq__(self, other):
""" Check equality between graphs """
return self.adj == other.adj and self.node == other.node


+ 24
- 15
scripts/wtf.py View File

@@ -3,23 +3,32 @@ from anders_briegel import graphsim
import numpy as np
import itertools as it

a = GraphState()
a.node = {0: {'vop': 1}, 1: {'vop': 0}, 2: {'vop': 3}}
a.adj = {0: {1: {}, 2: {}}, 1: {0: {}}, 2: {0: {}}}

a.act_cz(1,2)
print a.adj_list()
""" This is an example of where we get a discrepancy """

def pete():
a = GraphState(xrange(3))
a.act_hadamard(0)
a.act_hadamard(1)
a.act_hadamard(2)
a.act_cz(0, 1)
a.act_cz(0, 2)
a.act_local_rotation(0, 1)
a.act_local_rotation(2, 3)
a.act_cz(1,2)
return a.adj_list()

def anders():
b = graphsim.GraphRegister(3)
b.hadamard(0)
b.hadamard(1)
b.hadamard(2)
b.cphase(0, 1)
b.cphase(0, 2)
b.local_op(0, graphsim.LocCliffOp(1))
b.local_op(2, graphsim.LocCliffOp(3))
b.cphase(1,2)
b.print_adj_list()

b = graphsim.GraphRegister(3)
b.hadamard(0)
b.hadamard(1)
b.hadamard(2)
b.cphase(0, 1)
b.cphase(0, 2)
b.local_op(0, graphsim.LocCliffOp(1))
b.local_op(2, graphsim.LocCliffOp(3))
pete()

b.cphase(1,2)
b.print_adj_list()

+ 3
- 2
tests/test_against_anders_and_briegel.py View File

@@ -133,8 +133,9 @@ def test_all(N=3):
b.act_hadamard(j)
else:
q = random.randint(0, N-2)
a.cphase(q, q+1)
b.act_cz(q, q+1)
if a!=b:
a.cphase(q, q+1)
b.act_cz(q, q+1)
compare(a, b)



Loading…
Cancel
Save