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