|
|
@@ -11,8 +11,29 @@ Following the prescription of Anders (thesis pg. 26): |
|
|
|
> indicated by the column header and the opposite sign otherwise. |
|
|
|
""" |
|
|
|
|
|
|
|
# TODO: |
|
|
|
# - check that we re-generate the table |
|
|
|
# - sort of re-map to an ordering |
|
|
|
# - do conjugation |
|
|
|
# - do times table |
|
|
|
# - write tests |
|
|
|
|
|
|
|
from numpy import * |
|
|
|
|
|
|
|
def identify_pauli(m): |
|
|
|
""" Given a signed Pauli matrix, name it. """ |
|
|
|
for sign in (+1, -1): |
|
|
|
for pauli_label, pauli in zip("xyz", paulis): |
|
|
|
if allclose(sign*pauli, m): |
|
|
|
return sign, pauli_label |
|
|
|
|
|
|
|
def anders_sign_rule(sign, column, p): |
|
|
|
""" Anders' sign rule from thesis """ |
|
|
|
return sign if (p==column or column=="i") else -sign, p |
|
|
|
|
|
|
|
def format_action(action): |
|
|
|
return "".join("{}{}".format("+" if s>=0 else "-", p) for s, p in action) |
|
|
|
|
|
|
|
# Some two-qubit matrices |
|
|
|
i = matrix(eye(2, dtype=complex)) |
|
|
|
px = matrix([[0, 1], [1, 0]], dtype=complex) |
|
|
@@ -28,47 +49,18 @@ s_names = ["i", "p", "pp", "ppp"] |
|
|
|
c_rotations = [i, h, h*p, h*p*p, h*p*p*p, h*p*p*h] |
|
|
|
c_names = ["i", "h", "hp", "hpp", "hppp", "hpph"] |
|
|
|
|
|
|
|
def get_sign(x): |
|
|
|
""" Get the sign of a number """ |
|
|
|
return "+" if x>=0 else "-" |
|
|
|
|
|
|
|
def identify_pauli(m): |
|
|
|
""" Given a signed Pauli matrix, name it. """ |
|
|
|
for sign_label, sign in (("+", +1), ("-", -1)): |
|
|
|
for pauli_label, pauli in zip("xyz", paulis): |
|
|
|
if allclose(sign*pauli, m): |
|
|
|
return "{}{}".format(sign_label, pauli_label) |
|
|
|
|
|
|
|
def get_action(u): |
|
|
|
""" Get the action of a Pauli matrix on three qubits """ |
|
|
|
return tuple(identify_pauli(u*p*u.H) for p in paulis) |
|
|
|
|
|
|
|
def cliff_action(permutation, op): |
|
|
|
""" Computes the action of a particular local Clifford """ |
|
|
|
|
|
|
|
|
|
|
|
if __name__ == '__main__': |
|
|
|
labels = ("a" , "b" , "c" , "d" , "e" , "f") |
|
|
|
signs = (+1 , -1 , -1 , -1 , +1 , +1) |
|
|
|
permutations = ("xyz" , "yxz" , "zyx" , "xzy" , "yzx" , "zxy") |
|
|
|
anders = {} |
|
|
|
anders_inv = {} |
|
|
|
|
|
|
|
for label, sign, permutation in zip(labels, signs, permutations): |
|
|
|
for op in "ixyz": |
|
|
|
signs = [sign if (a == op or op == "i") else -sign for a in "xyz"] |
|
|
|
effect = "".join("{}{}".format(get_sign(x), y) |
|
|
|
for x, y in zip(signs, permutation)) |
|
|
|
anders["{}{}".format(op, label)] = effect |
|
|
|
anders_inv[effect] = "{}{}".format(op, label) |
|
|
|
|
|
|
|
print anders |
|
|
|
print anders_inv |
|
|
|
|
|
|
|
# Build the table of VOPs according to Anders (verbatim from thesis) |
|
|
|
table = (("a", "xyz", +1), ("b", "yxz", -1), ("c", "zyx", -1), |
|
|
|
("d", "xzy", -1), ("e", "yxz", +1), ("f", "zxy", +1)) |
|
|
|
|
|
|
|
for s, sn in zip(s_rotations, s_names): |
|
|
|
for c, cn in zip(c_rotations, c_names): |
|
|
|
action = "".join(get_action(s*c)) |
|
|
|
print anders_inv[action] |
|
|
|
for label, permutation, sign in table: |
|
|
|
for column, operator in zip("ixyz", "i"+permutation): |
|
|
|
effect = [anders_sign_rule(sign, column, p) for p in "xyz"] |
|
|
|
print label+operator, format_action(effect) |
|
|
|
|
|
|
|
for s, sn in zip(s_rotations, s_names): |
|
|
|
for c, cn in zip(c_rotations, c_names): |
|
|
|
u = s*c |
|
|
|
action = tuple(identify_pauli(u*p*u.H) for p in paulis) |
|
|
|
print cn, sn, format_action(action) |
|
|
|
|