Utilities

\[ \newcommand{\BB}{\mathbb{B}} \newcommand{\CC}{\mathbb{C}} \newcommand{\HH}{\mathbb{H}} \newcommand{\KK}{\mathbb{K}} \newcommand{\NN}{\mathbb{N}} \newcommand{\QQ}{\mathbb{Q}} \newcommand{\RR}{\mathbb{R}} \newcommand{\ZZ}{\mathbb{Z}} \newcommand{\ii}{\mathrm{i}} \newcommand{\jj}{\mathrm{j}} \newcommand{\kk}{\mathrm{k}} \newcommand{\dd}{\mathrm{d}} \newcommand{\FT}{\mathcal{F}} % Fourier Transform \newcommand{\tto}{\twoheadrightarrow} \newcommand{\inv}{^{-1}} \newcommand{\RF}{\mathrm{RF}} \newcommand{\sys}{\mathrm{sys}} \newcommand{\diag}{\mathrm{diag}} \newcommand{\cx}{\mathrm{CX}} \newcommand{\cy}{\mathrm{CY}} \newcommand{\cz}{\mathrm{CZ}} \newcommand{\cat}{\ket{\mathrm{cat}}} \newcommand{\catp}[1]{\ket{\mathrm{cat}_{#1}}} \newcommand{\calE}{\mathcal{E}} \newcommand{\calF}{\mathcal{F}} \newcommand{\calH}{\mathcal{H}} \newcommand{\calR}{\mathcal{R}} \newcommand{\abs}[1]{\left|#1\right|} \newcommand{\norm}[1]{\|#1\|} \newcommand{\sprod}[2]{\langle#1|#2\rangle} % deprecated, use braket instead. \newcommand{\braket}[2]{\langle#1|#2\rangle} % scalar product \newcommand{\ptrace}[2]{\mathrm{tr}_{#1}\left(#2\right)} \newcommand{\trace}[1]{\mathrm{tr}\left(#1\right)} \newcommand{\rank}[1]{\mathrm{rank}\left(#1\right)} \newcommand{\floor}[1]{\lfloor#1\rfloor} \newcommand{\ceil}[1]{\lceil#1\rceil} \newcommand{\bra}[1]{\langle#1|} \newcommand{\ket}[1]{|#1\rangle} \newcommand{\proj}[1]{\ket{#1}\bra{#1}} \newcommand{\mean}[1]{\langle#1\rangle} \newcommand{\wt}[1]{\mathrm{wt}\left(#1\right)} \newcommand{\prob}[1]{\mathrm{Prob}\left[#1\right]} \newcommand{\orac}{\mathrm{Orac}} \newcommand{\?}{} % sometimes I need just a separator other than whitespace \]

The code in this file is available via import utils (after tangling).

Pure Python

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

Sage

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