@@ -223,6 +223,9 @@ def load_from_disk(): | |||||
with open(temp("by_name.json")) as f: | with open(temp("by_name.json")) as f: | ||||
by_name = json.load(f) | by_name = json.load(f) | ||||
def is_diagonal(v): | |||||
""" TODO:remove. Checks if a VOP is diagonal or not """ | |||||
return v in {0, 3, 5, 6} | |||||
if __name__ == "__main__": | if __name__ == "__main__": | ||||
compute_everything() | compute_everything() | ||||
@@ -90,14 +90,31 @@ class GraphState(object): | |||||
def act_cz(self, a, b): | def act_cz(self, a, b): | ||||
""" Act a controlled-phase gate on two qubits """ | """ Act a controlled-phase gate on two qubits """ | ||||
#TODO: inefficient | |||||
if set(self.adj[a]) - {b}: | |||||
ci = self.get_connection_info(a, b) | |||||
if ci["non1"]: | |||||
self.remove_vop(a, b) | self.remove_vop(a, b) | ||||
if set(self.adj[b]) - {a}: | |||||
ci = self.get_connection_info(a, b) | |||||
if ci["non2"]: | |||||
self.remove_vop(b, a) | self.remove_vop(b, a) | ||||
if set(self.adj[a]) - {b}: | |||||
self.remove_vop(a, b) | |||||
edge = int(self.has_edge(a, b)) | |||||
ci = self.get_connection_info(a, b) | |||||
if ci["non1"] and not clifford.is_diagonal(self.node[a]["vop"]): | |||||
self.remove_vop(b, a) | |||||
self.cz_with_table(a, b, ci["was_edge"]) | |||||
def get_connection_info(self, a, b): | |||||
if self.has_edge(a, b): | |||||
return {"was_edge": True, | |||||
"non1": len(self.node.get(a, [])) > 0, | |||||
"non2": len(self.node.get(b, [])) > 0} | |||||
else: | |||||
return {"was_edge": False, | |||||
"non1": len(self.node.get(a, [])) > 1, | |||||
"non2": len(self.node.get(b, [])) > 1} | |||||
def cz_with_table(self, a, b, edge): | |||||
""" Run the table """ | |||||
new_edge, self.node[a]["vop"], self.node[ | new_edge, self.node[a]["vop"], self.node[ | ||||
b]["vop"] = clifford.cz_table[edge, self.node[a]["vop"], self.node[b]["vop"]] | b]["vop"] = clifford.cz_table[edge, self.node[a]["vop"], self.node[b]["vop"]] | ||||
if new_edge != edge: | if new_edge != edge: | ||||
@@ -1,46 +1,25 @@ | |||||
from abp import clifford, qi | |||||
from abp import clifford, qi, GraphState | |||||
from anders_briegel import graphsim | |||||
import numpy as np | import numpy as np | ||||
import itertools as it | import itertools as it | ||||
def conj_hack(operator, unitary): | |||||
""" TODO: make this meaningful / legible """ | |||||
assert operator in set(xrange(4)) | |||||
op = clifford.times_table[unitary, operator] | |||||
op = clifford.times_table[op, clifford.conjugation_table[unitary]] | |||||
is_id_or_operator = (unitary % 4 == 0) or (unitary % 4 == operator) | |||||
is_non_pauli = (unitary >= 4) and (unitary <= 15) | |||||
phase = ((-1, 1), (1, -1))[is_id_or_operator][is_non_pauli] | |||||
if operator == 0: | |||||
phase = 1 | |||||
return op, phase | |||||
a = GraphState() | |||||
a.node = {0: {'vop': 1}, 1: {'vop': 0}, 2: {'vop': 3}} | |||||
a.adj = {0: {1: {}, 2: {}}, 1: {0: {}}, 2: {0: {}}} | |||||
def conj(operator, unitary): | |||||
""" Better """ | |||||
matrices = ({"x": qi.msqx, "z": qi.sqz}[c] for c in clifford.decompositions[unitary]) | |||||
unitary = reduce(np.dot, matrices, np.eye(2, dtype=complex)) | |||||
operator = qi.operators[operator] | |||||
new_operator = reduce(np.dot, (unitary, operator, qi.hermitian_conjugate(unitary))) | |||||
a.act_cz(1,2) | |||||
print a.adj_list() | |||||
for i, o in enumerate(qi.operators): | |||||
if np.allclose(o, new_operator): | |||||
return i, 1 | |||||
elif np.allclose(o, -new_operator): | |||||
return i, -1 | |||||
raise IndexError | |||||
b = graphsim.GraphRegister(3) | |||||
b.hadamard(0) | |||||
b.hadamard(1) | |||||
b.hadamard(2) | |||||
b.cphase(0, 1) | |||||
b.cphase(0, 2) | |||||
b.local_op(0, graphsim.LocCliffOp(1)) | |||||
b.local_op(2, graphsim.LocCliffOp(3)) | |||||
for operator, unitary in it.product(range(4), range(24)): | |||||
assert conj(operator, unitary) == conj_hack(operator, unitary) | |||||
#new = np.dot(u, np.dot(o, qi.hermitian_conjugate(u))) | |||||
#which = clifford.find_clifford(new, clifford.unitaries[:4]) | |||||
#assert which in xrange(4) | |||||
#whichm = [qi.id, qi.px, qi.py, qi.pz][which] | |||||
#if np.allclose(new, whichm): | |||||
#return which, 1 | |||||
#elif np.allclose(new, -whichm): | |||||
#return which, -1 | |||||
#else: | |||||
#raise IndexError | |||||
b.cphase(1,2) | |||||
b.print_adj_list() |
@@ -5,6 +5,7 @@ from abp import clifford | |||||
import random | import random | ||||
import difflib | import difflib | ||||
import re | import re | ||||
from copy import deepcopy | |||||
def compare(a, b): | def compare(a, b): | ||||
""" TODO: Sketchy as you like. Remove this abomination """ | """ TODO: Sketchy as you like. Remove this abomination """ | ||||
@@ -116,17 +117,17 @@ def test_with_cphase_gates_hadamard_only(N=10): | |||||
compare(a, b) | compare(a, b) | ||||
def test_all(N=3): | def test_all(N=3): | ||||
""" Test all gates at random """ | """ Test all gates at random """ | ||||
#TODO: Currently fails. Why??? | #TODO: Currently fails. Why??? | ||||
clifford.use_old_cz() | clifford.use_old_cz() | ||||
a = graphsim.GraphRegister(N) | a = graphsim.GraphRegister(N) | ||||
b = GraphState(range(N)) | b = GraphState(range(N)) | ||||
for i in range(1000): | |||||
previous_state, previous_cz = None, None | |||||
while isequal(a, b): | |||||
if random.random()>0.5: | if random.random()>0.5: | ||||
j = random.randint(0, N-1) | j = random.randint(0, N-1) | ||||
a.hadamard(j) | a.hadamard(j) | ||||
@@ -135,7 +136,15 @@ def test_all(N=3): | |||||
q = random.randint(0, N-2) | q = random.randint(0, N-2) | ||||
a.cphase(q, q+1) | a.cphase(q, q+1) | ||||
b.act_cz(q, q+1) | b.act_cz(q, q+1) | ||||
compare(a, b) | |||||
#print b | |||||
previous_state = deepcopy(b) | |||||
previous_cz = q, q+1 | |||||
print "Initial state:" | |||||
print previous_state.node | |||||
print previous_state.adj | |||||
print "CZ:", previous_cz | |||||
print "Pete state:\n", a.get_adj_list() | |||||
print "Anders state:\n", b.adj_list() | |||||