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