|
|
@@ -2,14 +2,23 @@ import clifford as lc |
|
|
|
from numpy import * |
|
|
|
from scipy.linalg import sqrtm |
|
|
|
|
|
|
|
sqy = sqrtm(1j*lc.py) |
|
|
|
msqy = sqrtm(-1j*lc.py) |
|
|
|
sqz = sqrtm(1j*lc.pz) |
|
|
|
msqz = sqrtm(-1j*lc.pz) |
|
|
|
sqx = sqrtm(1j*lc.px) |
|
|
|
msqx = sqrtm(-1j*lc.px) |
|
|
|
sqy = sqrtm(1j * lc.py) |
|
|
|
msqy = sqrtm(-1j * lc.py) |
|
|
|
sqz = sqrtm(1j * lc.pz) |
|
|
|
msqz = sqrtm(-1j * lc.pz) |
|
|
|
sqx = sqrtm(1j * lc.px) |
|
|
|
msqx = sqrtm(-1j * lc.px) |
|
|
|
paulis = (lc.px, lc.py, lc.pz) |
|
|
|
|
|
|
|
|
|
|
|
def find_u(u, unitaries): |
|
|
|
""" Find the index of a given u within a list of unitaries """ |
|
|
|
for i, t in enumerate(unitaries): |
|
|
|
if allclose(t, u): |
|
|
|
return i |
|
|
|
return -1 |
|
|
|
|
|
|
|
|
|
|
|
def identify_pauli(m): |
|
|
|
""" Given a signed Pauli matrix, name it. """ |
|
|
|
for sign in (+1, -1): |
|
|
@@ -17,12 +26,20 @@ def identify_pauli(m): |
|
|
|
if allclose(sign * pauli, m): |
|
|
|
return sign, pauli_label |
|
|
|
|
|
|
|
|
|
|
|
def get_action(u): |
|
|
|
""" What does this unitary operator do to the Paulis? """ |
|
|
|
return [identify_pauli(u * p * u.H) for p in paulis] |
|
|
|
|
|
|
|
|
|
|
|
def format_action(action): |
|
|
|
return "".join("{}{}".format("+" if s>=0 else "-", p) for s, p in action) |
|
|
|
return "".join("{}{}".format("+" if s >= 0 else "-", p) for s, p in action) |
|
|
|
|
|
|
|
|
|
|
|
def test_we_have_24_matrices(): |
|
|
|
""" Check that we have 24 unique actions on the Bloch sphere """ |
|
|
|
actions = set(tuple(get_action(u)) for u in lc.unitaries) |
|
|
|
assert len(set(actions)) == 24 |
|
|
|
|
|
|
|
|
|
|
|
def test_we_have_all_useful_gates(): |
|
|
@@ -30,27 +47,15 @@ def test_we_have_all_useful_gates(): |
|
|
|
names = "i", "px", "py", "pz", "h", "p" |
|
|
|
unitaries = lc.i, lc.px, lc.py, lc.pz, lc.h, lc.p |
|
|
|
for name, unitary in zip(names, unitaries): |
|
|
|
foundit = False |
|
|
|
for i, clifford in enumerate(lc.unitaries): |
|
|
|
if allclose(clifford, unitary): |
|
|
|
foundit = True |
|
|
|
print "{}\t=\tlc.unitaries[{}]".format(name, i) |
|
|
|
assert foundit |
|
|
|
|
|
|
|
names = "sqrt(ix)", "sqrt(-ix)", "sqrt(iy)", "sqrt(-iy)", "sqrt(iz)", "sqrt(-iz)", |
|
|
|
i = find_u(unitary, lc.unitaries) |
|
|
|
assert i >= 0 |
|
|
|
print "{}\t=\tlc.unitaries[{}]".format(name, i) |
|
|
|
|
|
|
|
names = "sqrt(ix)", "sqrt(-ix)", "sqrt(iy)", "sqrt(-iy)", "sqrt(iz)", "sqrt(-iz)", |
|
|
|
unitaries = sqz, msqz, sqy, msqy, sqx, msqx |
|
|
|
for name, unitary in zip(names, unitaries): |
|
|
|
foundit = False |
|
|
|
for phase in range(8): |
|
|
|
for i, clifford in enumerate(lc.unitaries): |
|
|
|
if allclose(exp(1j*phase*pi/4.)*clifford, unitary): |
|
|
|
foundit = True |
|
|
|
print "{}\t=\texp({} . i . pi/4).lc.unitaries[{}]".format(name, phase, i) |
|
|
|
assert foundit |
|
|
|
|
|
|
|
|
|
|
|
def test_we_have_24_matrices(): |
|
|
|
""" Check that we have 24 unique actions on the Bloch sphere """ |
|
|
|
actions = set(tuple(get_action(u)) for u in lc.unitaries) |
|
|
|
assert len(set(actions)) == 24 |
|
|
|
|
|
|
|
rotated = [exp(1j * phase * pi / 4.) * unitary for phase in range(8)] |
|
|
|
results = [find_u(r, lc.unitaries) for r in rotated] |
|
|
|
assert any(x > 0 for x in results) |
|
|
|
phase, index = [(i, r) for i, r in enumerate(results) if r>=0][0] |
|
|
|
print "exp(1j*{}*pi/4) . {}\t=\tlc.unitaries[{}]".format(phase, name, index) |