Browse Source

Ported to Python3 on a goddam phone

master
Pete Shadbolt 7 years ago
parent
commit
8b87991ea5
24 changed files with 106 additions and 115 deletions
  1. +12
    -13
      abp/build_tables.py
  2. +5
    -5
      abp/clifford.py
  3. +12
    -12
      abp/graphstate.py
  4. +6
    -6
      abp/nxgraphstate.py
  5. +3
    -3
      abp/qi.py
  6. +4
    -3
      abp/stabilizer.py
  7. +5
    -5
      abp/vizclient.py
  8. +7
    -7
      doc/conf.py
  9. +2
    -2
      examples/mix_graph_and_networkx.py
  10. +1
    -1
      examples/stabilizers.py
  11. +1
    -1
      examples/visualization/auto_layout.py
  12. +1
    -1
      examples/visualization/grid_2d.py
  13. +1
    -1
      examples/visualization/lattice_2d.py
  14. +1
    -1
      examples/visualization/lattice_3d.py
  15. +2
    -2
      examples/visualization/raussendorf.py
  16. +1
    -1
      examples/visualization/stress_test.py
  17. +8
    -9
      tests/mock.py
  18. +12
    -12
      tests/test_against_anders_and_briegel.py
  19. +6
    -13
      tests/test_clifford.py
  20. +7
    -7
      tests/test_graphstate.py
  21. +1
    -1
      tests/test_measurement.py
  22. +1
    -1
      tests/test_mercedes.py
  23. +3
    -4
      tests/test_qi.py
  24. +4
    -4
      tests/test_stabilizer.py

+ 12
- 13
abp/build_tables.py View File

@@ -4,12 +4,11 @@ This program computes lookup tables and stores them as tables.py and tables.js
""" """


import numpy as np import numpy as np
from tqdm import tqdm
import itertools as it import itertools as it
from functools import reduce from functools import reduce
from os.path import dirname, join, split from os.path import dirname, join, split
import json import json
import qi, clifford
from . import qi, clifford




