Quantum gates

Common single-, two- and three-qubit gates used in quantum circuits, returned as TensorMaps on qubit spaces.

Conventions

Basis ordering

A qubit lives on a two-dimensional space with computational basis ordered as

\[|0⟩,\; |1⟩ \quad \text{(row/column 1 = } |0⟩\text{)}\]

Multi-qubit gates act on $V^{⊗n}$ with the first qubit as the leftmost tensor factor, so a controlled gate uses the first qubit(s) as control and the last as target.

Symmetry sectors

SymmetryPhysical meaningSector labelRepresentable gates
Trivialnoneall gates, full $2^n \times 2^n$ matrix
U1Irrepexcitation-number conservationcharge $∈ \{0, 1\}$ per qubitonly gates that conserve the number of ``
U(1) charge = excitation number

Under U1Irrep the two sectors of a qubit carry charge $0$ ($|0⟩$) and $1$ ($|1⟩$), i.e. the conserved quantity is the number of excited qubits. Only number-conserving gates are representable in this symmetry: pauli_z, proj_0, proj_1, s_gate, t_gate, phase_shift, rotation_z, cz, cs, cphase, swap, iswap, rotation_zz and fredkin. Gates that flip qubits (X, Y, H, CNOT, Toffoli, …) throw an ArgumentError when requested with U1Irrep.

Gate overview

FunctionAlias(es)SitesSupported symmetries
qubit_spaceTrivial, U1Irrep
pauli_xX1Trivial
pauli_yY1Trivial
pauli_zZ1Trivial, U1Irrep
proj_0P01Trivial, U1Irrep
proj_1P11Trivial, U1Irrep
hadamardH1Trivial
s_gateS1Trivial, U1Irrep
t_gateT1Trivial, U1Irrep
phase_shiftP1Trivial, U1Irrep
rotation_xRx1Trivial
rotation_yRy1Trivial
rotation_zRz1Trivial, U1Irrep
cnotCNOT, CX2Trivial
cyCY2Trivial
czCZ2Trivial, U1Irrep
chCH2Trivial
csCS2Trivial, U1Irrep
cphaseCP2Trivial, U1Irrep
swapSWAP2Trivial, U1Irrep
iswapISWAP2Trivial, U1Irrep
dcxDCX2Trivial
ecrECR2Trivial
rotation_xxRxx2Trivial
rotation_yyRyy2Trivial
rotation_zzRzz2Trivial, U1Irrep
rotation_zxRzx2Trivial
toffoliTOFFOLI, CCX3Trivial
fredkinFREDKIN, CSWAP3Trivial, U1Irrep

The adjoint gates $S^\dagger$ and $T^\dagger$ are obtained as s_gate()' and t_gate()'.

API

TensorKitTensors.QuantumGates.basis_transformMethod
basis_transform(symmetry::Type{<:Sector})

Return the unitary basis transformation that maps the computational basis $\{|0⟩, |1⟩\}$ of qubit_space(Trivial) onto the basis of qubit_space(symmetry), as a TensorMap from qubit_space(Trivial) to desymmetrize(qubit_space(symmetry)), as required by symmetrize.

For U1Irrep, the excitation number is used as the $U(1)$ charge, which coincides with the computational basis, such that the transformation is the identity. It is returned with integer scalar type, such that it promotes to any scalar type without loss of precision.

source
TensorKitTensors.QuantumGates.chMethod
ch([eltype::Type{<:Number}], [symmetry::Type{<:Sector}])
CH([eltype::Type{<:Number}], [symmetry::Type{<:Sector}])

The controlled-Hadamard gate $P_0 ⊗ I + P_1 ⊗ H$: applies hadamard to the second qubit if the first is $|1⟩$.

Supported symmetries: Trivial.

source
TensorKitTensors.QuantumGates.cnotMethod
cnot([eltype::Type{<:Number}], [symmetry::Type{<:Sector}])
CNOT([eltype::Type{<:Number}], [symmetry::Type{<:Sector}])
CX([eltype::Type{<:Number}], [symmetry::Type{<:Sector}])

The controlled-NOT gate $P_0 ⊗ I + P_1 ⊗ X$: applies pauli_x to the second qubit if the first is $|1⟩$.

Supported symmetries: Trivial.

