Pete Shadbolt 8 роки тому
джерело
коміт
b3ac940a17
8 змінених файлів з 44 додано та 73 видалено
  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 Переглянути файл

@@ -65,8 +65,7 @@ class GraphState(object):
others = set(self.adj[a]) - {avoid}
#TODO: this is a hack for determinsim. remove
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"]]):
if v == "x":
@@ -91,30 +90,29 @@ class GraphState(object):
self.node[v]["vop"] = clifford.times_table[
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)]
self.node[v]["vop"] = clifford.times_table[
self.node[v]["vop"], rotation]


def act_hadamard(self, qubit):
""" Shorthand """
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])

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

if self.lonely(b, a):
if self._lonely(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)

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

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

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

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

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

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


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

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

# Update the VOPs. TODO: pretty ugly
if result:
# 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}:
print "Z on", n
self.act_local_rotation2(n, "pz")
self._update_vop(n, "pz")
else:
# 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}:
print "Z on", n
self.act_local_rotation2(n, "pz")
self._update_vop(n, "pz")

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

return result

def measure_y(self, node, result):
def _measure_y(self, node, result):
""" Measure the graph in the Y-basis """
print "gYm{},{:d}".format(node, result)
# Do some rotations
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
vngbh = set(self.adj[node]) | {node}
for i, j in it.combinations(vngbh, 2):
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

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

# Rotate
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:
self.act_local_rotation2(node, "hadamard")
self._update_vop(node, "hadamard")

return result



+ 2
- 2
doc/index.rst Переглянути файл

@@ -7,10 +7,10 @@
: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.



+ 2
- 3
tests/test_against_anders_and_briegel.py Переглянути файл

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

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

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


+ 1
- 3
tests/test_against_circuit_model.py Переглянути файл

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

REPEATS = 10
DEPTH = 1000
from config import *

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


+ 1
- 5
tests/test_measurement.py Переглянути файл

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

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

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


+ 2
- 1
tests/test_measurement_against_anders_and_briegel.py Переглянути файл

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

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

def test_2qubit():


+ 10
- 10
tests/test_measurement_deterministic.py Переглянути файл

@@ -8,19 +8,19 @@ import itertools as it
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


+ 1
- 1
tests/test_single_qubit_measurement_against_anb.py Переглянути файл

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

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

def test_1():


Завантаження…
Відмінити
Зберегти