From 9776d3e10a66e2d29e2109dcd57c00fb63343726 Mon Sep 17 00:00:00 2001 From: Pete Shadbolt Date: Sun, 24 Jul 2016 22:17:12 +0100 Subject: [PATCH] Better mocking - not finished --- abp/graphstate.py | 43 +++++++++++++----- tests/mock.py | 109 ++++++++++++++++++++++++---------------------- 2 files changed, 88 insertions(+), 64 deletions(-) diff --git a/abp/graphstate.py b/abp/graphstate.py index 23befd2..736873e 100644 --- a/abp/graphstate.py +++ b/abp/graphstate.py @@ -25,26 +25,47 @@ class GraphState(object): self.add_nodes(nodes) self.deterministic = deterministic - def add_node(self, v, **kwargs): - """ Add a node """ - assert not v in self.node - self.adj[v] = {} - self.node[v] = {"vop": clifford.by_name["hadamard"]} - self.node[v].update(kwargs) + def add_node(self, node, **kwargs): + """ Add a node + + :param node: The name of the node, e.g. ``9``, ``start`` + :type node: Any hashable type + """ + assert not node in self.node, "Node {} already exists".format(v) + self.adj[node] = {} + self.node[node] = {"vop": clifford.by_name["hadamard"]} + self.node[node].update(kwargs) def add_nodes(self, nodes): """ Add a buncha nodes """ for n in nodes: self.add_node(n) + def act_circuit(self, circuit): + """ Run many gates in one call + + :param circuit: An iterable containing tuples of the form ``(node, operation)``. + If ``operation`` is a name for a local operation (e.g. ``6``, ``hadamard``) then that operation is performed on ``node``. + If ``operation`` is ``"cz"`` then a CZ is performed on the two nodes in ``node. + + For example:: + + >>> g.act_circuit([(0, "hadamard"), (1, "hadamard"), ((0, 1), "cz")]) + + """ + for node, operation in circuit: + if operation == "cz": + self.act_cz(*node) + else: + self.act_local_rotation(node, operation) + def _add_edge(self, v1, v2, data={}): - """ Add an edge between two vertices """ - assert v1 != v2 + """ Add an edge between two vertices """ self.adj[v1][v2] = data self.adj[v2][v1] = data def _del_edge(self, v1, v2): - """ Delete an edge between two vertices """ + """ Delete an edge between two vertices """ del self.adj[v1][v2] del self.adj[v2][v1] @@ -312,9 +333,7 @@ class GraphState(object): return output def __eq__(self, other): - """ Check equality between graphs """ - if str(type(other)) == "": - return self.to_json() == other.to_json() + """ Check equality between GraphStates """ return self.adj == other.adj and self.node == other.node if __name__ == '__main__': diff --git a/tests/mock.py b/tests/mock.py index 60d7eae..2963a5b 100644 --- a/tests/mock.py +++ b/tests/mock.py @@ -5,6 +5,7 @@ Mock graphs used for testing import numpy as np from abp import GraphState, clifford from anders_briegel import graphsim +from numpy import random # We always run with A&B's CZ table when we are testing clifford.use_old_cz() @@ -18,82 +19,86 @@ class AndersWrapper(graphsim.GraphRegister): assert list(nodes) == range(len(nodes)) super(AndersWrapper, self).__init__(len(nodes)) - def act_local_rotation(qubit, operation): - super(AndersWrapper, self).local_op( - qubit, graphsim.LocCliffOp(operation)) + def act_local_rotation(self, qubit, operation): + operation = clifford.by_name[str(operation)] + op = graphsim.LocCliffOp(operation) + super(AndersWrapper, self).local_op(qubit, op) - def act_cz(a, b): + def act_cz(self, a, b): super(AndersWrapper, self).cphase(a, b) - def measure(qubit, basis, force): + def measure(self, qubit, basis, force): basis = clifford.by_name[basis] 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) - def __str__(self): - return "A wrapped A&B state ({})".format(super(AndersWrapper, self).__str__()) + def __eq__(self, other): + return self.to_json() == other.to_json() - def __repr__(self): - return self.__str__() + def act_circuit(self, circuit): + for node, operation in circuit: + if operation == "cz": + self.act_cz(*node) + else: + self.act_local_rotation(node, operation) -class PeteWrapper(GraphState): + +class ABPWrapper(GraphState): """ A wrapper for abp, just to ensure determinism """ -def random_graph_state(N=10): - """ A random Graph state. """ + def __init__(self, nodes=[]): + super(ABPWrapper, self).__init__(nodes, deterministic = True) - for base in PeteWrapper, AndersWrapper: - g = base(range(N)) - for i in range(N): - g.act_hadamard(i) +def random_pair(n): + """ Helper function to get random pairs""" + return tuple(random.choice(range(n), 2, replace=False)) - for i in range(10): - j, k = np.random.choice(range(N), 2, replace=False) - g.act_cz(j, k) +def random_graph_state(n=10): + """ A random Graph state. """ + 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)] + for g in random_graph_state(): + g.act_circuit(rotations) + yield g -def random_stabilizer_state(N=10): - a, b = random_state() +def bell_pair(): + for Base in AndersWrapper, ABPWrapper: + g = Base((0, 1)) + g.act_circuit(((0, "hadamard"), (1, "hadamard"), ((0, 1), "cz"))) + yield g - 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)) +def onequbit(): + for Base in AndersWrapper, ABPWrapper: + g = Base((0,)) + yield g - return a, b +def named_node_graph(): + """ A graph with named nodes""" + edges = (0, 1), (1, 2), (2, 0), (0, 3), (100, 200), (200, "named") + g = ABPWrapper([0, 1, 2, 3, 100, 200, "named"]) + 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 -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 + a, b = random_stabilizer_state() + assert a == b + print named_node_graph() -def onequbit(): - a = GraphState(range(1)) - b = graphsim.GraphRegister(1) - return a, b - - -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