source
TensorKitTensors.QuantumGates.cphaseMethod
cphase([eltype::Type{<:Complex}], [symmetry::Type{<:Sector}]; θ)
CP([eltype::Type{<:Complex}], [symmetry::Type{<:Sector}]; θ)

The controlled phase-shift gate $\mathrm{diag}(1, 1, 1, e^{iθ}) = P_0 ⊗ I + P_1 ⊗ \mathrm{phase\_shift}(θ)$. The rotation angle θ is a required keyword; the ASCII name theta is accepted as an alias.

Supported symmetries: Trivial, U1Irrep.

source
TensorKitTensors.QuantumGates.csMethod
cs([eltype::Type{<:Complex}], [symmetry::Type{<:Sector}])
CS([eltype::Type{<:Complex}], [symmetry::Type{<:Sector}])

The controlled-$S$ gate $\mathrm{diag}(1, 1, 1, i)$, i.e. cphase(; θ=π/2).

Supported symmetries: Trivial, U1Irrep.

source
TensorKitTensors.QuantumGates.cyMethod
cy([eltype::Type{<:Complex}], [symmetry::Type{<:Sector}])
CY([eltype::Type{<:Complex}], [symmetry::Type{<:Sector}])

The controlled-Y gate $P_0 ⊗ I + P_1 ⊗ Y$: applies pauli_y to the second qubit if the first is $|1⟩$.

Supported symmetries: Trivial.

source
TensorKitTensors.QuantumGates.czMethod
cz([eltype::Type{<:Complex}], [symmetry::Type{<:Sector}])
CZ([eltype::Type{<:Complex}], [symmetry::Type{<:Sector}])

The controlled-Z gate $\mathrm{diag}(1, 1, 1, -1)$, i.e. cphase(; θ=π).

Supported symmetries: Trivial, U1Irrep.

source
TensorKitTensors.QuantumGates.dcxMethod
dcx([eltype::Type{<:Number}], [symmetry::Type{<:Sector}])
DCX([eltype::Type{<:Number}], [symmetry::Type{<:Sector}])

The double-CNOT gate: two back-to-back CNOTs with alternating control and target.

Supported symmetries: Trivial.

source
TensorKitTensors.QuantumGates.ecrMethod
ecr([eltype::Type{<:Complex}], [symmetry::Type{<:Sector}])
ECR([eltype::Type{<:Complex}], [symmetry::Type{<:Sector}])

The echoed cross-resonance gate $\mathrm{ECR} = \tfrac{1}{\sqrt 2}(I ⊗ X - X ⊗ Y)$.

Supported symmetries: Trivial.

source
TensorKitTensors.QuantumGates.fredkinMethod
fredkin([eltype::Type{<:Number}], [symmetry::Type{<:Sector}])
FREDKIN([eltype::Type{<:Number}], [symmetry::Type{<:Sector}])
CSWAP([eltype::Type{<:Number}], [symmetry::Type{<:Sector}])

The Fredkin (CSWAP) gate $P_0 ⊗ I ⊗ I + P_1 ⊗ \mathrm{swap}$: swaps the last two qubits if the first is $|1⟩$.

Supported symmetries: Trivial, U1Irrep.

source
TensorKitTensors.QuantumGates.hadamardMethod
hadamard([eltype::Type{<:Number}], [symmetry::Type{<:Sector}])
H([eltype::Type{<:Number}], [symmetry::Type{<:Sector}])

The Hadamard gate $H = \tfrac{1}{\sqrt 2}(X + Z)$.

Supported symmetries: Trivial.

source
TensorKitTensors.QuantumGates.iswapMethod
iswap([eltype::Type{<:Complex}], [symmetry::Type{<:Sector}])
ISWAP([eltype::Type{<:Complex}], [symmetry::Type{<:Sector}])

The iSWAP gate, swapping two qubits with an extra factor $i$ on the $|01⟩ ↔ |10⟩$ amplitudes.

Supported symmetries: Trivial, U1Irrep.

source
TensorKitTensors.QuantumGates.pauli_xMethod
pauli_x([eltype::Type{<:Number}], [symmetry::Type{<:Sector}])
X([eltype::Type{<:Number}], [symmetry::Type{<:Sector}])

The Pauli-X (NOT) gate $\begin{pmatrix} 0 & 1 \\ 1 & 0 \end{pmatrix}$.

