The code in this file is available via import utils
(after tangling).
The following class can be used to print colored text to the (ipython) terminal:
class TermColor: """Standard color sequences for coloring text on terminal. Usage: print(TermColor.RED + "In red" + TermColor.ENDC + " in normal color")""" GREEN = '\033[32m' RED = '\033[31m' ENDC = '\033[0m'
The commutator:
def commutator(a, b): """Commutator [a,b] of a and b.""" return a*b - b*a
The Pauli matrices implemented in sage
# Pauli matrices: Id = matrix.identity(2) X = matrix([[0, 1], [1, 0]]) Y = matrix([[0, -i], [i, 0]]) Z = matrix([[1, 0], [0, -1]]) # Hadamard matrix H = matrix([[1, 1], [1, -1]]) / sqrt(2) # Phase gate S = matrix([[1, 0], [0, i]])
The Pauli Rotations
theta = SR.var('theta', domain='real') Rz = matrix([[exp(-i*theta/2), 0], [0, exp(i*theta/2)]]) Rx = matrix([[cos(theta/2), -i*sin(theta/2)], [-i*sin(theta/2), cos(theta/2)]]) Ry = matrix([[cos(theta/2), -sin(theta/2)], [sin(theta/2), cos(theta/2)]])
Next we define the kronecker product, commutator, and functions to create kets and bras from bit-strings:
def kron(A1, *As): """Generalize TensorProduct to one and more then two arguments.""" P = A1 for A in As: P = P.tensor_product(A) return P def commutator(a, b): """Commutator [a,b] of a and b.""" return a*b - b*a def ket(bits: str) -> matrix: """If bits is a string of '0' and '1' this returns |bits>.""" vec = [0] * 2**len(bits) vec[int(bits, 2)] = 1 return vector(vec) def bra(bits: str) -> matrix: """If bits is a string of '0' and '1' this returns <bits|.""" return ket(bits).H
Projection operators
e0 = matrix(ket('0')) e1 = matrix(ket('1')) P0 = e0.H * e0 P1 = e1.H * e1
Some multi-qubit gates:
# Controlled Pauli gates CX = kron(P0, Id) + kron(P1, X) CY = kron(P0, Id) + kron(P1, Y) CZ = kron(P0, Id) + kron(P1, Z) Id2 = kron(Id, Id) CCX = kron(P0, Id2) + kron(P1, CX) SWAP = matrix([ [1, 0, 0, 0], [0, 0, 1, 0], [0, 1, 0, 0], [0, 0, 0, 1], ])
Hilbert-Schmidt inner product:
def trace(M): return M.trace() def inner(A, B): """Hilbert-Schmidt inner product""" return trace(A.H * B)
Kronecker delta and friends:
def sgn(i): """Signum function.""" if i == 0: return 0 return +1 if i > 0 else -1 def delta(i, j): """Kronecker delta.""" return 1 if i == j else 0 def eps(i, j, k): """Levi-Civita symbol.""" assert all(s in [0, 1, 2] for s in [i, j, k]), "Only arguments from 0, 1, 2 are allowed" return (j - i) * (k - j) * (k - i) / 2