Browse Source

Working on measure_x

Added some more terms to clifford.by_name to ease lookup of complex
conjugates

Added GraphState.toggle_edges(), used by GraphState.measure_x

Nearly finished GraphState.measure_x
master
Pete Shadbolt 7 years ago
parent
commit
26569dfc32
5 changed files with 63 additions and 24 deletions
  1. +5
    -3
      abp/build_tables.py
  2. +43
    -12
      abp/graphstate.py
  3. +1
    -1
      abp/tables.py
  4. +1
    -1
      static/scripts/tables.js
  5. +13
    -7
      tests/test_measurement.py

+ 5
- 3
abp/build_tables.py View File

@@ -90,10 +90,11 @@ def get_unitaries():
return [compose_u(d) for d in DECOMPOSITIONS]


def get_by_name(unitaries):
def get_by_name(unitaries, conjugation_table):
""" Get a lookup table of cliffords by name """
a = {name: find_clifford(u, unitaries)
for name, u in qi.by_name.items()}
a.update({key+"_h": conjugation_table[value] for key, value in a.items()})
a.update({clifford.get_name(i): i for i in range(24)})
a.update({i: i for i in range(24)})
return a
@@ -183,10 +184,11 @@ def get_cz_table(unitaries):
def compute_everything():
""" Compute all lookup tables """
unitaries = get_unitaries()
conjugation_table = get_conjugation_table(unitaries)
return {"decompositions": DECOMPOSITIONS,
"unitaries": unitaries,
"by_name": get_by_name(unitaries),
"conjugation_table": get_conjugation_table(unitaries),
"by_name": get_by_name(unitaries, conjugation_table),
"conjugation_table": conjugation_table,
"times_table": get_times_table(unitaries),
"cz_table": get_cz_table(unitaries),
"measurement_table": get_measurement_table()}


+ 43
- 12
abp/graphstate.py View File

@@ -78,12 +78,10 @@ class GraphState(object):
for i, j in it.combinations(self.adj[v], 2):
self.toggle_edge(i, j)

msqx_h = clifford.conjugation_table[clifford.by_name["msqx"]]
sqz_h = clifford.conjugation_table[clifford.by_name["sqz"]]
self.node[v]["vop"] = clifford.times_table[self.node[v]["vop"], msqx_h]
self.node[v]["vop"] = clifford.times_table[self.node[v]["vop"], clifford.by_name["msqx_h"]]
for i in self.adj[v]:
self.node[i]["vop"] = clifford.times_table[
self.node[i]["vop"], sqz_h]
self.node[i]["vop"], clifford.by_name["sqz_h"]]

def act_local_rotation(self, v, op):
""" Act a local rotation """
@@ -137,30 +135,54 @@ class GraphState(object):
# TODO: put the asserts from graphsim.cpp into tests
return res

def measure_x(self, node, force=None):
""" Measure the graph in the X-basis """
if len(self.adj[node]) == 0:
return 0

# Flip a coin
result = force if force != None else random.choice([0, 1])
# Pick a vertex
friend = next(self.adj[node].iterkeys())

if not result:
# Do a z on all ngb(v) \ ngb(vb) \ {vb}, and sqy on the friend
self.act_local_rotation(friend, "sqy")
for n in set(self.adj[node]) - set(self.adj(friend)) - {friend}:
self.act_local_rotation(n, "pz")
else:
# Do a z on all ngb(vb) \ ngb(v) \ {v}, and some other stuff
self.act_local_rotation(node, "pz")
self.act_local_rotation(friend, "msqy")
for n in set(self.adj[friend]) - set(self.adj(node)) - {node}:
self.act_local_rotation(n, "pz")

# TODO: the really nasty bit


def measure_y(self, node, force=None):
""" Measure the graph in the Y-basis """
# Flip a coin
result = force if force != None else random.choice([0, 1])

# Do some rotations
rotation = clifford.conjugate("sqz" if result else "msqz")
for neighbour in self.adj[node]:
self.act_local_rotation(neighbour, rotation)
# NB: should these be hermitian_conjugated?
self.act_local_rotation(neighbour, "sqz" if result else "msqz")

# A sort of local complementation
vngbh = set(self.adj[node]) + {node}
vngbh = set(self.adj[node]) | {node}
for i, j in it.combinations(vngbh, 2):
self.toggle_edge(i, j)

if result:
self.act_local_rotation(node, "msqz")
else:
self.act_local_rotation(node, clifford.conjugate("msqz"))
self.act_local_rotation(node, "msqz" if result else "msqz_h")
return result



def measure_z(self, node, force=None):
""" Measure the graph in the Z-basis """
# Flip a coin
result = force if force != None else random.choice([0, 1])

# Disconnect
@@ -176,6 +198,15 @@ class GraphState(object):
self.act_local_rotation(node, "hadamard")
return result

def toggle_edge(a, b):
""" Toggle edges between vertex sets a and b """
done = {}
for i, j in it.product(a, b):
if i==j and not (i, j) in done:
done.add((i, j))
self.toggle_edge(i, j)


def order(self):
""" Get the number of qubits """
return len(self.node)


+ 1
- 1
abp/tables.py
File diff suppressed because it is too large
View File


+ 1
- 1
static/scripts/tables.js
File diff suppressed because it is too large
View File


+ 13
- 7
tests/test_measurement.py View File

@@ -6,11 +6,17 @@ def test_z_measurement():
assert g.measure_z(0, 0) == 0
assert g.measure_z(0, 1) == 1

def test_y_measurement():
g = GraphState([0])
assert g.measure_y(0, 0) == 0
assert g.measure_y(0, 1) == 1



def test_z_measurement_against_ab():
for i in range(10):
a = graphsim.GraphRegister(1)
b = GraphState()
b.add_node(0)
print a.measure(0, graphsim.lco_Z)
print b.measure(0, "pz")
#def test_z_measurement_against_ab():
#for i in range(10):
#a = graphsim.GraphRegister(1)
#b = GraphState()
#b.add_node(0)
#print a.measure(0, graphsim.lco_Z)
#print b.measure(0, "pz")

Loading…
Cancel
Save