Supported symmetries: Trivial.

source
TensorKitTensors.QuantumGates.pauli_yMethod
pauli_y([eltype::Type{<:Complex}], [symmetry::Type{<:Sector}])
Y([eltype::Type{<:Complex}], [symmetry::Type{<:Sector}])

The Pauli-Y gate $\begin{pmatrix} 0 & -i \\ i & 0 \end{pmatrix}$.

Supported symmetries: Trivial.

source
TensorKitTensors.QuantumGates.pauli_zMethod
pauli_z([eltype::Type{<:Number}], [symmetry::Type{<:Sector}])
Z([eltype::Type{<:Number}], [symmetry::Type{<:Sector}])

The Pauli-Z gate $\begin{pmatrix} 1 & 0 \\ 0 & -1 \end{pmatrix}$.

Supported symmetries: Trivial, U1Irrep.

source
TensorKitTensors.QuantumGates.phase_shiftMethod
phase_shift([eltype::Type{<:Complex}], [symmetry::Type{<:Sector}]; θ)
P([eltype::Type{<:Complex}], [symmetry::Type{<:Sector}]; θ)

The phase-shift gate $\mathrm{diag}(1, e^{iθ}) = P_0 + e^{iθ} P_1$. The rotation angle θ is a required keyword; the ASCII name theta is accepted as an alias.

Supported symmetries: Trivial, U1Irrep.

source
TensorKitTensors.QuantumGates.proj_0Method
proj_0([eltype::Type{<:Number}], [symmetry::Type{<:Sector}])
P0([eltype::Type{<:Number}], [symmetry::Type{<:Sector}])

The projector onto $|0⟩$, $|0⟩⟨0| = \tfrac{1}{2}(I + Z)$.

Supported symmetries: Trivial, U1Irrep.

source
TensorKitTensors.QuantumGates.proj_1Method
proj_1([eltype::Type{<:Number}], [symmetry::Type{<:Sector}])
P1([eltype::Type{<:Number}], [symmetry::Type{<:Sector}])

The projector onto $|1⟩$, $|1⟩⟨1| = \tfrac{1}{2}(I - Z)$.

Supported symmetries: Trivial, U1Irrep.

source
TensorKitTensors.QuantumGates.qubit_spaceFunction
qubit_space([symmetry::Type{<:Sector}])

Return the local Hilbert space of a single qubit with basis $|0⟩, |1⟩$.

SymmetrySpace
TrivialComplexSpace(2)
U1IrrepU1Space(0 => 1, 1 => 1) (charge = number of excitations)
source
TensorKitTensors.QuantumGates.rotation_xMethod
rotation_x([eltype::Type{<:Complex}], [symmetry::Type{<:Sector}]; θ)
Rx([eltype::Type{<:Complex}], [symmetry::Type{<:Sector}]; θ)

The x-rotation gate $e^{-iθX/2} = \cos\tfrac{θ}{2}\,I - i\sin\tfrac{θ}{2}\,X$. The rotation angle θ is a required keyword; the ASCII name theta is accepted as an alias.

Supported symmetries: Trivial.

source
TensorKitTensors.QuantumGates.rotation_xxMethod
rotation_xx([eltype::Type{<:Complex}], [symmetry::Type{<:Sector}]; θ)
Rxx([eltype::Type{<:Complex}], [symmetry::Type{<:Sector}]; θ)

The XX-rotation (Ising coupling) gate $e^{-iθ\, X ⊗ X / 2} = \cos\tfrac{θ}{2}\,I ⊗ I - i\sin\tfrac{θ}{2}\,X ⊗ X$. The rotation angle θ is a required keyword; the ASCII name theta is accepted as an alias.

Supported symmetries: Trivial.

source
TensorKitTensors.QuantumGates.rotation_yMethod
rotation_y([eltype::Type{<:Complex}], [symmetry::Type{<:Sector}]; θ)
Ry([eltype::Type{<:Complex}], [symmetry::Type{<:Sector}]; θ)

The y-rotation gate $e^{-iθY/2} = \cos\tfrac{θ}{2}\,I - i\sin\tfrac{θ}{2}\,Y$. The rotation angle θ is a required keyword; the ASCII name theta is accepted as an alias.

Supported symmetries: Trivial.

