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
| Symmetry | Physical meaning | Sector label | Representable gates |
|---|---|---|---|
Trivial | none | — | all gates, full $2^n \times 2^n$ matrix |
U1Irrep | excitation-number conservation | charge $∈ \{0, 1\}$ per qubit | only gates that conserve the number of `` |
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
| Function | Alias(es) | Sites | Supported symmetries |
|---|---|---|---|
qubit_space | — | — | Trivial, U1Irrep |
pauli_x | X | 1 | Trivial |
pauli_y | Y | 1 | Trivial |
pauli_z | Z | 1 | Trivial, U1Irrep |
proj_0 | P0 | 1 | Trivial, U1Irrep |
proj_1 | P1 | 1 | Trivial, U1Irrep |
hadamard | H | 1 | Trivial |
s_gate | S | 1 | Trivial, U1Irrep |
t_gate | T | 1 | Trivial, U1Irrep |
phase_shift | P | 1 | Trivial, U1Irrep |
rotation_x | Rx | 1 | Trivial |
rotation_y | Ry | 1 | Trivial |
rotation_z | Rz | 1 | Trivial, U1Irrep |
cnot | CNOT, CX | 2 | Trivial |
cy | CY | 2 | Trivial |
cz | CZ | 2 | Trivial, U1Irrep |
ch | CH | 2 | Trivial |
cs | CS | 2 | Trivial, U1Irrep |
cphase | CP | 2 | Trivial, U1Irrep |
swap | SWAP | 2 | Trivial, U1Irrep |
iswap | ISWAP | 2 | Trivial, U1Irrep |
dcx | DCX | 2 | Trivial |
ecr | ECR | 2 | Trivial |
rotation_xx | Rxx | 2 | Trivial |
rotation_yy | Ryy | 2 | Trivial |
rotation_zz | Rzz | 2 | Trivial, U1Irrep |
rotation_zx | Rzx | 2 | Trivial |
toffoli | TOFFOLI, CCX | 3 | Trivial |
fredkin | FREDKIN, CSWAP | 3 | Trivial, U1Irrep |
The adjoint gates $S^\dagger$ and $T^\dagger$ are obtained as s_gate()' and t_gate()'.
API
TensorKitTensors.QuantumGates.basis_transform — Method
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.
TensorKitTensors.QuantumGates.ch — Method
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.
TensorKitTensors.QuantumGates.cnot — Method
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.
TensorKitTensors.QuantumGates.cphase — Method
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.
TensorKitTensors.QuantumGates.cs — Method
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.
TensorKitTensors.QuantumGates.cy — Method
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.
TensorKitTensors.QuantumGates.cz — Method
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.
TensorKitTensors.QuantumGates.dcx — Method
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.
TensorKitTensors.QuantumGates.ecr — Method
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.
TensorKitTensors.QuantumGates.fredkin — Method
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.
TensorKitTensors.QuantumGates.hadamard — Method
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.
TensorKitTensors.QuantumGates.iswap — Method
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.
TensorKitTensors.QuantumGates.pauli_x — Method
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.
TensorKitTensors.QuantumGates.pauli_y — Method
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.
TensorKitTensors.QuantumGates.pauli_z — Method
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.
TensorKitTensors.QuantumGates.phase_shift — Method
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.
TensorKitTensors.QuantumGates.proj_0 — Method
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.
TensorKitTensors.QuantumGates.proj_1 — Method
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.
TensorKitTensors.QuantumGates.qubit_space — Function
qubit_space([symmetry::Type{<:Sector}])Return the local Hilbert space of a single qubit with basis $|0⟩, |1⟩$.
| Symmetry | Space |
|---|---|
Trivial | ComplexSpace(2) |
U1Irrep | U1Space(0 => 1, 1 => 1) (charge = number of excitations) |
TensorKitTensors.QuantumGates.rotation_x — Method
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.
TensorKitTensors.QuantumGates.rotation_xx — Method
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.
TensorKitTensors.QuantumGates.rotation_y — Method
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.
TensorKitTensors.QuantumGates.rotation_yy — Method
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.
TensorKitTensors.QuantumGates.rotation_z — Method
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.
TensorKitTensors.QuantumGates.rotation_zx — Method
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.
TensorKitTensors.QuantumGates.rotation_zz — Method
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.
TensorKitTensors.QuantumGates.s_gate — Method
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.
TensorKitTensors.QuantumGates.swap — Method
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.
TensorKitTensors.QuantumGates.t_gate — Method
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.
TensorKitTensors.QuantumGates.toffoli — Method
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.