@@ -6,6 +6,7 @@ from collections import defaultdict | |||||
import itertools as it | import itertools as it | ||||
import clifford | import clifford | ||||
import json | import json | ||||
import qi | |||||
try: | try: | ||||
import networkx as nx | import networkx as nx | ||||
except ImportError: | except ImportError: | ||||
@@ -139,8 +140,9 @@ class GraphState(object): | |||||
def __str__(self): | def __str__(self): | ||||
""" Represent as a string for quick debugging """ | """ 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): | def to_json(self): | ||||
""" Convert the graph to JSON form """ | """ Convert the graph to JSON form """ | ||||
@@ -160,8 +162,20 @@ class GraphState(object): | |||||
return g | return g | ||||
def to_state_vector(self): | 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): | def layout(self): | ||||
""" Automatically lay out the graph """ | """ Automatically lay out the graph """ | ||||
@@ -68,12 +68,9 @@ class CircuitModel(object): | |||||
where = 1 << qubit | where = 1 << qubit | ||||
output = np.zeros((self.d, 1), dtype=complex) | output = np.zeros((self.d, 1), dtype=complex) | ||||
for i, v in enumerate(self.state): | 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 | self.state = output | ||||
@@ -82,12 +79,9 @@ class CircuitModel(object): | |||||
where = 1 << qubit | where = 1 << qubit | ||||
output = np.zeros((self.d, 1), dtype=complex) | output = np.zeros((self.d, 1), dtype=complex) | ||||
for i, v in enumerate(self.state): | 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 | 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 | import numpy as np | ||||
from abp import qi | from abp import qi | ||||
def test_init(): | |||||
def _test_init(): | |||||
""" Can you initialize some qubits """ | """ Can you initialize some qubits """ | ||||
psi = qi.CircuitModel(5) | psi = qi.CircuitModel(5) | ||||
assert psi.d == 32 | assert psi.d == 32 | ||||
def test_hadamard(): | def test_hadamard(): | ||||
""" What does CZ do ? """ | """ What does CZ do ? """ | ||||
psi = qi.CircuitModel(10) | |||||
psi = qi.CircuitModel(3) | |||||
psi.act_hadamard(0) | 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) | 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(): | def test_cz(): | ||||
@@ -30,4 +34,10 @@ def test_local_rotation(): | |||||
psi.act_local_rotation(0, qi.ha) | psi.act_local_rotation(0, qi.ha) | ||||
assert np.allclose(psi.state[0], 1) | 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) | |||||