source
TensorKitTensors.QuantumGates.rotation_yyMethod
rotation_yy([eltype::Type{<:Complex}], [symmetry::Type{<:Sector}]; θ)
Ryy([eltype::Type{<:Complex}], [symmetry::Type{<:Sector}]; θ)

The YY-rotation gate $e^{-iθ\, Y ⊗ Y / 2} = \cos\tfrac{θ}{2}\,I ⊗ I - i\sin\tfrac{θ}{2}\,Y ⊗ Y$. The rotation angle θ is a required keyword; the ASCII name theta is accepted as an alias.

Supported symmetries: Trivial.

source
TensorKitTensors.QuantumGates.rotation_zMethod
rotation_z([eltype::Type{<:Complex}], [symmetry::Type{<:Sector}]; θ)
Rz([eltype::Type{<:Complex}], [symmetry::Type{<:Sector}]; θ)

The z-rotation gate $e^{-iθZ/2} = \cos\tfrac{θ}{2}\,I - i\sin\tfrac{θ}{2}\,Z$. The rotation angle θ is a required keyword; the ASCII name theta is accepted as an alias.

Supported symmetries: Trivial, U1Irrep.

source
TensorKitTensors.QuantumGates.rotation_zxMethod
rotation_zx([eltype::Type{<:Complex}], [symmetry::Type{<:Sector}]; θ)
Rzx([eltype::Type{<:Complex}], [symmetry::Type{<:Sector}]; θ)

The ZX-rotation gate $e^{-iθ\, Z ⊗ X / 2} = \cos\tfrac{θ}{2}\,I ⊗ I - i\sin\tfrac{θ}{2}\,Z ⊗ X$. The rotation angle θ is a required keyword; the ASCII name theta is accepted as an alias.

Supported symmetries: Trivial.

source
TensorKitTensors.QuantumGates.rotation_zzMethod
rotation_zz([eltype::Type{<:Complex}], [symmetry::Type{<:Sector}]; θ)
Rzz([eltype::Type{<:Complex}], [symmetry::Type{<:Sector}]; θ)

The ZZ-rotation gate $e^{-iθ\, Z ⊗ Z / 2} = \cos\tfrac{θ}{2}\,I ⊗ I - i\sin\tfrac{θ}{2}\,Z ⊗ Z$. The rotation angle θ is a required keyword; the ASCII name theta is accepted as an alias.

Supported symmetries: Trivial, U1Irrep.

source
TensorKitTensors.QuantumGates.s_gateMethod
s_gate([eltype::Type{<:Complex}], [symmetry::Type{<:Sector}])
S([eltype::Type{<:Complex}], [symmetry::Type{<:Sector}])

The phase gate $S = \sqrt Z = \mathrm{diag}(1, i)$, i.e. phase_shift(; θ=π/2). Its adjoint $S^†$ is s_gate()'.

Supported symmetries: Trivial, U1Irrep.

source
TensorKitTensors.QuantumGates.swapMethod
swap([eltype::Type{<:Number}], [symmetry::Type{<:Sector}])
SWAP([eltype::Type{<:Number}], [symmetry::Type{<:Sector}])

The gate that swaps two qubits, $|ab⟩ ↦ |ba⟩$.

Supported symmetries: Trivial, U1Irrep.

source
TensorKitTensors.QuantumGates.t_gateMethod
t_gate([eltype::Type{<:Complex}], [symmetry::Type{<:Sector}])
T([eltype::Type{<:Complex}], [symmetry::Type{<:Sector}])

The $T$ (π/8) gate $T = \sqrt S = \mathrm{diag}(1, e^{iπ/4})$, i.e. phase_shift(; θ=π/4). Its adjoint $T^†$ is t_gate()'.

Supported symmetries: Trivial, U1Irrep.

source
TensorKitTensors.QuantumGates.toffoliMethod
toffoli([eltype::Type{<:Number}], [symmetry::Type{<:Sector}])
TOFFOLI([eltype::Type{<:Number}], [symmetry::Type{<:Sector}])
CCX([eltype::Type{<:Number}], [symmetry::Type{<:Sector}])

The Toffoli (CCX) gate $P_0 ⊗ I ⊗ I + P_1 ⊗ \mathrm{cnot}$: applies pauli_x to the third qubit if the first two are both $|1⟩$.

Supported symmetries: Trivial.

source