Browse Source

PEP8

master
Pete Shadbolt 8 years ago
parent
commit
329cbe70e3
2 changed files with 29 additions and 27 deletions
  1. +28
    -26
      abp/graphstate.py
  2. +1
    -1
      tests/test_measurement.py

+ 28
- 26
abp/graphstate.py View File

@@ -9,6 +9,7 @@ import json, random
import qi, clifford, util import qi, clifford, util
from stabilizer import Stabilizer from stabilizer import Stabilizer



class GraphState(object): class GraphState(object):


""" """
@@ -31,9 +32,10 @@ class GraphState(object):
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 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: except AttributeError:
try:
try:
# Provided with a list of node names? # Provided with a list of node names?
for n in data: for n in data:
self._add_node(n, vop=vop) self._add_node(n, vop=vop)
@@ -46,7 +48,6 @@ class GraphState(object):
""" Add a node """ """ Add a node """
self._add_node(self, *args, **kwargs) self._add_node(self, *args, **kwargs)



def _del_node(self, node): def _del_node(self, node):
""" Remove a node. TODO: this is a hack right now! """ """ Remove a node. TODO: this is a hack right now! """
if not node in self.node: if not node in self.node:
@@ -56,7 +57,6 @@ class GraphState(object):
del self.adj[k][node] del self.adj[k][node]
del self.adj[node] del self.adj[node]



def _add_node(self, node, **kwargs): 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. """ 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") default = kwargs.get("default", "identity")
self.adj[node] = {} self.adj[node] = {}
self.node[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) self.node[node].update(kwargs)


def add_qubit(self, name, **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``. :param name: The name of the node, e.g. ``9``, ``start``.
:type name: Any hashable type :type name: Any hashable type
:param kwargs: Any extra node attributes :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) self._add_node(name, **kwargs)


def act_circuit(self, circuit): def act_circuit(self, circuit):
@@ -224,14 +226,14 @@ class GraphState(object):
:type basis: :math:`\in` ``{"px", "py", "pz"}`` :type basis: :math:`\in` ``{"px", "py", "pz"}``
:param force: Forces the measurement outcome. :param force: Forces the measurement outcome.
:type force: boolean :type force: boolean
:param detail: Get detailed information.
:param detail: Get detailed information.
:type detail: boolean :type detail: boolean
Measurements in quantum mechanics are probabilistic. If you want to force a particular outcome :math:`\in\{0, 1\}`, use ``force``. 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: 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. - ``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`. - ``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`. - ``phase``: The phase of the cojugated basis, :math:`\pm 1`.
@@ -263,8 +265,8 @@ class GraphState(object):
result = not result result = not result


if detail: if detail:
return {"outcome": int(result),
"determinate": (determinate or force!=None),
return {"outcome": int(result),
"determinate": (determinate or force != None),
"conjugated_basis": basis, "conjugated_basis": basis,
"phase": phase, "phase": phase,
"node": node, "node": node,
@@ -312,23 +314,24 @@ class GraphState(object):


def measure_sequence(self, measurements, forces=None, detail=False): def measure_sequence(self, measurements, forces=None, detail=False):
""" Measures a sequence of Paulis """ Measures a sequence of Paulis
:param measurements: The sequence of measurements to be made, in the form [(node, basis), ...] :param measurements: The sequence of measurements to be made, in the form [(node, basis), ...]
:type force: list of tuples :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 :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 :type force: list
:param detail: Provide detailed information :param detail: Provide detailed information
:type detail: boolean :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) measurements = 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)
results += [result] results += [result]
return results return results
def _toggle_edges(self, a, b): def _toggle_edges(self, a, b):
""" Toggle edges between vertex sets a and b """ """ Toggle edges between vertex sets a and b """
# TODO: i'm pretty sure this is just a single-line it.combinations or # TODO: i'm pretty sure this is just a single-line it.combinations or
@@ -352,7 +355,7 @@ class GraphState(object):
else: else:
friend = next(self.adj[node].iterkeys()) friend = next(self.adj[node].iterkeys())
else: 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 # Update the VOPs. TODO: pretty ugly
if result: if result:
@@ -452,7 +455,7 @@ class GraphState(object):
return {"node": self.node, "adj": self.adj} return {"node": self.node, "adj": self.adj}


def from_json(self, data): def from_json(self, data):
""" Construct the graph from JSON data
""" Construct the graph from JSON data
:param data: JSON data to be read. :param data: JSON data to be read.
""" """
self.node = data["node"] self.node = data["node"]
@@ -482,17 +485,17 @@ class GraphState(object):
return state return state


def to_stabilizer(self): def to_stabilizer(self):
"""
"""
Get the stabilizer representation of the state:: Get the stabilizer representation of the state::


>>> print g.to_stabilizer() >>> print g.to_stabilizer()
0 1 2 3 100 200 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 Z X


""" """
@@ -509,4 +512,3 @@ class GraphState(object):
g.adj = self.adj.copy() g.adj = self.adj.copy()
g.deterministic = self.deterministic g.deterministic = self.deterministic
return g return g


+ 1
- 1
tests/test_measurement.py View File

@@ -60,6 +60,7 @@ def test_projection():
g.measure(0, "pz", 1) g.measure(0, "pz", 1)
assert np.allclose(g.to_state_vector().state, qi.one) assert np.allclose(g.to_state_vector().state, qi.one)



def test_measure_sequence(): def test_measure_sequence():
""" Simple test of measurement sequences """ """ Simple test of measurement sequences """
g = GraphState(2, vop="identity") g = GraphState(2, vop="identity")
@@ -68,4 +69,3 @@ def test_measure_sequence():
assert len(g.edgelist()) == 0 assert len(g.edgelist()) == 0
assert g.node[1]["vop"] == clifford.pz assert g.node[1]["vop"] == clifford.pz




Loading…
Cancel
Save