Skip to content

Primitives

States

Qudit makes a state an almost first class citizen which allows us to easily create and manipulate quantum states. We can start by defining a basis, which for now is just the computational basis in some dimension. Consider a qutrit (d=3) system:

python
from qudit import Basis

Ket = Basis(3)

And then declare a computational basis pure state via the basis. The following are all equivalent in creating the state |012:

python
Psi = Ket("012")

Psi = Ket(0, 1, 2)

Psi = Ket(0) ^ Ket(1) ^ Ket(2)

We also have a State class which can be used to create more complex states with automatically normalized vectors. A result of this is that states are about as hard to declare in python as they are to write on paper. Consider

|ψ=ω|0000+ω2|1010+3i|2010+|2200+(9i+16)|1210+(ωω2)|0022+(ω1)2|2020+(eiπ18+6)|2221+|0112+(5+9i)|1200+0.67|1111+9eiπ5|2222
python
from qudit import State, Basis

SV = State(
    w * Ket("0000")
    + w**2 * Ket("1010")
    + rt(3) * 1j * Ket("2010")
    + Ket("2200")
    + (9j + 16) * Ket("1210")
    + (w - w**2) * Ket("0022")
    + (w - 1) ** 2 * Ket("2020")
    + (e(1j * pi / 18) + 6) * Ket("2221")
    + Ket("0112")
    + (5 + 9j) * Ket("1200")
    + 0.67 * Ket("1111")
    + (9 * e(1j * pi / 16)) * Ket("2222")
)

Assuming the following preliminaries exist:

python
import numpy as np

Unity = lambda d: np.exp(2j * np.pi / d)
e, rt = np.exp, np.sqrt
pi = np.pi

w, Ket = Unity(3), Basis(4)

Properties of states

States contain several properties, and methods for information and manipulation

PropertyDescription
ddimension of state (e.g. 2 for qubits, 3 for qutrits)
HHermitian conjugate via .conj().T
traceReturn the trace of the state (if density matrix) else return norm squared (if pure state)
isDensityif state is a density matrix (True) else pure state (False)
isPure()if state is pure (True) else density matrix (False)
norm()Return the state normalized to unit norm (if not)
density()Return the density matrix of the state
proj()projector |ψψ| if pure state else ρ
oproj()perpendicular projector I|ψψ| if pure state else Iρ

Gates

Gates in qudit are operators (matrices) that act on states and states. With the same preliminaries as above;

Single-qudit examples

We use the operations

  • @ to apply matmult of an operator on a state, and similarly
  • ^ to build tensor products of states and gates.

For example, for a qubit system:

python
Ket = Basis(2)
G = Gategen(2)

psi = Ket("0")

# Apply a Hadamard
psi = G.H @ psi
print(psi)

# Apply a rotation
psi = G.RY(np.pi/2) @ psi
print(psi) # results in |1>

The above system creates RY(π/2)|+=|1.

Three-qudit GHZ

Similarly we can start with |000 and apply a Hadamard on the first qubit followed by two CNOTs to create a three-qubit GHZ state:

|GHZ=|000+|1112.

python
Ket = Basis(2)
G = Gategen(2)

psi = Ket("000")

HII = G.H ^ G.I ^ G.I
CX1 = G.CX ^ G.I
CX2 = G.I ^ G.CX

psi = CX2 @ (CX1 @ (HII @ psi))
print(psi)

Gategen Generics

Gates are made up of two interoperable classes Unitary and Gate, both of which interop with each other, states, and tensors. The following gates are available in Gategen for a given dimension d in the circuit-less form:

NameSymbolDescription
IdentityIIdentity gate
HadamardHGeneralized Hadamard gate
XXGeneralized Pauli X gate
YYGeneralized Pauli Y gate
ZZGeneralized Pauli Z gate
RX(θ)RX(θ)X rotation axis by θ
RY(θ)RY(θ)Y rotation axis by θ
RZ(θ)RZ(θ)Z rotation axis by θ
CXCXCX gate
CSUMCSUMGeneralized CX gate, or the CSUM gate such that CSUM|i|j=|i|i+jmodd
SWAPSWAPGeneralized SWAP gate such that SWAP|i|j=|j|i

Gategen Special Gates

In addition to these gates there are two special gates called CU or Controlled-U and GMR or GellMann Rotation used as

  • CU is a generalization of the CX gate where the target operation can be any unitary, and the control can be on any state. For example, CU(control=1, target=G.H) applies a Hadamard on the target qudit if the control qudit is in state |1.
  • GMR is a generalization of the RX, RY, RZ gates where the rotation can be on any axis defined by two states. For example, GMR(0, 2, np.pi/2) applies a π/2 rotation on the axis defined by |0 and |2.