DECOMPOSITIONS = ( DECOMPOSITIONS = (
@@ -52,8 +51,8 @@ def find_cz(bond, c1, c2, commuters, state_table):
target = qi.normalize_global_phase(target) target = qi.normalize_global_phase(target)


# Choose the sets to search over # Choose the sets to search over
s1 = commuters if c1 in commuters else xrange(24)
s2 = commuters if c2 in commuters else xrange(24)
s1 = commuters if c1 in commuters else range(24)
s2 = commuters if c2 in commuters else range(24)


# Find a match # Find a match
for bondp, c1p, c2p in it.product([0, 1], s1, s2): for bondp, c1p, c2p in it.product([0, 1], s1, s2):
@@ -79,9 +78,9 @@ def get_unitaries():
def get_by_name(unitaries, conjugation_table): def get_by_name(unitaries, conjugation_table):
""" Get a lookup table of cliffords by name """ """ Get a lookup table of cliffords by name """
a = {name: find_clifford(u, unitaries) a = {name: find_clifford(u, unitaries)
for name, u in qi.by_name.items()}
for name, u in list(qi.by_name.items())}
a.update({key + "_h": conjugation_table[value] a.update({key + "_h": conjugation_table[value]
for key, value in a.items()})
for key, value in list(a.items())})
a.update({clifford.get_name(i): i for i in range(24)}) a.update({clifford.get_name(i): i for i in range(24)})
a.update({i: i for i in range(24)}) a.update({i: i for i in range(24)})
return a return a
@@ -95,14 +94,14 @@ def get_conjugation_table(unitaries):
def get_times_table(unitaries): def get_times_table(unitaries):
""" Construct the times-table """ """ Construct the times-table """
return np.array([[find_clifford(u.dot(v), unitaries) for v in unitaries] return np.array([[find_clifford(u.dot(v), unitaries) for v in unitaries]
for u in tqdm(unitaries, desc="Building times-table")], dtype=int)
for u in unitaries], dtype=int)




def get_state_table(unitaries): def get_state_table(unitaries):
""" Cache a table of state to speed up a little bit """ """ Cache a table of state to speed up a little bit """
state_table = np.zeros((2, 24, 24, 4), dtype=complex) state_table = np.zeros((2, 24, 24, 4), dtype=complex)
params = list(it.product([0, 1], range(24), range(24)))
for bond, i, j in tqdm(params, desc="Building state table"):
params = list(it.product([0, 1], list(range(24)), list(range(24))))
for bond, i, j in params:
state = qi.bond if bond else qi.nobond state = qi.bond if bond else qi.nobond
kp = np.kron(unitaries[i], unitaries[j]) kp = np.kron(unitaries[i], unitaries[j])
state_table[bond, i, j, :] = qi.normalize_global_phase( state_table[bond, i, j, :] = qi.normalize_global_phase(
@@ -137,7 +136,7 @@ def get_measurement_table():
This is pretty unintelligible right now, we should probably compute the phase from unitaries instead This is pretty unintelligible right now, we should probably compute the phase from unitaries instead
""" """
measurement_table = np.zeros((4, 24, 2), dtype=int) measurement_table = np.zeros((4, 24, 2), dtype=int)
for operator, unitary in it.product(range(4), range(24)):
for operator, unitary in it.product(list(range(4)), list(range(24))):
measurement_table[operator, unitary] = get_measurement_entry( measurement_table[operator, unitary] = get_measurement_entry(
operator, unitary) operator, unitary)
return measurement_table return measurement_table
@@ -158,9 +157,9 @@ def get_cz_table(unitaries):
# And now build the CZ table # And now build the CZ table
cz_table = np.zeros((2, 24, 24, 3), dtype=int) cz_table = np.zeros((2, 24, 24, 3), dtype=int)
rows = list( rows = list(
it.product([0, 1], it.combinations_with_replacement(range(24), 2)))
it.product([0, 1], it.combinations_with_replacement(list(range(24)), 2)))
# CZ is symmetric so we only need combinations # CZ is symmetric so we only need combinations
for bond, (c1, c2) in tqdm(rows, desc="Building CZ table"):
for bond, (c1, c2) in rows:
newbond, c1p, c2p = find_cz( newbond, c1p, c2p = find_cz(
bond, c1, c2, commuters, state_table) bond, c1, c2, commuters, state_table)
cz_table[bond, c1, c2] = [newbond, c1p, c2p] cz_table[bond, c1, c2] = [newbond, c1p, c2p]
@@ -174,7 +173,7 @@ def get_display_table(unitaries):
c = qi.CircuitModel(1) c = qi.CircuitModel(1)
c.act_local_rotation(0, u) c.act_local_rotation(0, u)
state = c.state.round(2) state = c.state.round(2)
print "{:.2f}, {:.2f}".format(state[0][0], state[1][0])
print("{:.2f}, {:.2f}".format(state[0][0], state[1][0]))




def compute_everything(): def compute_everything():


+ 5
- 5
abp/clifford.py View File

@@ -40,7 +40,7 @@ The complete set of aliases for single-qubit Cliffords is as follows:


""" """


from tables import *
from .tables import *


# Aliases # Aliases
identity = by_name["identity"] identity = by_name["identity"]
@@ -58,7 +58,7 @@ def conjugate(operator, unitary):
def use_old_cz(): def use_old_cz():
""" Use the CZ lookup table from A&B's code, rather than our own. Useful for testing. """ """ Use the CZ lookup table from A&B's code, rather than our own. Useful for testing. """
global cz_table global cz_table
from anders_cz import cz_table
from .anders_cz import cz_table


def get_name(i): def get_name(i):
""" Get the name of this clifford """ """ Get the name of this clifford """
@@ -66,7 +66,7 @@ def get_name(i):


def human_name(i): def human_name(i):
""" Get the human-readable name of this clifford - slow """ """ Get the human-readable name of this clifford - slow """
choices = sorted((key for key, value in by_name.items() if value == i), key=len)
choices = sorted((key for key, value in list(by_name.items()) if value == i), key=len)
return choices[-1] return choices[-1]


def is_diagonal(v): def is_diagonal(v):
@@ -78,9 +78,9 @@ if __name__ == '__main__':
from itertools import groupby from itertools import groupby


for i in range(24): for i in range(24):
members = [key for key, value in by_name.items() if value == i and str(key)!=str(i)]
members = [key for key, value in list(by_name.items()) if value == i and str(key)!=str(i)]
members = sorted(members, key=len) members = sorted(members, key=len)
print "* {}: {}".format(i, ", ".join(members))
print("* {}: {}".format(i, ", ".join(members)))





+ 12
- 12
abp/graphstate.py View File

@@ -6,9 +6,9 @@ This module implements Anders and Briegel's method for fast simulation of Cliffo


import itertools as it import itertools as it
import json, random import json, random
import qi, clifford, util
from . import qi, clifford, util
import abp import abp
from stabilizer import Stabilizer
from .stabilizer import Stabilizer




class GraphState(object): class GraphState(object):
@@ -30,7 +30,7 @@ class GraphState(object):
# Cloning from a networkx graph # Cloning from a networkx graph
self.adj = data.adj.copy() self.adj = data.adj.copy()
self.node = data.node.copy() self.node = data.node.copy()
for key, value in self.node.items():
for key, value in list(self.node.items()):
self.node[key]["vop"] = data.node[ self.node[key]["vop"] = data.node[
key].get("vop", clifford.identity) key].get("vop", clifford.identity)
except AttributeError: except AttributeError:
@@ -66,7 +66,7 @@ class GraphState(object):
By default, nodes are initialized with ``vop=``:math:`I`, i.e. they are in the :math:`|+\\rangle` state. By default, nodes are initialized with ``vop=``:math:`I`, i.e. they are in the :math:`|+\\rangle` state.
""" """
if node in self.node: if node in self.node:
print "Warning: node {} already exists".format(node)
print("Warning: node {} already exists".format(node))
return return


default = kwargs.get("default", "identity") default = kwargs.get("default", "identity")
@@ -141,7 +141,7 @@ class GraphState(object):
def edgelist(self): def edgelist(self):
""" Describe a graph as an edgelist # TODO: inefficient """ """ Describe a graph as an edgelist # TODO: inefficient """
edges = set(tuple(sorted((i, n))) edges = set(tuple(sorted((i, n)))
for i, v in self.adj.items()
for i, v in list(self.adj.items())
for n in v) for n in v)
return tuple(edges) return tuple(edges)


@@ -305,7 +305,7 @@ class GraphState(object):
""" """
forces = forces if forces != None else [ forces = forces if forces != None else [
random.choice([0, 1]) for i in range(len(measurements))] random.choice([0, 1]) for i in range(len(measurements))]
measurements = zip(measurements, forces)
measurements = list(zip(measurements, forces))
results = [] results = []
for (node, basis), force in measurements: for (node, basis), force in measurements:
result = self.measure(node, basis, force, detail) result = self.measure(node, basis, force, detail)
@@ -333,9 +333,9 @@ class GraphState(object):
if abp.DETERMINISTIC: if abp.DETERMINISTIC:
friend = sorted(self.adj[node].keys())[0] friend = sorted(self.adj[node].keys())[0]
else: else:
friend = next(self.adj[node].iterkeys())
friend = next(iter(self.adj[node].keys()))
else: else:
assert friend in self.adj[node].keys() # TODO: unnecessary assert
assert friend in list(self.adj[node].keys()) # TODO: unnecessary assert


# Update the VOPs. TODO: pretty ugly # Update the VOPs. TODO: pretty ugly
if result: if result:
@@ -427,9 +427,9 @@ class GraphState(object):


""" """
if stringify: if stringify:
node = {str(key): value for key, value in self.node.items()}
adj = {str(key): {str(key): value for key, value in ngbh.items()}
for key, ngbh in self.adj.items()}
node = {str(key): value for key, value in list(self.node.items())}
adj = {str(key): {str(key): value for key, value in list(ngbh.items())}
for key, ngbh in list(self.adj.items())}
return {"node": node, "adj": adj} return {"node": node, "adj": adj}
else: else:
return {"node": self.node, "adj": self.adj} return {"node": self.node, "adj": self.adj}
@@ -460,7 +460,7 @@ class GraphState(object):
state.act_hadamard(mapping[n]) state.act_hadamard(mapping[n])
for i, j in self.edgelist(): for i, j in self.edgelist():
state.act_cz(mapping[i], mapping[j]) state.act_cz(mapping[i], mapping[j])
for i, n in self.node.items():
for i, n in list(self.node.items()):
state.act_local_rotation(mapping[i], clifford.unitaries[n["vop"]]) state.act_local_rotation(mapping[i], clifford.unitaries[n["vop"]])
return state return state




+ 6
- 6
abp/nxgraphstate.py View File

@@ -1,8 +1,8 @@
import networkx as nx import networkx as nx
import numpy as np import numpy as np
import graphstate
import clifford
import util
from . import graphstate
from . import clifford
from . import util


class NXGraphState(graphstate.GraphState, nx.Graph): class NXGraphState(graphstate.GraphState, nx.Graph):
""" This is GraphState with NetworkX-like abilities """ """ This is GraphState with NetworkX-like abilities """
@@ -12,8 +12,8 @@ class NXGraphState(graphstate.GraphState, nx.Graph):
def layout(self): def layout(self):
""" Automatically lay out the graph """ """ Automatically lay out the graph """
pos = nx.spring_layout(self, dim=3, scale=np.sqrt(self.order())) pos = nx.spring_layout(self, dim=3, scale=np.sqrt(self.order()))
middle = np.average(pos.values(), axis=0)
pos = {key: value - middle for key, value in pos.items()}
for key, (x, y, z) in pos.items():
middle = np.average(list(pos.values()), axis=0)
pos = {key: value - middle for key, value in list(pos.items())}
for key, (x, y, z) in list(pos.items()):
self.node[key]["position"] = util.xyz(x, y, z) self.node[key]["position"] = util.xyz(x, y, z)



+ 3
- 3
abp/qi.py View File

@@ -52,7 +52,7 @@ nobond = np.kron(plus, plus)
# Labelling stuff # Labelling stuff
common_us = id, px, py, pz, ha, ph, sqz, msqz, sqy, msqy, sqx, msqx common_us = id, px, py, pz, ha, ph, sqz, msqz, sqy, msqy, sqx, msqx
names = "identity", "px", "py", "pz", "hadamard", "phase", "sqz", "msqz", "sqy", "msqy", "sqx", "msqx" names = "identity", "px", "py", "pz", "hadamard", "phase", "sqz", "msqz", "sqy", "msqy", "sqx", "msqx"
by_name = dict(zip(names, common_us))
by_name = dict(list(zip(names, common_us)))


paulis = px, py, pz paulis = px, py, pz
operators = id, px, py, pz operators = id, px, py, pz
@@ -60,7 +60,7 @@ operators = id, px, py, pz


def normalize_global_phase(m): def normalize_global_phase(m):
""" Normalize the global phase of a matrix """ """ Normalize the global phase of a matrix """
v = (x for x in m.flatten() if np.abs(x) > 0.001).next()
v = next((x for x in m.flatten() if np.abs(x) > 0.001))
phase = np.arctan2(v.imag, v.real) % np.pi phase = np.arctan2(v.imag, v.real) % np.pi
rot = np.exp(-1j * phase) rot = np.exp(-1j * phase)
return rot * m if rot * v > 0 else -rot * m return rot * m if rot * v > 0 else -rot * m
@@ -78,7 +78,7 @@ class CircuitModel(object):
""" Act a CU somewhere. """ """ Act a CU somewhere. """
control = 1 << control control = 1 << control
target = 1 << target target = 1 << target
for i in xrange(self.d):
for i in range(self.d):
if (i & control) and (i & target): if (i & control) and (i & target):
self.state[i, 0] *= -1 self.state[i, 0] *= -1




+ 4
- 3
abp/stabilizer.py View File

@@ -31,15 +31,16 @@ class Stabilizer(object):
""" For comparison with old A&B code """ """ For comparison with old A&B code """
m = {1: 0, 1j:1, -1: 2, -1j: 3} m = {1: 0, 1j:1, -1: 2, -1j: 3}
return {"paulis": self.tableau, return {"paulis": self.tableau,
"phases": {key: m[value] for key, value in self.phases.items()}}
"phases": {key: m[value] for key, value in list(self.phases.items())}}


def __getitem__(self, (i, j)):
def __getitem__(self, xxx_todo_changeme):
"""" Pass straight through to the dictionary """ """" Pass straight through to the dictionary """
(i, j) = xxx_todo_changeme
return self.tableau[i][j] return self.tableau[i][j]


def __str__(self): def __str__(self):
""" Represent as a string """ """ Represent as a string """
keys = map(str, self.tableau.keys())
keys = list(map(str, list(self.tableau.keys())))
w = max(len(k) for k in keys) w = max(len(k) for k in keys)
keys = [k.ljust(w) for k in keys] keys = [k.ljust(w) for k in keys]
s = " {}\n".format(" ".join(map(str, keys))) s = " {}\n".format(" ".join(map(str, keys)))


+ 5
- 5
abp/vizclient.py View File

@@ -3,9 +3,9 @@ import networkx as nx
import numpy as np import numpy as np
import websocket import websocket
from socket import error as socket_error from socket import error as socket_error
import clifford
import util
import nxgraphstate
from . import clifford
from . import util
from . import nxgraphstate


class VizClient(object): class VizClient(object):
def __init__(self, uri = "ws://localhost:5000"): def __init__(self, uri = "ws://localhost:5000"):
@@ -21,7 +21,7 @@ class VizClient(object):
g = nxgraphstate.NXGraphState(graph) g = nxgraphstate.NXGraphState(graph)


# Automatically perform layout if position is not provided # Automatically perform layout if position is not provided
if not all(("position" in node) for node in g.node.values()):
if not all(("position" in node) for node in list(g.node.values())):
g.layout() g.layout()


# Send data to browser and rate-limit # Send data to browser and rate-limit
@@ -29,7 +29,7 @@ class VizClient(object):
self.ws.send(json.dumps(g.to_json(stringify=True))) self.ws.send(json.dumps(g.to_json(stringify=True)))
self.ws.recv() self.ws.recv()
except websocket._exceptions.WebSocketTimeoutException: except websocket._exceptions.WebSocketTimeoutException:
print "Timed out ... you might be pushing a bit hard"
print("Timed out ... you might be pushing a bit hard")
time.sleep(delay) time.sleep(delay)





+ 7
- 7
doc/conf.py View File

@@ -51,9 +51,9 @@ source_suffix = '.rst'
master_doc = 'index' master_doc = 'index'


# General information about the project. # General information about the project.
project = u'abp'
copyright = u'2016, Pete Shadbolt'
author = u'Pete Shadbolt'
project = 'abp'
copyright = '2016, Pete Shadbolt'
author = 'Pete Shadbolt'


# The version info for the project you're documenting, acts as replacement for # The version info for the project you're documenting, acts as replacement for
# |version| and |release|, also used in various other places throughout the # |version| and |release|, also used in various other places throughout the
@@ -227,8 +227,8 @@ latex_elements = {
# (source start file, target name, title, # (source start file, target name, title,
# author, documentclass [howto, manual, or own class]). # author, documentclass [howto, manual, or own class]).
latex_documents = [ latex_documents = [
(master_doc, 'abp.tex', u'abp Documentation',
u'Pete Shadbolt', 'manual'),
(master_doc, 'abp.tex', 'abp Documentation',
'Pete Shadbolt', 'manual'),
] ]


# The name of an image file (relative to this directory) to place at the top of # The name of an image file (relative to this directory) to place at the top of
@@ -257,7 +257,7 @@ latex_documents = [
# One entry per manual page. List of tuples # One entry per manual page. List of tuples
# (source start file, name, description, authors, manual section). # (source start file, name, description, authors, manual section).
man_pages = [ man_pages = [
(master_doc, 'abp', u'abp Documentation',
(master_doc, 'abp', 'abp Documentation',
[author], 1) [author], 1)
] ]


@@ -271,7 +271,7 @@ man_pages = [
# (source start file, target name, title, author, # (source start file, target name, title, author,
# dir menu entry, description, category) # dir menu entry, description, category)
texinfo_documents = [ texinfo_documents = [
(master_doc, 'abp', u'abp Documentation',
(master_doc, 'abp', 'abp Documentation',
author, 'abp', 'One line description of project.', author, 'abp', 'One line description of project.',
'Miscellaneous'), 'Miscellaneous'),
] ]


+ 2
- 2
examples/mix_graph_and_networkx.py View File

@@ -3,8 +3,8 @@ from abp.util import xyz
import networkx as nx import networkx as nx


n = 10 n = 10
g = NXGraphState(range(n))
g = NXGraphState(list(range(n)))
nx.set_node_attributes(g, "color", "red") nx.set_node_attributes(g, "color", "red")
g.add_edges_from([i, i+1] for i in range(n-1)) g.add_edges_from([i, i+1] for i in range(n-1))
print g.node[0]["color"]
print(g.node[0]["color"])



+ 1
- 1
examples/stabilizers.py View File

@@ -7,5 +7,5 @@ g.act_circuit((edge, "cz") for edge in edges)


g.act_local_rotation(3, 9) g.act_local_rotation(3, 9)


print g.to_stabilizer()
print(g.to_stabilizer())



+ 1
- 1
examples/visualization/auto_layout.py View File

@@ -35,7 +35,7 @@ def offset_unit_cell(unit_cell, offset):
def lattice(unit_cell, size): def lattice(unit_cell, size):
""" Generate a lattice from a unit cell """ """ Generate a lattice from a unit cell """
edges = set() edges = set()
for offset in itertools.product(*map(range, size)):
for offset in itertools.product(*list(map(range, size))):
edges |= offset_unit_cell(unit_cell, offset) edges |= offset_unit_cell(unit_cell, offset)


nodes = set(itertools.chain(*edges)) nodes = set(itertools.chain(*edges))


+ 1
- 1
examples/visualization/grid_2d.py View File

@@ -5,7 +5,7 @@ import itertools
def grid_2d(width, height): def grid_2d(width, height):
""" Make a 2D grid """ """ Make a 2D grid """
psi = GraphState() psi = GraphState()
grid = list(itertools.product(range(width), range(height)))
grid = list(itertools.product(list(range(width)), list(range(height))))


for x, y in grid: for x, y in grid:
psi.add_qubit((x, y), position=xyz(x, y, 0), vop=0) psi.add_qubit((x, y), position=xyz(x, y, 0), vop=0)


+ 1
- 1
examples/visualization/lattice_2d.py View File

@@ -23,7 +23,7 @@ def offset_unit_cell(unit_cell, offset):
def lattice(unit_cell, size): def lattice(unit_cell, size):
""" Generate a lattice from a unit cell """ """ Generate a lattice from a unit cell """
edges = set() edges = set()
for offset in itertools.product(*map(range, size)):
for offset in itertools.product(*list(map(range, size))):
edges |= offset_unit_cell(unit_cell, offset) edges |= offset_unit_cell(unit_cell, offset)


nodes = set(itertools.chain(*edges)) nodes = set(itertools.chain(*edges))


+ 1
- 1
examples/visualization/lattice_3d.py View File

@@ -35,7 +35,7 @@ def offset_unit_cell(unit_cell, offset):
def lattice(unit_cell, size): def lattice(unit_cell, size):
""" Generate a lattice from a unit cell """ """ Generate a lattice from a unit cell """
edges = set() edges = set()
for offset in itertools.product(*map(range, size)):
for offset in itertools.product(*list(map(range, size))):
edges |= offset_unit_cell(unit_cell, offset) edges |= offset_unit_cell(unit_cell, offset)


nodes = set(itertools.chain(*edges)) nodes = set(itertools.chain(*edges))


+ 2
- 2
examples/visualization/raussendorf.py View File

@@ -33,7 +33,7 @@ def offset_unit_cell(unit_cell, offset):
def lattice(unit_cell, size): def lattice(unit_cell, size):
""" Generate a lattice from a unit cell """ """ Generate a lattice from a unit cell """
edges = set() edges = set()
for offset in itertools.product(*map(range, size)):
for offset in itertools.product(*list(map(range, size))):
edges |= offset_unit_cell(unit_cell, offset) edges |= offset_unit_cell(unit_cell, offset)


nodes = set(itertools.chain(*edges)) nodes = set(itertools.chain(*edges))
@@ -45,7 +45,7 @@ psi = GraphState()
for node in nodes: for node in nodes:
x, y, z = node x, y, z = node
color = "red" if (x+y+z) % 2 > 0 else "black" color = "red" if (x+y+z) % 2 > 0 else "black"
print color
print(color)
psi.add_qubit(node, position=xyz(*node), color=color) psi.add_qubit(node, position=xyz(*node), color=color)
psi.act_hadamard(node) psi.act_hadamard(node)




+ 1
- 1
examples/visualization/stress_test.py View File

@@ -23,7 +23,7 @@ def offset_unit_cell(unit_cell, offset):
def lattice(unit_cell, size): def lattice(unit_cell, size):
""" Generate a lattice from a unit cell """ """ Generate a lattice from a unit cell """
edges = set() edges = set()
for offset in itertools.product(*map(range, size)):
for offset in itertools.product(*list(map(range, size))):
edges |= offset_unit_cell(unit_cell, offset) edges |= offset_unit_cell(unit_cell, offset)


nodes = set(itertools.chain(*edges)) nodes = set(itertools.chain(*edges))


+ 8
- 9
tests/mock.py View File

@@ -6,7 +6,6 @@ import numpy as np
import abp import abp
from abp import GraphState, clifford, qi from abp import GraphState, clifford, qi
from numpy import random from numpy import random
import nose
try: try:
from anders_briegel import graphsim from anders_briegel import graphsim
except ImportError: except ImportError:
@@ -21,7 +20,7 @@ class AndersWrapper(graphsim.GraphRegister):
""" A wrapper for A&B to make the interface identical and enable equality testing """ """ A wrapper for A&B to make the interface identical and enable equality testing """


def __init__(self, nodes): def __init__(self, nodes):
assert list(nodes) == range(len(nodes))
assert list(nodes) == list(range(len(nodes)))
super(AndersWrapper, self).__init__(len(nodes)) super(AndersWrapper, self).__init__(len(nodes))


def act_local_rotation(self, qubit, operation): def act_local_rotation(self, qubit, operation):
@@ -58,7 +57,7 @@ class ABPWrapper(GraphState):
super(ABPWrapper, self).__init__(nodes, vop="hadamard") super(ABPWrapper, self).__init__(nodes, vop="hadamard")


def print_stabilizer(self): def print_stabilizer(self):
print self.to_stabilizer()
print(self.to_stabilizer())


def __eq__(self, other): def __eq__(self, other):
return self.to_json() == other.to_json() return self.to_json() == other.to_json()
@@ -67,7 +66,7 @@ class ABPWrapper(GraphState):
class CircuitModelWrapper(qi.CircuitModel): class CircuitModelWrapper(qi.CircuitModel):


def __init__(self, nodes=[]): def __init__(self, nodes=[]):
assert list(nodes) == range(len(nodes))
assert list(nodes) == list(range(len(nodes)))
super(CircuitModelWrapper, self).__init__(len(nodes)) super(CircuitModelWrapper, self).__init__(len(nodes))


def act_circuit(self, circuit): def act_circuit(self, circuit):
@@ -82,19 +81,19 @@ class CircuitModelWrapper(qi.CircuitModel):


def random_pair(n): def random_pair(n):
""" Helper function to get random pairs""" """ Helper function to get random pairs"""
return tuple(random.choice(range(n), 2, replace=False))
return tuple(random.choice(list(range(n)), 2, replace=False))




def random_graph_circuit(n=10, depth=100): def random_graph_circuit(n=10, depth=100):
""" A random Graph state. """ """ A random Graph state. """
return [(i, "hadamard") for i in xrange(n)] + \
[(random_pair(n), "cz") for i in xrange(depth)]
return [(i, "hadamard") for i in range(n)] + \
[(random_pair(n), "cz") for i in range(depth)]




def random_stabilizer_circuit(n=10, depth=100): def random_stabilizer_circuit(n=10, depth=100):
""" Generate a random stabilizer state, without any VOPs """ """ Generate a random stabilizer state, without any VOPs """
return random_graph_circuit(n, depth) + \ return random_graph_circuit(n, depth) + \
[(i, random.choice(range(24))) for i in range(n)]
[(i, random.choice(list(range(24)))) for i in range(n)]




def bell_pair(): def bell_pair():
@@ -122,7 +121,7 @@ def simple_graph():


def circuit_to_state(Base, n, circuit): def circuit_to_state(Base, n, circuit):
""" Convert a circuit to a state, given a base class """ """ Convert a circuit to a state, given a base class """
g = Base(range(n))
g = Base(list(range(n)))
g.act_circuit(circuit) g.act_circuit(circuit)
return g return g




+ 12
- 12
tests/test_against_anders_and_briegel.py View File

@@ -17,48 +17,48 @@ def test_hadamard():


def test_local_rotations(): def test_local_rotations():
""" Test local rotations """ """ Test local rotations """
for i in tqdm(range(REPEATS), "Testing local rotations"):
circuit = [(0, random.choice(range(24))) for j in range(DEPTH)]
for i in tqdm(list(range(REPEATS)), "Testing local rotations"):
circuit = [(0, random.choice(list(range(24)))) for j in range(DEPTH)]
mock.test_circuit(circuit, 1) mock.test_circuit(circuit, 1)




def test_times_table(): def test_times_table():
""" Test times table """ """ Test times table """
for i, j in it.product(range(24), range(24)):
for i, j in it.product(list(range(24)), list(range(24))):
circuit = [(0, i), (0, j)] circuit = [(0, i), (0, j)]
mock.test_circuit(circuit, 1) mock.test_circuit(circuit, 1)




def test_cz_table(): def test_cz_table():
""" Test the CZ table """ """ Test the CZ table """
for i, j in it.product(range(24), range(24)):
for i, j in it.product(list(range(24)), list(range(24))):
circuit = [(0, i), (1, j), ((0, 1), "cz")] circuit = [(0, i), (1, j), ((0, 1), "cz")]
mock.test_circuit(circuit, 2) mock.test_circuit(circuit, 2)




def test_cz_hadamard(n=10): def test_cz_hadamard(n=10):
""" Test CZs and Hadamards at random """ """ Test CZs and Hadamards at random """
for i in tqdm(range(REPEATS), desc="Testing CZ and Hadamard against A&B"):
for i in tqdm(list(range(REPEATS)), desc="Testing CZ and Hadamard against A&B"):
circuit = random.choice(["cz", "hadamard"], DEPTH) circuit = random.choice(["cz", "hadamard"], DEPTH)
circuit = [(mock.random_pair(n), gate) if gate == "cz" circuit = [(mock.random_pair(n), gate) if gate == "cz"
else (random.choice(range(n)), gate)
else (random.choice(list(range(n))), gate)
for gate in circuit] for gate in circuit]
mock.test_circuit(circuit, n) mock.test_circuit(circuit, n)




def test_all(n=10): def test_all(n=10):
""" Test everything """ """ Test everything """
for i in tqdm(range(REPEATS), desc="Testing CZ and Hadamard against A&B"):
circuit = random.choice(["cz"] * 10 + range(24), DEPTH)
for i in tqdm(list(range(REPEATS)), desc="Testing CZ and Hadamard against A&B"):
circuit = random.choice(["cz"] * 10 + list(range(24)), DEPTH)
circuit = [(mock.random_pair(n), gate) if gate == "cz" circuit = [(mock.random_pair(n), gate) if gate == "cz"
else (random.choice(range(n)), gate)
else (random.choice(list(range(n))), gate)
for gate in circuit] for gate in circuit]
mock.test_circuit(circuit, n) mock.test_circuit(circuit, n)




def test_single_qubit_measurement(): def test_single_qubit_measurement():
""" Determinstic test of all single-qubit situations """ """ Determinstic test of all single-qubit situations """
space = it.product(range(24), PAULIS, (0, 1))
space = it.product(list(range(24)), PAULIS, (0, 1))
for rotation, measurement, outcome in tqdm(space, "Testing single qubit measurements"): for rotation, measurement, outcome in tqdm(space, "Testing single qubit measurements"):
a = mock.circuit_to_state(mock.ABPWrapper, 1, [(0, rotation)]) a = mock.circuit_to_state(mock.ABPWrapper, 1, [(0, rotation)])
b = mock.circuit_to_state(mock.AndersWrapper, 1, [(0, rotation)]) b = mock.circuit_to_state(mock.AndersWrapper, 1, [(0, rotation)])
@@ -79,7 +79,7 @@ def test_two_qubit_measurement():
def test_graph_state_measurement(n = 10): def test_graph_state_measurement(n = 10):
""" Measuring random graph states """ """ Measuring random graph states """
space = list(it.product(range(REPEATS), PAULIS, (0, 1)))
space = list(it.product(list(range(REPEATS)), PAULIS, (0, 1)))
for i, measurement, outcome in tqdm(space, "Measuring random graph states"): for i, measurement, outcome in tqdm(space, "Measuring random graph states"):
circuit = mock.random_graph_circuit(n, DEPTH) circuit = mock.random_graph_circuit(n, DEPTH)
a = mock.circuit_to_state(mock.ABPWrapper, n, circuit) a = mock.circuit_to_state(mock.ABPWrapper, n, circuit)
@@ -90,7 +90,7 @@ def test_graph_state_measurement(n = 10):


def test_stabilizer_state_measurement(n = 10): def test_stabilizer_state_measurement(n = 10):
""" Measuring random stabilizer states """ """ Measuring random stabilizer states """
space = list(it.product(range(REPEATS), PAULIS, (0, 1)))
space = list(it.product(list(range(REPEATS)), PAULIS, (0, 1)))
for i, measurement, outcome in tqdm(space, "Measuring random stabilizer states"): for i, measurement, outcome in tqdm(space, "Measuring random stabilizer states"):
circuit = mock.random_stabilizer_circuit(n, DEPTH) circuit = mock.random_stabilizer_circuit(n, DEPTH)
a = mock.circuit_to_state(mock.ABPWrapper, n, circuit) a = mock.circuit_to_state(mock.ABPWrapper, n, circuit)


+ 6
- 13
tests/test_clifford.py View File

@@ -1,11 +1,9 @@
import numpy as np import numpy as np
from tqdm import tqdm
import itertools as it import itertools as it
from abp import clifford from abp import clifford
from abp import build_tables from abp import build_tables
from abp import qi from abp import qi
import nose
from nose.tools import raises
import pytest




def identify_pauli(m): def identify_pauli(m):
@@ -22,11 +20,6 @@ def test_find_clifford():
assert build_tables.find_clifford(qi.px, clifford.unitaries) == 1 assert build_tables.find_clifford(qi.px, clifford.unitaries) == 1




@raises(IndexError)
def test_find_non_clifford():
""" Test that looking for a non-Clifford gate fails """
build_tables.find_clifford(qi.t, clifford.unitaries)



def get_action(u): def get_action(u):
""" What does this unitary operator do to the Paulis? """ """ What does this unitary operator do to the Paulis? """
@@ -45,14 +38,14 @@ def test_we_have_24_matrices():


def test_we_have_all_useful_gates(): def test_we_have_all_useful_gates():
""" Check that all the interesting gates are included up to a global phase """ """ Check that all the interesting gates are included up to a global phase """
for name, u in qi.by_name.items():
for name, u in list(qi.by_name.items()):
build_tables.find_clifford(u, clifford.unitaries) build_tables.find_clifford(u, clifford.unitaries)




def test_group(): def test_group():
""" Test we are really in a group """ """ Test we are really in a group """
matches = set() matches = set()
for a, b in tqdm(it.combinations(clifford.unitaries, 2), "Testing this is a group"):
for a, b in it.combinations(clifford.unitaries, 2):
i = build_tables.find_clifford(a.dot(b), clifford.unitaries) i = build_tables.find_clifford(a.dot(b), clifford.unitaries)
matches.add(i) matches.add(i)
assert len(matches) == 24 assert len(matches) == 24
@@ -82,10 +75,10 @@ def test_conjugation():
try: try:
from anders_briegel import graphsim from anders_briegel import graphsim
except ImportError: except ImportError:
raise nose.SkipTest("Original C++ is not available, skipping test")
pytest.skip("Original C++ is not available, skipping test")


for operation_index, transform_index in it.product(range(4), range(24)):
for operation_index, transform_index in it.product(list(range(4)), list(range(24))):
transform = graphsim.LocCliffOp(transform_index) transform = graphsim.LocCliffOp(transform_index)
operation = graphsim.LocCliffOp(operation_index) operation = graphsim.LocCliffOp(operation_index)


@@ -103,7 +96,7 @@ def test_cz_table():
""" Does the CZ code work good? """ """ Does the CZ code work good? """
state_table = build_tables.get_state_table(clifford.unitaries) state_table = build_tables.get_state_table(clifford.unitaries)


rows = it.product([0, 1], it.combinations_with_replacement(range(24), 2))
rows = it.product([0, 1], it.combinations_with_replacement(list(range(24)), 2))


for bond, (c1, c2) in rows: for bond, (c1, c2) in rows:




+ 7
- 7
tests/test_graphstate.py View File

@@ -65,9 +65,9 @@ def test_edgelist():
def test_stress(n=int(1e5)): def test_stress(n=int(1e5)):
""" Testing that making a graph of ten thousand qubits takes less than half a second""" """ Testing that making a graph of ten thousand qubits takes less than half a second"""
import time import time
g = GraphState(range(n + 1), vop="hadamard")
g = GraphState(list(range(n + 1)), vop="hadamard")
t = time.clock() t = time.clock()
for i in xrange(n):
for i in range(n):
g._add_edge(i, i + 1) g._add_edge(i, i + 1)
assert time.clock() - t < .5 assert time.clock() - t < .5


@@ -93,7 +93,7 @@ def test_czs():
def test_local_complementation(): def test_local_complementation():
""" Test that local complementation works okay """ """ Test that local complementation works okay """
pairs = (0, 1), (0, 3), (1, 3), (1, 2), pairs = (0, 1), (0, 3), (1, 3), (1, 2),
psi = GraphState(range(4), vop="hadamard")
psi = GraphState(list(range(4)), vop="hadamard")
psi.act_circuit([(i, "hadamard") for i in psi.node]) psi.act_circuit([(i, "hadamard") for i in psi.node])
psi.act_circuit([(pair, "cz") for pair in pairs]) psi.act_circuit([(pair, "cz") for pair in pairs])
old_edges = psi.edgelist() old_edges = psi.edgelist()
@@ -105,8 +105,8 @@ def test_local_complementation():


def test_single_qubit(): def test_single_qubit():
""" A multi qubit test with Hadamards only""" """ A multi qubit test with Hadamards only"""
for repeat in tqdm(range(REPEATS), desc="Single qubit rotations against CircuitModel"):
circuit = [(0, random.choice(range(24))) for i in range(DEPTH)]
for repeat in tqdm(list(range(REPEATS)), desc="Single qubit rotations against CircuitModel"):
circuit = [(0, random.choice(list(range(24)))) for i in range(DEPTH)]
a = mock.circuit_to_state(mock.ABPWrapper, 1, circuit) a = mock.circuit_to_state(mock.ABPWrapper, 1, circuit)
b = mock.circuit_to_state(mock.CircuitModelWrapper, 1, circuit) b = mock.circuit_to_state(mock.CircuitModelWrapper, 1, circuit)
assert a.to_state_vector() == b assert a.to_state_vector() == b
@@ -114,7 +114,7 @@ def test_single_qubit():


def test_graph_state_multiqubit(n=6): def test_graph_state_multiqubit(n=6):
""" A multi qubit test with Hadamards only""" """ A multi qubit test with Hadamards only"""
for repeat in tqdm(range(REPEATS), desc="Random graph states against the CircuitModel"):
for repeat in tqdm(list(range(REPEATS)), desc="Random graph states against the CircuitModel"):
circuit = mock.random_graph_circuit(n) circuit = mock.random_graph_circuit(n)
a = mock.circuit_to_state(mock.ABPWrapper, n, circuit) a = mock.circuit_to_state(mock.ABPWrapper, n, circuit)
b = mock.circuit_to_state(mock.CircuitModelWrapper, n, circuit) b = mock.circuit_to_state(mock.CircuitModelWrapper, n, circuit)
@@ -123,7 +123,7 @@ def test_graph_state_multiqubit(n=6):


def test_stabilizer_state_multiqubit(n=6): def test_stabilizer_state_multiqubit(n=6):
""" A multi qubit test with arbitrary local rotations """ """ A multi qubit test with arbitrary local rotations """
for repeat in tqdm(range(REPEATS), desc="Random Clifford circuits against the CircuitModel"):
for repeat in tqdm(list(range(REPEATS)), desc="Random Clifford circuits against the CircuitModel"):
circuit = mock.random_stabilizer_circuit(n) circuit = mock.random_stabilizer_circuit(n)
a = mock.circuit_to_state(mock.ABPWrapper, n, circuit) a = mock.circuit_to_state(mock.ABPWrapper, n, circuit)
b = mock.circuit_to_state(mock.CircuitModelWrapper, n, circuit) b = mock.circuit_to_state(mock.CircuitModelWrapper, n, circuit)


+ 1
- 1
tests/test_measurement.py View File

@@ -29,7 +29,7 @@ def test_single_qubit_measurements():


def test_type(): def test_type():
""" Test that the output is always an int """ """ Test that the output is always an int """
for r, m, f in it.product(range(24), ("px", "py", "pz"), (0, 1)):
for r, m, f in it.product(list(range(24)), ("px", "py", "pz"), (0, 1)):
g = GraphState([0], vop="hadamard") g = GraphState([0], vop="hadamard")
g.act_local_rotation(0, r) g.act_local_rotation(0, r)
assert str(g.measure(0, m)) in "01" assert str(g.measure(0, m)) in "01"


+ 1
- 1
tests/test_mercedes.py View File

@@ -3,7 +3,7 @@ from abp.util import xyz
from mock import simple_graph from mock import simple_graph


def linear_cluster(n): def linear_cluster(n):
g = GraphState(range(n), vop="hadamard")
g = GraphState(list(range(n)), vop="hadamard")
g.act_circuit([(i, "hadamard") for i in range(n)]) g.act_circuit([(i, "hadamard") for i in range(n)])
g.act_circuit([((i, i+1), "cz") for i in range(n-1)]) g.act_circuit([((i, i+1), "cz") for i in range(n-1)])
return g return g


+ 3
- 4
tests/test_qi.py View File

@@ -2,7 +2,6 @@ import numpy as np
from abp import qi, GraphState from abp import qi, GraphState
from tqdm import tqdm from tqdm import tqdm
import mock import mock
import nose


DEPTH = 1000 DEPTH = 1000


@@ -135,7 +134,7 @@ def test_against_chp(n=5):
ket = chp.get_ket() ket = chp.get_ket()
nonzero = np.sqrt(len(ket)) nonzero = np.sqrt(len(ket))
output.state[0, 0] = 0 output.state[0, 0] = 0
for key, phase in ket.items():
for key, phase in list(ket.items()):
output.state[key] = np.exp(1j * phase * np.pi / 2) / nonzero output.state[key] = np.exp(1j * phase * np.pi / 2) / nonzero
return output return output


@@ -151,7 +150,7 @@ def test_against_chp(n=5):
# Run a random circuit # Run a random circuit
chp.init(n) chp.init(n)
psi = qi.CircuitModel(n) psi = qi.CircuitModel(n)
for i in tqdm(range(DEPTH), "Testing CircuitModel against CHP"):
for i in tqdm(list(range(DEPTH)), "Testing CircuitModel against CHP"):
if np.random.rand() > .5: if np.random.rand() > .5:
a = np.random.randint(0, n - 1) a = np.random.randint(0, n - 1)
chp.act_hadamard(a) chp.act_hadamard(a)
@@ -166,7 +165,7 @@ def test_against_chp(n=5):
def test_sqrt_notation(n=2): def test_sqrt_notation(n=2):
""" Test that SQRT notation looks nice """ """ Test that SQRT notation looks nice """
c = mock.random_stabilizer_circuit(n) c = mock.random_stabilizer_circuit(n)
g = GraphState(range(n))
g = GraphState(list(range(n)))
g.act_circuit(c) g.act_circuit(c)


def test_indexint(): def test_indexint():


+ 4
- 4
tests/test_stabilizer.py View File

@@ -7,13 +7,13 @@ REPEATS = 1000
def test_stabilizers_against_anders_and_briegel(n=10): def test_stabilizers_against_anders_and_briegel(n=10):
""" Test that stabilizers are line-for-line equivalent """ """ Test that stabilizers are line-for-line equivalent """
for i in tqdm(range(REPEATS), "Stabilizer representation VS A&B"):
for i in tqdm(list(range(REPEATS)), "Stabilizer representation VS A&B"):
c = mock.random_stabilizer_circuit(n) c = mock.random_stabilizer_circuit(n)
g = mock.AndersWrapper(range(n))
g = mock.AndersWrapper(list(range(n)))
g.act_circuit(c) g.act_circuit(c)
da = g.get_full_stabilizer().to_dictionary() da = g.get_full_stabilizer().to_dictionary()


g = mock.ABPWrapper(range(n))
g = mock.ABPWrapper(list(range(n)))
g.act_circuit(c) g.act_circuit(c)
db = g.to_stabilizer().to_dictionary() db = g.to_stabilizer().to_dictionary()


@@ -21,4 +21,4 @@ def test_stabilizers_against_anders_and_briegel(n=10):


def test_stabilizer_access(): def test_stabilizer_access():
g = GraphState(3) g = GraphState(3)
print g.to_stabilizer()[0, 0]
print(g.to_stabilizer()[0, 0])

Loading…
Cancel
Save