Browse Source

Meaningful conjugation code

master
Pete Shadbolt 8 years ago
parent
commit
0ec10d155c
4 changed files with 71 additions and 13 deletions
  1. +22
    -12
      abp/clifford.py
  2. +3
    -0
      abp/qi.py
  3. +46
    -0
      scripts/wtf.py
  4. +0
    -1
      tests/test_conjugation.py

+ 22
- 12
abp/clifford.py View File

@@ -15,9 +15,9 @@ decompositions = ("xxxx", "xx", "zzxx", "zz", "zxx", "z", "zzz", "xxz",
"xzx", "xzxxx", "xzzzx", "xxxzx", "xzz", "zzx", "xxx", "x",
"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} """
return measurement_table[vop, transform]
return measurement_table[operator, unitary]

def use_old_cz():
""" Use the CZ table from A&B's code """
@@ -101,22 +101,32 @@ def get_state_table(unitaries):
np.dot(kp, state).T)
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():
"""
Compute a table of transform * operation * transform^dagger
This is pretty unintelligible right now, we should probably compute the phase from unitaries instead
"""
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




+ 3
- 0
abp/qi.py View File

@@ -36,6 +36,8 @@ cz = np.array(np.eye(4), dtype=complex)
cz[3,3]=-1

# 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)
bond = cz.dot(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))

paulis = px, py, pz
operators = id, px, py, pz


def normalize_global_phase(m):


+ 46
- 0
scripts/wtf.py View File

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


+ 0
- 1
tests/test_conjugation.py View File

@@ -4,7 +4,6 @@ import itertools

#//! replaces op by trans * op * trans^dagger and returns a phase,
#/*! either +1 or -1 (as RightPhase(0) or RightPhase(2)) */
#RightPhase conjugate (const LocCliffOp trans);

def test_conjugation():
""" Test that clifford.conugate() agrees with graphsim.LocCliffOp.conjugate """


Loading…
Cancel
Save