diff --git a/abp/clifford.py b/abp/clifford.py index c077b81..9fb5948 100644 --- a/abp/clifford.py +++ b/abp/clifford.py @@ -223,6 +223,9 @@ def load_from_disk(): with open(temp("by_name.json")) as 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__": compute_everything() diff --git a/abp/graphstate.py b/abp/graphstate.py index c995ad7..6f62b7d 100644 --- a/abp/graphstate.py +++ b/abp/graphstate.py @@ -90,14 +90,31 @@ class GraphState(object): def act_cz(self, a, b): """ 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) - if set(self.adj[b]) - {a}: + + ci = self.get_connection_info(a, b) + if ci["non2"]: 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[ b]["vop"] = clifford.cz_table[edge, self.node[a]["vop"], self.node[b]["vop"]] if new_edge != edge: diff --git a/scripts/wtf.py b/scripts/wtf.py index 868bd88..a9be90d 100644 --- a/scripts/wtf.py +++ b/scripts/wtf.py @@ -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 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() diff --git a/tests/test_against_anders_and_briegel.py b/tests/test_against_anders_and_briegel.py index d102c09..ae21062 100644 --- a/tests/test_against_anders_and_briegel.py +++ b/tests/test_against_anders_and_briegel.py @@ -5,6 +5,7 @@ from abp import clifford import random import difflib import re +from copy import deepcopy def compare(a, b): """ TODO: Sketchy as you like. Remove this abomination """ @@ -116,17 +117,17 @@ def test_with_cphase_gates_hadamard_only(N=10): compare(a, b) - def test_all(N=3): """ Test all gates at random """ #TODO: Currently fails. Why??? clifford.use_old_cz() + a = graphsim.GraphRegister(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: j = random.randint(0, N-1) a.hadamard(j) @@ -135,7 +136,15 @@ def test_all(N=3): q = random.randint(0, N-2) a.cphase(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() +