From 11368ba8809916f1265e83dcbec8d3a193397454 Mon Sep 17 00:00:00 2001 From: Pete Shadbolt Date: Tue, 10 May 2016 22:55:22 +0100 Subject: [PATCH] Fix qi simulator again, test passing --- abp/graphstate.py | 22 ++++++++++++++++++---- abp/qi.py | 18 ++++++------------ tests/test_get_state_vector.py | 15 +++++++++++++++ tests/test_qi_circuit_model.py | 16 +++++++++++++--- 4 files changed, 52 insertions(+), 19 deletions(-) create mode 100644 tests/test_get_state_vector.py diff --git a/abp/graphstate.py b/abp/graphstate.py index 44f8b14..36d7e6b 100644 --- a/abp/graphstate.py +++ b/abp/graphstate.py @@ -6,6 +6,7 @@ from collections import defaultdict import itertools as it import clifford import json +import qi try: import networkx as nx except ImportError: @@ -139,8 +140,9 @@ class GraphState(object): def __str__(self): """ Represent as a string for quick debugging """ - return "graph:\n vops: {}\n ngbh: {}\n"\ - .format(str(dict(self.vops)), str(dict(self.ngbh))) + vopstr = {key: clifford.get_name(value) for key,value in self.vops.items()} + nbstr = str(dict(self.ngbh)) + return "graph:\n vops: {}\n ngbh: {}\n".format(vopstr, nbstr) def to_json(self): """ Convert the graph to JSON form """ @@ -160,8 +162,20 @@ class GraphState(object): return g def to_state_vector(self): - """ Get the freaking state vector """ - return None + """ Get the full state vector """ + if not len(self.vops)<10: + raise ValueError("Cannot build state vector: too many qubits") + output = qi.CircuitModel(len(self.vops)) + #print output + for i in range(len(self.vops)): + output.act_hadamard(i) + #print output + for i, j in self.edgelist(): + output.act_cz(i, j) + #print output + for i, u in self.vops.items(): + output.act_local_rotation(i, clifford.unitaries[u]) + return output def layout(self): """ Automatically lay out the graph """ diff --git a/abp/qi.py b/abp/qi.py index e942995..9584650 100644 --- a/abp/qi.py +++ b/abp/qi.py @@ -68,12 +68,9 @@ class CircuitModel(object): where = 1 << qubit output = np.zeros((self.d, 1), dtype=complex) for i, v in enumerate(self.state): - if (i & where) == 0: - output[i] += v*ir2 - output[i ^ where] += v*ir2 - if (i & where) == 1: - output[i ^ where] += v*ir2 - output[i] -= v*ir2 + q = i & where > 0 + output[i] += v*ha[q, q] + output[i ^ where] += v*ha[not q, q] self.state = output @@ -82,12 +79,9 @@ class CircuitModel(object): where = 1 << qubit output = np.zeros((self.d, 1), dtype=complex) for i, v in enumerate(self.state): - if (i & where) == 0: - output[i] += v*u[0, 0] - output[i ^ where] += v*u[0, 1] - if (i & where) == 1: - output[i ^ where] += v*u[1, 0] - output[i] += v*u[1, 1] + q = i & where > 0 + output[i] += v*u[q, q] + output[i ^ where] += v*u[not q, q] self.state = output diff --git a/tests/test_get_state_vector.py b/tests/test_get_state_vector.py new file mode 100644 index 0000000..94bacf9 --- /dev/null +++ b/tests/test_get_state_vector.py @@ -0,0 +1,15 @@ +from abp.graphstate 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_by_name(0, "hadamard") + g.act_local_rotation_by_name(1, "hadamard") + g.act_cz(0, 1) + assert np.allclose(g.to_state_vector().state, qi.bond) + + diff --git a/tests/test_qi_circuit_model.py b/tests/test_qi_circuit_model.py index 19c0ec4..c31c284 100644 --- a/tests/test_qi_circuit_model.py +++ b/tests/test_qi_circuit_model.py @@ -1,17 +1,21 @@ import numpy as np from abp import qi -def test_init(): +def _test_init(): """ Can you initialize some qubits """ psi = qi.CircuitModel(5) assert psi.d == 32 def test_hadamard(): """ What does CZ do ? """ - psi = qi.CircuitModel(10) + 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.) + psi.act_hadamard(1) psi.act_hadamard(0) - assert np.allclose(psi.state[0], 1) + psi.act_hadamard(2) + assert np.allclose(psi.state, qi.ir2*np.array([[1,0,0,0,1,0,0,0]]).T) def test_cz(): @@ -30,4 +34,10 @@ def test_local_rotation(): psi.act_local_rotation(0, qi.ha) assert np.allclose(psi.state[0], 1) + psi.act_local_rotation(0, qi.ha) + psi.act_local_rotation(1, qi.ha) + psi.act_local_rotation(0, qi.ha) + psi.act_local_rotation(1, qi.ha) + assert np.allclose(psi.state[0], 1) +