Browse Source

Tidying tests

master
Pete Shadbolt 7 years ago
parent
commit
3b6963c95e
13 changed files with 169 additions and 165 deletions
  1. +1
    -1
      README.md
  2. +1
    -1
      setup.py
  3. +0
    -13
      tests/demograph.py
  4. +0
    -53
      tests/dummy.py
  5. +17
    -5
      tests/mock.py
  6. +0
    -14
      tests/old/test_circuit_model_fails.py
  7. +0
    -7
      tests/old/test_clifford_names.py
  8. +0
    -24
      tests/old/test_conjugation.py
  9. +0
    -27
      tests/old/test_cphase_table.py
  10. +0
    -15
      tests/old/test_get_state_vector.py
  11. +42
    -2
      tests/test_clifford.py
  12. +76
    -0
      tests/test_graphstate.py
  13. +32
    -3
      tests/test_qi.py

+ 1
- 1
README.md View File

@@ -1,6 +1,6 @@
# abp

Python port of Anders and Briegel' s [method](https://arxiv.org/abs/quant-ph/0504117) for fast simulation of Clifford circuits. You can read the full documentation [here](https://peteshadbolt.co.uk/abp/).
Python port of Anders and Briegel' s [method](https://arxiv.org/abs/quant-ph/0504117) for fast simulation of Clifford circuits. You can read the full documentation [here](https://peteshadbolt.co.uk/abp/).

![demo](examples/demo.gif)



+ 1
- 1
setup.py View File

@@ -6,7 +6,7 @@ STATIC = glob("static/*.*")+glob("static/img/*.*")+glob("static/scripts/*.*")

