Browse Source

Better naming

master
Pete Shadbolt 8 years ago
parent
commit
b3ac940a17
8 changed files with 44 additions and 73 deletions
  1. +25
    -48
      abp/graphstate.py
  2. +2
    -2
      doc/index.rst
  3. +2
    -3
      tests/test_against_anders_and_briegel.py
  4. +1
    -3
      tests/test_against_circuit_model.py
  5. +1
    -5
      tests/test_measurement.py
  6. +2
    -1
      tests/test_measurement_against_anders_and_briegel.py
  7. +10
    -10
      tests/test_measurement_deterministic.py
  8. +1
    -1
      tests/test_single_qubit_measurement_against_anb.py

+ 25
- 48
abp/graphstate.py View File

@@ -65,8 +65,7 @@ class GraphState(object):
others = set(self.adj[a]) - {avoid} others = set(self.adj[a]) - {avoid}
#TODO: this is a hack for determinsim. remove #TODO: this is a hack for determinsim. remove
swap_qubit = min(others) if others else avoid swap_qubit = min(others) if others else avoid
#swap_qubit = others.pop() if others else avoid # TODO: maybe this is the only problematic part
#print "SWAPPING WITH {} (options were {})".format(swap_qubit, tuple(others))
#swap_qubit = others.pop() if others else avoid


for v in reversed(clifford.decompositions[self.node[a]["vop"]]): for v in reversed(clifford.decompositions[self.node[a]["vop"]]):
if v == "x": if v == "x":
@@ -91,30 +90,29 @@ class GraphState(object):
self.node[v]["vop"] = clifford.times_table[ self.node[v]["vop"] = clifford.times_table[
rotation, self.node[v]["vop"]] rotation, self.node[v]["vop"]]


def act_local_rotation2(self, v, op):
""" Act a local rotation """
def _update_vop(self, v, op):
""" Update a VOP - only used internally"""
rotation = clifford.by_name[str(op)] rotation = clifford.by_name[str(op)]
self.node[v]["vop"] = clifford.times_table[ self.node[v]["vop"] = clifford.times_table[
self.node[v]["vop"], rotation] self.node[v]["vop"], rotation]



def act_hadamard(self, qubit): def act_hadamard(self, qubit):
""" Shorthand """ """ Shorthand """
self.act_local_rotation(qubit, 10) self.act_local_rotation(qubit, 10)


def lonely(self, a, b):
""" Is this qubit lonely ? """
def _lonely(self, a, b):
""" Is this qubit _lonely ? """
return len(self.adj[a]) > (b in self.adj[a]) return len(self.adj[a]) > (b in self.adj[a])


def act_cz(self, a, b): def act_cz(self, a, b):
""" Act a controlled-phase gate on two qubits """ """ Act a controlled-phase gate on two qubits """
if self.lonely(a, b):
if self._lonely(a, b):
self.remove_vop(a, b) self.remove_vop(a, b)


if self.lonely(b, a):
if self._lonely(b, a):
self.remove_vop(b, a) self.remove_vop(b, a)


if self.lonely(a, b) and not clifford.is_diagonal(self.node[a]["vop"]):
if self._lonely(a, b) and not clifford.is_diagonal(self.node[a]["vop"]):
self.remove_vop(a, b) self.remove_vop(a, b)


edge = self.has_edge(a, b) edge = self.has_edge(a, b)
@@ -131,9 +129,6 @@ class GraphState(object):
ha = clifford.conjugation_table[self.node[node]["vop"]] ha = clifford.conjugation_table[self.node[node]["vop"]]
basis, phase = clifford.conjugate(basis, ha) basis, phase = clifford.conjugate(basis, ha)


#print "MEASURE"
#print "Op: {} Phase: {}".format(basis, phase)

# Flip a coin # Flip a coin
result = force if force!=None else random.choice([0, 1]) result = force if force!=None else random.choice([0, 1])
# Flip the result if we have negative phase # Flip the result if we have negative phase
@@ -141,11 +136,11 @@ class GraphState(object):
result = not result result = not result


if basis == clifford.by_name["px"]: if basis == clifford.by_name["px"]:
result = self.measure_x(node, result)
result = self._measure_x(node, result)
elif basis == clifford.by_name["py"]: elif basis == clifford.by_name["py"]:
result = self.measure_y(node, result)
result = self._measure_y(node, result)
elif basis == clifford.by_name["pz"]: elif basis == clifford.by_name["pz"]:
result = self.measure_z(node, result)
result = self._measure_z(node, result)
else: else:
raise ValueError("You can only measure in {X,Y,Z}") raise ValueError("You can only measure in {X,Y,Z}")


