| @@ -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 """ | |||
| @@ -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 | |||
| @@ -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) | |||
| @@ -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) | |||