瀏覽代碼

Meaningful conjugation code

master
Pete Shadbolt 9 年之前
父節點
當前提交
0ec10d155c
共有 4 個文件被更改,包括 71 次插入13 次删除
  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 查看文件

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






+ 3
- 0
abp/qi.py 查看文件

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


+ 46
- 0
scripts/wtf.py 查看文件

@@ -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 查看文件

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


Loading…
取消
儲存