@@ -165,39 +160,29 @@ class GraphState(object):
done.add((j, i)) done.add((j, i))
self.toggle_edge(i, j) self.toggle_edge(i, j)


def measure_x(self, node, result):
def _measure_x(self, node, result):
""" Measure the graph in the X-basis """ """ Measure the graph in the X-basis """
if len(self.adj[node]) == 0: if len(self.adj[node]) == 0:
print "gXm{},D".format(node)
return 0 return 0



print "gXm{},{:d}".format(node, result)

# Pick a vertex # Pick a vertex
#friend = next(self.adj[node].iterkeys()) #friend = next(self.adj[node].iterkeys())
# TODO this is enforced determinism for testing purposes # TODO this is enforced determinism for testing purposes
friend = sorted(self.adj[node].keys())[0] friend = sorted(self.adj[node].keys())[0]
print "Friend: {}".format(friend)


# Update the VOPs. TODO: pretty ugly # Update the VOPs. TODO: pretty ugly
if result: if result:
# Do a z on all ngb(vb) \ ngb(v) \ {v}, and some other stuff # Do a z on all ngb(vb) \ ngb(v) \ {v}, and some other stuff
self.act_local_rotation2(friend, "msqy")
self.act_local_rotation2(node, "pz")
self._update_vop(friend, "msqy")
self._update_vop(node, "pz")


print "sq(-Y) on", friend
print "Z on", node
for n in set(self.adj[friend]) - set(self.adj[node]) - {node}: for n in set(self.adj[friend]) - set(self.adj[node]) - {node}:
print "Z on", n
self.act_local_rotation2(n, "pz")
self._update_vop(n, "pz")
else: else:
# Do a z on all ngb(v) \ ngb(vb) \ {vb}, and sqy on the friend # Do a z on all ngb(v) \ ngb(vb) \ {vb}, and sqy on the friend
self.act_local_rotation2(friend, "sqy")
print "sq(Y) on", friend
self._update_vop(friend, "sqy")
for n in set(self.adj[node]) - set(self.adj[friend]) - {friend}: for n in set(self.adj[node]) - set(self.adj[friend]) - {friend}:
print "Z on", n
self.act_local_rotation2(n, "pz")
self._update_vop(n, "pz")


# Toggle the edges. TODO: Yuk. Just awful! # Toggle the edges. TODO: Yuk. Just awful!
a = set(self.adj[node].keys()) a = set(self.adj[node].keys())
@@ -212,42 +197,34 @@ class GraphState(object):


return result return result


def measure_y(self, node, result):
def _measure_y(self, node, result):
""" Measure the graph in the Y-basis """ """ Measure the graph in the Y-basis """
print "gYm{},{:d}".format(node, result)
# Do some rotations # Do some rotations
for neighbour in self.adj[node]: for neighbour in self.adj[node]:
# NB: should these be hermitian_conjugated?
self.act_local_rotation2(neighbour, "sqz" if result else "msqz")
self._update_vop(neighbour, "sqz" if result else "msqz")


# A sort of local complementation # 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): for i, j in it.combinations(vngbh, 2):
self.toggle_edge(i, j) self.toggle_edge(i, j)


# lcoS.herm_adjoint() if result else lcoS
# else smiZ
# 5 else 6
#print "RESULT is {:d}, op is {} doing {}".format(result, self.node[node]["vop"], 5 if result else 6)
self.act_local_rotation2(node, 5 if result else 6)
#print "BECAME ", self.node[node]["vop"]
self._update_vop(node, 5 if result else 6) # TODO: naming: # lcoS.herm_adjoint() if result else lcoS
return result return result


def measure_z(self, node, result):
def _measure_z(self, node, result):
""" Measure the graph in the Z-basis """ """ Measure the graph in the Z-basis """
print "gZm{},{:d}".format(node, result)
# Disconnect # Disconnect
for neighbour in tuple(self.adj[node]): for neighbour in tuple(self.adj[node]):
self.del_edge(node, neighbour) self.del_edge(node, neighbour)
if result: if result:
self.act_local_rotation2(neighbour, "pz")
self._update_vop(neighbour, "pz")


# Rotate # Rotate
if result: if result:
self.act_local_rotation2(node, "px")
self.act_local_rotation2(node, "hadamard")
self._update_vop(node, "px")
self._update_vop(node, "hadamard")
else: else:
self.act_local_rotation2(node, "hadamard")
self._update_vop(node, "hadamard")


