| @@ -15,9 +15,9 @@ decompositions = ("xxxx", "xx", "zzxx", "zz", "zxx", "z", "zzz", "xxz", | |||||
| "xzx", "xzxxx", "xzzzx", "xxxzx", "xzz", "zzx", "xxx", "x", | "xzx", "xzxxx", "xzzzx", "xxxzx", "xzz", "zzx", "xxx", "x", | ||||
| "zzzx", "xxzx", "zx", "zxxx", "xxxz", "xzzz", "xz", "xzxx") | "zzzx", "xxzx", "zx", "zxxx", "xxxz", "xzzz", "xz", "xzxx") | ||||
| def conjugate(vop, transform): | |||||
| def conjugate(operator, unitary): | |||||
| """ Returns transform * vop * transform^dagger and a phase in {+1, -1} """ | """ Returns transform * vop * transform^dagger and a phase in {+1, -1} """ | ||||
| return measurement_table[vop, transform] | |||||
| return measurement_table[operator, unitary] | |||||
| def use_old_cz(): | def use_old_cz(): | ||||
| """ Use the CZ table from A&B's code """ | """ Use the CZ table from A&B's code """ | ||||
| @@ -101,22 +101,32 @@ def get_state_table(unitaries): | |||||
| np.dot(kp, state).T) | np.dot(kp, state).T) | ||||
| return state_table | return state_table | ||||
| def get_measurement_entry(operator, unitary): | |||||
| """ | |||||
| Any Clifford group unitary will map an operator A in {I, X, Y, Z} | |||||
| to an operator B in +-{I, X, Y, Z}. This finds that mapping. | |||||
| """ | |||||
| matrices = ({"x": qi.msqx, "z": qi.sqz}[c] for c in 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))) | |||||
| 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 | |||||
| def get_measurement_table(): | def get_measurement_table(): | ||||
| """ | """ | ||||
| Compute a table of transform * operation * transform^dagger | Compute a table of transform * operation * transform^dagger | ||||
| This is pretty unintelligible right now, we should probably compute the phase from unitaries instead | This is pretty unintelligible right now, we should probably compute the phase from unitaries instead | ||||
| """ | """ | ||||
| measurement_table = np.zeros((4, 24, 2), dtype=complex) | measurement_table = np.zeros((4, 24, 2), dtype=complex) | ||||
| for vop, transform in it.product(range(4), range(24)): | |||||
| assert vop in set(xrange(4)) | |||||
| op = times_table[transform, vop] | |||||
| op = times_table[op, conjugation_table[transform]] | |||||
| is_id_or_vop = (transform % 4 == 0) or (transform % 4 == vop) | |||||
| is_non_pauli = (transform >= 4) and (transform <= 15) | |||||
| phase = ((-1, 1), (1, -1))[is_id_or_vop][is_non_pauli] | |||||
| if vop == 0: | |||||
| phase = 1 | |||||
| measurement_table[vop, transform] = [op, phase] | |||||
| for operator, unitary in it.product(range(4), range(24)): | |||||
| measurement_table[operator, unitary] = [operator, unitary] | |||||
| return measurement_table | return measurement_table | ||||
| @@ -36,6 +36,8 @@ cz = np.array(np.eye(4), dtype=complex) | |||||
| cz[3,3]=-1 | cz[3,3]=-1 | ||||
| # States | # States | ||||
| zero = np.array([[1],[0]], dtype=complex) | |||||
| one = np.array([[0],[1]], dtype=complex) | |||||
| plus = np.array([[1],[1]], dtype=complex) / np.sqrt(2) | plus = np.array([[1],[1]], dtype=complex) / np.sqrt(2) | ||||
| bond = cz.dot(np.kron(plus, plus)) | bond = cz.dot(np.kron(plus, plus)) | ||||
| nobond = np.kron(plus, plus) | nobond = np.kron(plus, plus) | ||||
| @@ -46,6 +48,7 @@ names = "identity", "px", "py", "pz", "hadamard", "phase", "sqz", "msqz", "sqy", | |||||
| by_name = dict(zip(names, common_us)) | by_name = dict(zip(names, common_us)) | ||||
| paulis = px, py, pz | paulis = px, py, pz | ||||
| operators = id, px, py, pz | |||||
| def normalize_global_phase(m): | def normalize_global_phase(m): | ||||
| @@ -0,0 +1,46 @@ | |||||
| from abp import clifford, qi | |||||
| 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 | |||||
| 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))) | |||||
| 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 | |||||
| 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 | |||||
| @@ -4,7 +4,6 @@ import itertools | |||||
| #//! replaces op by trans * op * trans^dagger and returns a phase, | #//! replaces op by trans * op * trans^dagger and returns a phase, | ||||
| #/*! either +1 or -1 (as RightPhase(0) or RightPhase(2)) */ | #/*! either +1 or -1 (as RightPhase(0) or RightPhase(2)) */ | ||||
| #RightPhase conjugate (const LocCliffOp trans); | |||||
| def test_conjugation(): | def test_conjugation(): | ||||
| """ Test that clifford.conugate() agrees with graphsim.LocCliffOp.conjugate """ | """ Test that clifford.conugate() agrees with graphsim.LocCliffOp.conjugate """ | ||||