setup(
name = "abp",
version = "0.4.1",
version = "0.4.2",
packages = find_packages(),
test_suite = "tests",
author = "Pete Shadbolt",


+ 0
- 13
tests/demograph.py View File

@@ -1,13 +0,0 @@
from abp import GraphState

def demograph():
""" A graph for testing with """
g = GraphState([0,1,2,3,100,200])
g.add_edge(0, 1)
g.add_edge(1, 2)
g.add_edge(2, 0)
g.add_edge(0, 3)
g.add_edge(100, 200)
return g



+ 0
- 53
tests/dummy.py View File

@@ -1,53 +0,0 @@
from abp import GraphState, clifford
from anders_briegel import graphsim
import numpy as np

def clean_random_state(N=10):
""" A state to test on """
a = GraphState(range(N))
b = graphsim.GraphRegister(N)
clifford.use_old_cz()

for i in range(N):
a.act_hadamard(i)
b.hadamard(i)

for i in range(10):
j, k= np.random.choice(range(N), 2, replace=False)
a.act_cz(j, k)
b.cphase(j, k)

return a, b

def messy_random_state(N=10):
a, b = clean_random_state(N)
for i in range(N):
a.act_hadamard(i)
b.hadamard(i)

for i in range(N):
j, k= np.random.choice(range(N), 2, replace=False)
a.act_cz(j, k)
b.cphase(j, k)

for i in range(N):
j = np.random.choice(range(N))
k = np.random.choice(range(24))
a.act_local_rotation(j, k)
b.local_op(j, graphsim.LocCliffOp(k))

return a, b

def bell():
a = GraphState(range(2))
b = graphsim.GraphRegister(2)
a.act_hadamard(0); a.act_hadamard(1);
b.hadamard(0); b.hadamard(1);
a.act_cz(0,1)
b.cphase(0,1)
return a, b

def onequbit():
a = GraphState(range(1))
b = graphsim.GraphRegister(1)
return a, b

+ 17
- 5
tests/mock.py View File

@@ -29,8 +29,8 @@ class AndersWrapper(graphsim.GraphRegister):

def measure(self, qubit, basis, force):
basis = clifford.by_name[basis]
basis = {1: graphsim.lco_X,
2: graphsim.lco_Y,
basis = {1: graphsim.lco_X,
2: graphsim.lco_Y,
3: graphsim.lco_Z}[clifford.by_name[basis]]
super(AndersWrapper, self).measure(qubit, basis, None, force)

@@ -50,7 +50,7 @@ class ABPWrapper(GraphState):
""" A wrapper for abp, just to ensure determinism """

def __init__(self, nodes=[]):
super(ABPWrapper, self).__init__(nodes, deterministic = True)
super(ABPWrapper, self).__init__(nodes, deterministic=True)


def random_pair(n):
@@ -60,13 +60,14 @@ def random_pair(n):

def random_graph_state(n=10):
""" A random Graph state. """
czs = [(random_pair(n), "cz") for i in range(n*2)]
czs = [(random_pair(n), "cz") for i in range(n * 2)]
for Base in AndersWrapper, ABPWrapper:
g = Base(range(n))
g.act_circuit((i, "hadamard") for i in range(n))
g.act_circuit(czs)
yield g


def random_stabilizer_state(n=10):
""" Generate a random stabilizer state, without any VOPs """
rotations = [(i, random.choice(range(24))) for i in range(n)]
@@ -74,17 +75,20 @@ def random_stabilizer_state(n=10):
g.act_circuit(rotations)
yield g


def bell_pair():
for Base in AndersWrapper, ABPWrapper:
g = Base((0, 1))
g.act_circuit(((0, "hadamard"), (1, "hadamard"), ((0, 1), "cz")))
yield g


def onequbit():
for Base in AndersWrapper, ABPWrapper:
g = Base((0,))
yield g


def named_node_graph():
""" A graph with named nodes"""
edges = (0, 1), (1, 2), (2, 0), (0, 3), (100, 200), (200, "named")
@@ -93,6 +97,15 @@ def named_node_graph():
g.act_circuit((edge, "cz") for edge in edges)
return g

def simple_graph():
""" A simple graph to test with"""
edges = (0, 1), (1, 2), (2, 0), (0, 3), (100, 200)
g = ABPWrapper([0, 1, 2, 3, 100, 200])
g.act_circuit((i, "hadamard") for i in g.node)
g.act_circuit((edge, "cz") for edge in edges)
return g


if __name__ == '__main__':
a, b = random_graph_state()
assert a == b
@@ -101,4 +114,3 @@ if __name__ == '__main__':
assert a == b

print named_node_graph()


+ 0
- 14
tests/old/test_circuit_model_fails.py View File

@@ -1,14 +0,0 @@
from abp import qi

def test_dumbness():
a = qi.CircuitModel(1)
b = qi.CircuitModel(1)
assert a == b

a.act_local_rotation(0, qi.px)

assert not (a == b)

a.act_local_rotation(0, qi.px)

assert (a == b)

+ 0
- 7
tests/old/test_clifford_names.py View File

@@ -1,7 +0,0 @@
from abp import clifford

def test_names():
""" Test the naming scheme """
for i in range(24):
clifford.get_name(i)
assert clifford.get_name(16)=="IE"

+ 0
- 24
tests/old/test_conjugation.py View File

@@ -1,24 +0,0 @@
from anders_briegel import graphsim
from abp import clifford
import itertools

#//! replaces op by trans * op * trans^dagger and returns a phase,
#/*! either +1 or -1 (as RightPhase(0) or RightPhase(2)) */

def test_conjugation():
""" Test that clifford.conugate() agrees with graphsim.LocCliffOp.conjugate """
for operation_index, transform_index in itertools.product(range(4), range(24)):
transform = graphsim.LocCliffOp(transform_index)
operation = graphsim.LocCliffOp(operation_index)

phase = operation.conjugate(transform).ph
if phase == 1:
print phase
phase = [1, 0, -1][phase]
new_operation = operation.op

NEW_OPERATION, PHASE = clifford.conjugate(operation_index, transform_index)
print new_operation, NEW_OPERATION, " ",
assert new_operation == NEW_OPERATION
assert PHASE == phase


+ 0
- 27
tests/old/test_cphase_table.py View File

@@ -1,27 +0,0 @@
import numpy as np
from abp import clifford, qi, build_tables
import itertools as it

def test_cz_table():
""" Does the CZ code work good? """
state_table = build_tables.get_state_table(clifford.unitaries)

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

for bond, (c1, c2) in rows:

# Pick the input state
input_state = state_table[bond, c1, c2]

# Go and compute the output
computed_output = np.dot(qi.cz, input_state)
computed_output = qi.normalize_global_phase(computed_output)

# Now look up the answer in the table
bondp, c1p, c2p = clifford.cz_table[bond, c1, c2]
table_output = state_table[bondp, c1p, c2p]

assert np.allclose(computed_output, table_output)




+ 0
- 15
tests/old/test_get_state_vector.py View File

@@ -1,15 +0,0 @@
from abp import GraphState
from abp import qi
import numpy as np

def test_single_qubit():
""" Test some single-qubit stuff """
g = GraphState()
g.add_node(0)
g.add_node(1)
g.act_local_rotation(0, "hadamard")
g.act_local_rotation(1, "hadamard")
g.act_cz(0, 1)
assert np.allclose(g.to_state_vector().state, qi.bond)



tests/old/test_clifford.py → tests/test_clifford.py View File

@@ -1,17 +1,18 @@
from numpy import *
import numpy as np
from tqdm import tqdm
import itertools as it
from abp import clifford
from abp import build_tables
from abp import qi
from nose.tools import raises
from anders_briegel import graphsim


def identify_pauli(m):
""" Given a signed Pauli matrix, name it. """
for sign in (+1, -1):
for pauli_label, pauli in zip("xyz", qi.paulis):
if allclose(sign * pauli, m):
if np.allclose(sign * pauli, m):
return sign, pauli_label


@@ -70,6 +71,45 @@ def test_cz_table_makes_sense():
assert all(
clifford.cz_table[0, hadamard, hadamard] == [0, hadamard, hadamard])


def test_commuters():
""" Test that commutation is good """
assert len(build_tables.get_commuters(clifford.unitaries)) == 4


def test_conjugation():
""" Test that clifford.conugate() agrees with graphsim.LocCliffOp.conjugate """
for operation_index, transform_index in it.product(range(4), range(24)):
transform = graphsim.LocCliffOp(transform_index)
operation = graphsim.LocCliffOp(operation_index)

phase = operation.conjugate(transform).ph
phase = [1, 0, -1][phase]
new_operation = operation.op

NEW_OPERATION, PHASE = clifford.conjugate(
operation_index, transform_index)
assert new_operation == NEW_OPERATION
assert PHASE == phase


def test_cz_table():
""" Does the CZ code work good? """
state_table = build_tables.get_state_table(clifford.unitaries)

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

for bond, (c1, c2) in rows:

# Pick the input state
input_state = state_table[bond, c1, c2]

# Go and compute the output
computed_output = np.dot(qi.cz, input_state)
computed_output = qi.normalize_global_phase(computed_output)

# Now look up the answer in the table
bondp, c1p, c2p = clifford.cz_table[bond, c1, c2]
table_output = state_table[bondp, c1p, c2p]

assert np.allclose(computed_output, table_output)

+ 76
- 0
tests/test_graphstate.py View File

@@ -0,0 +1,76 @@
from abp import GraphState
from abp import clifford
from mock import simple_graph
import time


def test_graph_basic():
""" Test that we can construct graphs, delete edges, whatever """
g = simple_graph()
assert set(g.adj[0].keys()) == set([1, 2, 3])
g._del_edge(0, 1)
assert set(g.adj[0].keys()) == set([2, 3])
assert g.has_edge(1, 2)
assert not g.has_edge(0, 1)


def test_local_complementation():
""" Test that local complementation works as expected """
g = simple_graph()
g.local_complementation(0)
assert g.has_edge(0, 1)
assert g.has_edge(0, 2)
assert not g.has_edge(1, 2)
assert g.has_edge(3, 2)
assert g.has_edge(3, 1)

# TODO: test VOP conditions


def test_remove_vop():
""" Test that removing VOPs really works """
g = simple_graph()
g.remove_vop(0, 1)
assert g.node[0]["vop"] == clifford.by_name["identity"]
g.remove_vop(1, 1)
assert g.node[1]["vop"] == clifford.by_name["identity"]
g.remove_vop(2, 1)
assert g.node[2]["vop"] == clifford.by_name["identity"]
g.remove_vop(0, 1)
assert g.node[0]["vop"] == clifford.by_name["identity"]


def test_edgelist():
""" Test making edgelists """
g = simple_graph()
el = g.edgelist()
assert (0, 3) in el
assert (0, 2) in el
assert (100, 200) in el


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


def test_cz():
""" Test CZ gate """
g = GraphState([0, 1])
g.act_local_rotation(0, clifford.by_name["hadamard"])
g.act_local_rotation(1, clifford.by_name["hadamard"])
g.act_local_rotation(1, clifford.by_name["py"])
assert not g.has_edge(0, 1)
g.act_cz(0, 1)
assert g.has_edge(0, 1)

def test_stabilizer():
""" Test that we can generate stabilizers okay """
g = simple_graph()
stab = g.to_stabilizer()
#TODO


tests/old/test_qi_circuit_model.py → tests/test_qi.py View File

@@ -1,11 +1,14 @@
import numpy as np
from abp import qi
from abp import GraphState


def test_init():
""" Can you initialize some qubits """
psi = qi.CircuitModel(5)
assert psi.d == 32


def test_single_qubit_stuff():
""" Try some sensible single-qubit things """
psi = qi.CircuitModel(2)
@@ -18,6 +21,7 @@ def test_single_qubit_stuff():
psi.act_local_rotation(0, qi.px)
assert np.allclose(psi.state[0], -1)


def test_further_single_qubit_stuff():
""" Try some sensible single-qubit things """
psi = qi.CircuitModel(2)
@@ -37,6 +41,7 @@ def test_more_single_qubit_stuff():
psi.act_local_rotation(1, qi.px)
psi.act_cz(0, 1)


def test_equality():
""" Test that equality succeeds / fails as desired """
a = qi.CircuitModel(2)
@@ -46,17 +51,17 @@ def test_equality():
assert a != b



def test_hadamard():
""" What does CZ do ? """
psi = qi.CircuitModel(3)
psi.act_hadamard(0)
psi.act_hadamard(1)
assert np.allclose(psi.state, np.array([[1,1,1,1,0,0,0,0]]).T/2.)
assert np.allclose(psi.state, np.array([[1, 1, 1, 1, 0, 0, 0, 0]]).T / 2.)
psi.act_hadamard(1)
psi.act_hadamard(0)
psi.act_hadamard(2)
assert np.allclose(psi.state, qi.ir2*np.array([[1,0,0,0,1,0,0,0]]).T)
assert np.allclose(
psi.state, qi.ir2 * np.array([[1, 0, 0, 0, 1, 0, 0, 0]]).T)


def test_cz():
@@ -82,3 +87,27 @@ def test_local_rotation():
assert np.allclose(psi.state[0], 1)


def test_dumbness():
""" Check that I haven't done something really dumb """
a = qi.CircuitModel(1)
b = qi.CircuitModel(1)
assert a == b

a.act_local_rotation(0, qi.px)

assert not (a == b)

a.act_local_rotation(0, qi.px)

assert (a == b)


def test_to_state_vector_single_qubit():
""" Test some single-qubit stuff """
g = GraphState()
g.add_node(0)
g.add_node(1)
g.act_local_rotation(0, "hadamard")
g.act_local_rotation(1, "hadamard")
g.act_cz(0, 1)
assert np.allclose(g.to_state_vector().state, qi.bond)

Loading…
Cancel
Save