return result return result




+ 2
- 2
doc/index.rst View File

@@ -7,10 +7,10 @@
:maxdepth: 2 :maxdepth: 2




Welcome to abp
Welcome to ``abp``
=============================== ===============================


This is the documentation for abp. It's a work in progress.
This is the documentation for ``abp``. It's a work in progress.


This is blah blah. Link to paper. Whatever. This is blah blah. Link to paper. Whatever.




+ 2
- 3
tests/test_against_anders_and_briegel.py View File

@@ -5,8 +5,8 @@ from abp import clifford
import random import random
import numpy as np import numpy as np
from tqdm import tqdm from tqdm import tqdm
REPEATS = 100000
import itertools as it
from config import *


def assert_equal(a, b, debug=""): def assert_equal(a, b, debug=""):
assert a.to_json() == b.to_json() assert a.to_json() == b.to_json()
@@ -142,7 +142,6 @@ def test_all(N=9):


a = graphsim.GraphRegister(N) a = graphsim.GraphRegister(N)
b = GraphState(range(N)) b = GraphState(range(N))
print "woi"
for i in tqdm(range(REPEATS), desc="Testing all gates against Anders and Briegel"): for i in tqdm(range(REPEATS), desc="Testing all gates against Anders and Briegel"):
if random.random()>0.5: if random.random()>0.5:
j = random.randint(0, N-1) j = random.randint(0, N-1)


+ 1
- 3
tests/test_against_circuit_model.py View File

@@ -4,9 +4,7 @@ from abp import clifford
import numpy as np import numpy as np
import random import random
from tqdm import tqdm from tqdm import tqdm

REPEATS = 10
DEPTH = 1000
from config import *


def test_single_qubit(): def test_single_qubit():
""" A multi qubit test with Hadamards only""" """ A multi qubit test with Hadamards only"""


+ 1
- 5
tests/test_measurement.py View File

@@ -4,11 +4,7 @@ from abp import qi, clifford
from anders_briegel import graphsim from anders_briegel import graphsim
from tqdm import tqdm from tqdm import tqdm
import random import random

REPEATS = 100000
LOCAL_ROTATION = 0
CZ = 1
MEASURE = 2
from config import *


def test_single_qubit_measurements(): def test_single_qubit_measurements():
""" Various simple tests of measurements """ """ Various simple tests of measurements """


+ 2
- 1
tests/test_measurement_against_anders_and_briegel.py View File

@@ -4,9 +4,10 @@ import numpy as np
from tqdm import tqdm from tqdm import tqdm
import dummy import dummy
import itertools as it import itertools as it
from config import *


N = 10 N = 10
REPEATS = 1000
m = {1: graphsim.lco_X, 2: graphsim.lco_Y, 3: graphsim.lco_Z} m = {1: graphsim.lco_X, 2: graphsim.lco_Y, 3: graphsim.lco_Z}


def test_2qubit(): def test_2qubit():


+ 10
- 10
tests/test_measurement_deterministic.py View File

@@ -8,19 +8,19 @@ import itertools as it
import networkx as nx import networkx as nx




def all_simple_graphs(filename="tests/graph5.g6"):
""" Generate all possible simple graphs """
with open(filename) as f:
for line in tqdm(f):
yield nx.parse_graph6(line.strip())
#def all_simple_graphs(filename="tests/graph5.g6"):
#""" Generate all possible simple graphs """
#with open(filename) as f:
#for line in tqdm(f):
#yield nx.parse_graph6(line.strip())
def rotated(simple_graphs):
for g in simple_graphs:
for r in it.product(*[range(24)]*2):
yield g, r
#def rotated(simple_graphs):
#for g in simple_graphs:
#for r in it.product(*[range(24)]*2):
#yield g, r




print len(list(rotated(all_simple_graphs())))
#print len(list(rotated(all_simple_graphs())))




#N = 3 #N = 3


+ 1
- 1
tests/test_single_qubit_measurement_against_anb.py View File

@@ -4,9 +4,9 @@ import numpy as np
from tqdm import tqdm from tqdm import tqdm
import itertools as it import itertools as it
import dummy import dummy
from config import *


N = 10 N = 10
REPEATS = 10
m = {1: graphsim.lco_X, 2: graphsim.lco_Y, 3: graphsim.lco_Z} m = {1: graphsim.lco_X, 2: graphsim.lco_Y, 3: graphsim.lco_Z}


def test_1(): def test_1():


Loading…
Cancel
Save