From bd55821c11622a5beb22bbbdaf7c7d14faff79cc Mon Sep 17 00:00:00 2001 From: Pete Shadbolt Date: Tue, 25 Oct 2016 10:53:18 +0100 Subject: [PATCH 01/10] Add an example of 2D grid generation (#12) --- examples/visualization/grid_2d.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 examples/visualization/grid_2d.py diff --git a/examples/visualization/grid_2d.py b/examples/visualization/grid_2d.py new file mode 100644 index 0000000..6a88d40 --- /dev/null +++ b/examples/visualization/grid_2d.py @@ -0,0 +1,14 @@ +from abp.fancy import GraphState +from abp.util import xyz +import itertools + +psi = GraphState() +grid = itertools.product(range(10), range(10)) +for i, (x, y) in enumerate(grid): + psi.add_qubit(i, position=xyz(x, y, 0), vop=0) + +for i in range(50): + psi.act_cz(i, i+1) + +psi.update() + From 9377249675d110795dcb1cf628f4b28a293b51f2 Mon Sep 17 00:00:00 2001 From: Sam Morley-Short Date: Wed, 2 Nov 2016 23:47:06 +0000 Subject: [PATCH 02/10] measure_sequences added, not yet working --- abp/graphstate.py | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) mode change 100644 => 100755 abp/graphstate.py diff --git a/abp/graphstate.py b/abp/graphstate.py old mode 100644 new mode 100755 index f443e0d..2bea4ab --- a/abp/graphstate.py +++ b/abp/graphstate.py @@ -292,6 +292,27 @@ class GraphState(object): """ return self.measure(node, "pz", force, detail) + def measure_sequence(self, measurements, forces=None, detail=False): + """ Measures a sequence of Paulis + + :param measurements: The sequence of measurements to be made, in the form [(node, basis), ...] + :type force: list of tuples + :param force: Measurements in quantum mechanics are probabilistic. If you want to force a particular outcome, use the ``force``. List outcome force values in same order as measurements + :type force: list + :param detail: Provide detailed information + :type detail: boolean + + """ + forces = forces if forces != None else [random.choice([0, 1]) for i in range(len(measurements))] + measurements = zip(measurements, forces) + print measurements + results = [] + for (node, basis), force in measurements: + result = self.measure(node, basis, force, detail) + print result + results += [result] + return results + def _toggle_edges(self, a, b): """ Toggle edges between vertex sets a and b """ # TODO: i'm pretty sure this is just a single-line it.combinations or From 10860e20660d864b49d4e00473919f1879eacef3 Mon Sep 17 00:00:00 2001 From: Sam Morley-Short Date: Thu, 3 Nov 2016 08:59:21 +0000 Subject: [PATCH 03/10] measure_sequence now working, was not in develop mode :baby: --- abp/graphstate.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/abp/graphstate.py b/abp/graphstate.py index 2bea4ab..b80172d 100755 --- a/abp/graphstate.py +++ b/abp/graphstate.py @@ -305,11 +305,9 @@ class GraphState(object): """ forces = forces if forces != None else [random.choice([0, 1]) for i in range(len(measurements))] measurements = zip(measurements, forces) - print measurements results = [] for (node, basis), force in measurements: result = self.measure(node, basis, force, detail) - print result results += [result] return results From 76e9ddd2859cdeb0b49a2f818a110138cb05ce0a Mon Sep 17 00:00:00 2001 From: Pete Shadbolt Date: Sun, 6 Nov 2016 10:40:41 +0000 Subject: [PATCH 04/10] =?UTF-8?q?Bump=20version:=200.4.16=20=E2=86=92=200.?= =?UTF-8?q?5.0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .bumpversion.cfg | 2 +- setup.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.bumpversion.cfg b/.bumpversion.cfg index 3a09af7..a0ed8bf 100644 --- a/.bumpversion.cfg +++ b/.bumpversion.cfg @@ -1,5 +1,5 @@ [bumpversion] -current_version = 0.4.16 +current_version = 0.5.0 commit = True tag = True diff --git a/setup.py b/setup.py index b36af03..d010f69 100755 --- a/setup.py +++ b/setup.py @@ -6,7 +6,7 @@ STATIC = glob("abp/static/*.*")+glob("abp/static/img/*.*")+glob("abp/static/scri setup( name = "abp", - version = "0.4.16", + version = "0.5.0", packages = ["abp", "abp.static"], test_suite = "tests", author = "Pete Shadbolt", From 51e128b87037d1423d169839c6090f5b31a81b44 Mon Sep 17 00:00:00 2001 From: Pete Shadbolt Date: Sun, 6 Nov 2016 10:41:02 +0000 Subject: [PATCH 05/10] =?UTF-8?q?Bump=20version:=200.5.0=20=E2=86=92=200.6?= =?UTF-8?q?.0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .bumpversion.cfg | 2 +- setup.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.bumpversion.cfg b/.bumpversion.cfg index a0ed8bf..9c2dc69 100644 --- a/.bumpversion.cfg +++ b/.bumpversion.cfg @@ -1,5 +1,5 @@ [bumpversion] -current_version = 0.5.0 +current_version = 0.6.0 commit = True tag = True diff --git a/setup.py b/setup.py index d010f69..2dd9d7a 100755 --- a/setup.py +++ b/setup.py @@ -6,7 +6,7 @@ STATIC = glob("abp/static/*.*")+glob("abp/static/img/*.*")+glob("abp/static/scri setup( name = "abp", - version = "0.5.0", + version = "0.6.0", packages = ["abp", "abp.static"], test_suite = "tests", author = "Pete Shadbolt", From e7da39ff3fbcb1c7756410a2cb66515501c886a5 Mon Sep 17 00:00:00 2001 From: Pete Shadbolt Date: Sun, 6 Nov 2016 10:41:22 +0000 Subject: [PATCH 06/10] =?UTF-8?q?Bump=20version:=200.6.0=20=E2=86=92=200.6?= =?UTF-8?q?.1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .bumpversion.cfg | 2 +- setup.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.bumpversion.cfg b/.bumpversion.cfg index 9c2dc69..957e13a 100644 --- a/.bumpversion.cfg +++ b/.bumpversion.cfg @@ -1,5 +1,5 @@ [bumpversion] -current_version = 0.6.0 +current_version = 0.6.1 commit = True tag = True diff --git a/setup.py b/setup.py index 2dd9d7a..44d6bcf 100755 --- a/setup.py +++ b/setup.py @@ -6,7 +6,7 @@ STATIC = glob("abp/static/*.*")+glob("abp/static/img/*.*")+glob("abp/static/scri setup( name = "abp", - version = "0.6.0", + version = "0.6.1", packages = ["abp", "abp.static"], test_suite = "tests", author = "Pete Shadbolt", From 9bfe0459bd274b370ee80a6c7059af3086c3686b Mon Sep 17 00:00:00 2001 From: Pete Shadbolt Date: Tue, 8 Nov 2016 06:47:52 -0800 Subject: [PATCH 07/10] Add a test for measure_sequence, closes #13 --- tests/test_measurement.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/tests/test_measurement.py b/tests/test_measurement.py index d6d494f..19ff1f6 100644 --- a/tests/test_measurement.py +++ b/tests/test_measurement.py @@ -59,3 +59,13 @@ def test_projection(): g.act_local_rotation(0, "hadamard") g.measure(0, "pz", 1) assert np.allclose(g.to_state_vector().state, qi.one) + +def test_measure_sequence(): + """ Simple test of measurement sequences """ + g = GraphState(2, vop="identity") + g.act_cz(0, 1) + assert g.measure_sequence(((0, "px"), (1, "px")), forces=(0, 1)) == [0, 1] + assert len(g.edgelist()) == 0 + assert g.node[1]["vop"] == clifford.pz + + From 329cbe70e33b42ce1f4b26faf94f11ee38247e9f Mon Sep 17 00:00:00 2001 From: Pete Shadbolt Date: Tue, 8 Nov 2016 06:49:48 -0800 Subject: [PATCH 08/10] PEP8 --- abp/graphstate.py | 54 ++++++++++++++++++++------------------- tests/test_measurement.py | 2 +- 2 files changed, 29 insertions(+), 27 deletions(-) diff --git a/abp/graphstate.py b/abp/graphstate.py index b1beda8..31fc891 100755 --- a/abp/graphstate.py +++ b/abp/graphstate.py @@ -9,6 +9,7 @@ import json, random import qi, clifford, util from stabilizer import Stabilizer + class GraphState(object): """ @@ -31,9 +32,10 @@ class GraphState(object): self.adj = data.adj.copy() self.node = data.node.copy() for key, value in self.node.items(): - self.node[key]["vop"] = data.node[key].get("vop", clifford.identity) + self.node[key]["vop"] = data.node[ + key].get("vop", clifford.identity) except AttributeError: - try: + try: # Provided with a list of node names? for n in data: self._add_node(n, vop=vop) @@ -46,7 +48,6 @@ class GraphState(object): """ Add a node """ self._add_node(self, *args, **kwargs) - def _del_node(self, node): """ Remove a node. TODO: this is a hack right now! """ if not node in self.node: @@ -56,7 +57,6 @@ class GraphState(object): del self.adj[k][node] del self.adj[node] - def _add_node(self, node, **kwargs): """ Add a node. By default, nodes are initialized with ``vop=``:math:`I`, i.e. they are in the :math:`|+\\rangle` state. @@ -78,19 +78,21 @@ class GraphState(object): default = kwargs.get("default", "identity") self.adj[node] = {} self.node[node] = {} - kwargs["vop"] = clifford.by_name[str(kwargs.get("vop", "identity"))] #TODO: ugly + kwargs["vop"] = clifford.by_name[ + str(kwargs.get("vop", "identity"))] # TODO: ugly self.node[node].update(kwargs) def add_qubit(self, name, **kwargs): - """ Add a qubit to the state. + """ Add a qubit to the state. :param name: The name of the node, e.g. ``9``, ``start``. :type name: Any hashable type :param kwargs: Any extra node attributes - By default, qubits are initialized in the :math:`|0\\rangle` state. Provide the optional ``vop`` argument to set the initial state. + By default, qubits are initialized in the :math:`|0\\rangle` state. Provide the optional ``vop`` argument to set the initial state. """ - kwargs["vop"] = clifford.by_name[str(kwargs.get("vop", "hadamard"))] #TODO: ugly + kwargs["vop"] = clifford.by_name[ + str(kwargs.get("vop", "hadamard"))] # TODO: ugly self._add_node(name, **kwargs) def act_circuit(self, circuit): @@ -224,14 +226,14 @@ class GraphState(object): :type basis: :math:`\in` ``{"px", "py", "pz"}`` :param force: Forces the measurement outcome. :type force: boolean - :param detail: Get detailed information. + :param detail: Get detailed information. :type detail: boolean - + Measurements in quantum mechanics are probabilistic. If you want to force a particular outcome :math:`\in\{0, 1\}`, use ``force``. You can get more information by setting ``detail=True``, in which case ``measure()`` returns a dictionary with the following keys: - - ``outcome``: the measurement outcome. + - ``outcome``: the measurement outcome. - ``determinate``: indicates whether the outcome was determinate or random. For example, measuring :math:`|0\\rangle` in :math:`\sigma_x` always gives a deterministic outcome. ``determinate`` is overridden by ``force`` -- forced outcomes are always determinate. - ``conjugated_basis``: The index of the measurement operator, rotated by the vertex operator of the measured node, i.e. :math:`U_\\text{vop} \sigma_m U_\\text{vop}^\dagger`. - ``phase``: The phase of the cojugated basis, :math:`\pm 1`. @@ -263,8 +265,8 @@ class GraphState(object): result = not result if detail: - return {"outcome": int(result), - "determinate": (determinate or force!=None), + return {"outcome": int(result), + "determinate": (determinate or force != None), "conjugated_basis": basis, "phase": phase, "node": node, @@ -312,23 +314,24 @@ class GraphState(object): def measure_sequence(self, measurements, forces=None, detail=False): """ Measures a sequence of Paulis - + :param measurements: The sequence of measurements to be made, in the form [(node, basis), ...] :type force: list of tuples :param force: Measurements in quantum mechanics are probabilistic. If you want to force a particular outcome, use the ``force``. List outcome force values in same order as measurements :type force: list :param detail: Provide detailed information :type detail: boolean - + """ - forces = forces if forces != None else [random.choice([0, 1]) for i in range(len(measurements))] + forces = forces if forces != None else [ + random.choice([0, 1]) for i in range(len(measurements))] measurements = zip(measurements, forces) results = [] for (node, basis), force in measurements: result = self.measure(node, basis, force, detail) results += [result] return results - + def _toggle_edges(self, a, b): """ Toggle edges between vertex sets a and b """ # TODO: i'm pretty sure this is just a single-line it.combinations or @@ -352,7 +355,7 @@ class GraphState(object): else: friend = next(self.adj[node].iterkeys()) else: - assert friend in self.adj[node].keys() # TODO: unnecessary assert + assert friend in self.adj[node].keys() # TODO: unnecessary assert # Update the VOPs. TODO: pretty ugly if result: @@ -452,7 +455,7 @@ class GraphState(object): return {"node": self.node, "adj": self.adj} def from_json(self, data): - """ Construct the graph from JSON data + """ Construct the graph from JSON data :param data: JSON data to be read. """ self.node = data["node"] @@ -482,17 +485,17 @@ class GraphState(object): return state def to_stabilizer(self): - """ + """ Get the stabilizer representation of the state:: >>> print g.to_stabilizer() 0 1 2 3 100 200 ------------------------------ - X Z Z X - Z X Z - Z Z X - - Z Z - X Z + X Z Z X + Z X Z + Z Z X + - Z Z + X Z Z X """ @@ -509,4 +512,3 @@ class GraphState(object): g.adj = self.adj.copy() g.deterministic = self.deterministic return g - diff --git a/tests/test_measurement.py b/tests/test_measurement.py index 19ff1f6..5cafcaf 100644 --- a/tests/test_measurement.py +++ b/tests/test_measurement.py @@ -60,6 +60,7 @@ def test_projection(): g.measure(0, "pz", 1) assert np.allclose(g.to_state_vector().state, qi.one) + def test_measure_sequence(): """ Simple test of measurement sequences """ g = GraphState(2, vop="identity") @@ -68,4 +69,3 @@ def test_measure_sequence(): assert len(g.edgelist()) == 0 assert g.node[1]["vop"] == clifford.pz - From 80a183998d73677ff5a65914375a46d748d07d90 Mon Sep 17 00:00:00 2001 From: Pete Shadbolt Date: Tue, 8 Nov 2016 07:06:29 -0800 Subject: [PATCH 09/10] =?UTF-8?q?Bump=20version:=200.6.1=20=E2=86=92=200.7?= =?UTF-8?q?.0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .bumpversion.cfg | 2 +- setup.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.bumpversion.cfg b/.bumpversion.cfg index 957e13a..bc080c5 100644 --- a/.bumpversion.cfg +++ b/.bumpversion.cfg @@ -1,5 +1,5 @@ [bumpversion] -current_version = 0.6.1 +current_version = 0.7.0 commit = True tag = True diff --git a/setup.py b/setup.py index 44d6bcf..cedae5a 100755 --- a/setup.py +++ b/setup.py @@ -6,7 +6,7 @@ STATIC = glob("abp/static/*.*")+glob("abp/static/img/*.*")+glob("abp/static/scri setup( name = "abp", - version = "0.6.1", + version = "0.7.0", packages = ["abp", "abp.static"], test_suite = "tests", author = "Pete Shadbolt", From 9b5b57448cdf721b584db2faf7f43f4a27f8e5a2 Mon Sep 17 00:00:00 2001 From: Pete Shadbolt Date: Thu, 17 Nov 2016 14:45:33 -0800 Subject: [PATCH 10/10] Fix broken versioning --- .bumpversion.cfg | 2 +- doc/conf.py | 2 +- setup.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.bumpversion.cfg b/.bumpversion.cfg index bc080c5..35237a6 100644 --- a/.bumpversion.cfg +++ b/.bumpversion.cfg @@ -1,5 +1,5 @@ [bumpversion] -current_version = 0.7.0 +current_version = 0.4.17 commit = True tag = True diff --git a/doc/conf.py b/doc/conf.py index d27325a..add97dd 100644 --- a/doc/conf.py +++ b/doc/conf.py @@ -61,7 +61,7 @@ author = u'Pete Shadbolt' # The short X.Y version. version = '0.4' # The full version, including alpha/beta/rc tags. -release = '0.4.1' +release = '0.4.17' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. diff --git a/setup.py b/setup.py index cedae5a..ea6d4d8 100755 --- a/setup.py +++ b/setup.py @@ -6,7 +6,7 @@ STATIC = glob("abp/static/*.*")+glob("abp/static/img/*.*")+glob("abp/static/scri setup( name = "abp", - version = "0.7.0", + version = "0.4.17", packages = ["abp", "abp.static"], test_suite = "tests", author = "Pete Shadbolt",