소스 검색

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


불러오는 중...
취소
저장