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