The Gate Library

An operation is gate that is applied to a collection of wires, i.e., objects with a wire::id given by a circuit. A gate can be applied to wire(s) by directly constructing a operation object, or by calling one of the create_op methods from a circuit—this will also create an operation object. For example:

#include <tweedledum/tweedledum.hpp>

int main()
{
    using namespace tweedledum;
    netlist<w3_op> circuit;

    wire::id q0 = circuit.create_qubit();
    wire::id q1 = circuit.create_qubit();

    // directly constructing an operation object and emplacing it in the circuit
    w3_op cx_op(gate_lib::cx, q0, q1);
    circuit.emplace_op(cx_op);

    // directly creating an operation in the circuit
    circuit.create_op(gate_lib::cx, q0, q1);
}

Note

When using a network create_op methdos, the returned value is a node::id, which is basically a identifier to a network node that encapsulates the operation.

Gates are classified into three categories: Meta, non-parameterisable, and parameterisable. Meta gates are internal helpers. Non-parameterisable gates are uniquely indentified by a symbol, e.g., a \(\mathrm{T}\) gate is identifed by gate_lib::t, and from that we know its parameters. Parameterisable gates, on the other hand, require the user to define a symbol and the parameters, e.g., we can define a \(\mathrm{R}_1\) gate by gate_lib:r1 and a angle parameter \(\frac\pi4\) (in fact, this gate is the \(\mathrm{T}\) gate).

Warning

It is possible to mix parameterisable and non-parameterisable gates in a quantum circuit representation, but some methods will work sub-optimally. For example:

Suppose you want to optimize your circuit using gate_cancellation(). Somewhere in your circuit, two conditional phase shifts that cancel each other out, say \(\mathrm{T}\) and its adjoint \(\mathrm{T}^{\dagger}\), appear. One is defined symbolically, and the other parametrically (using gate_lib::r1 and pi/4). They won’t be identified as adjoint by the is_adjoint() method defined in the gate class! Hence, this optimization oportunity will be missed.*

Meta gates

Meta gates

Name(s)

tweedledum symbol

Undefined

gate_lib::undefined

Opaque

gate_lib::opaque

Input

gate_lib::input

Non-parameterisable gates

One-qubit gates

Name(s)

Symbol

tweedledum symbol

Identity

\(\mathrm{I}\)

gate_lib::identity

Hadamard

\(\mathrm{H}\)

gate_lib::hadamard

Pauli X, NOT

\(\mathrm{X}\)

gate_lib::x

Pauli Y

\(\mathrm{Y}\)

gate_lib::y

Pauli Z, Phase flip

\(\mathrm{Z}\)

gate_lib::z

Phase

\(\mathrm{S}\)

gate_lib::s

Adjoint Phase

\(\mathrm{S}^{\dagger}\)

gate_lib::sdg

T

\(\mathrm{T}\)

gate_lib::t

Adjoint T

\(\mathrm{T}^{\dagger}\)

gate_lib::tdg

Hadamard

The Hadamard is a half rotation of the Bloch sphere. It rotates around an axis located halfway between the x and z axis. This gives it the effect of rotating states that point along the z axis to those pointing along x, and vice versa.

\[\begin{split}\mathrm{H} = \frac{1}{\sqrt{2}}\pmatrix{1&1 \\ 1&-1}\end{split}\]

Note

The Hadamard gates is central in quantum computing. I can be used to create states in superposition from classical base states:

\[\begin{split}\mathrm{H}|0\rangle = |+\rangle \\ \mathrm{H}|1\rangle = |-\rangle \\\end{split}\]

Since \(\mathrm{H}\) is self-adjoint, i.e., \(\mathrm{H}^\dagger = \mathrm{H}\), the inverse direction also holds:

\[\begin{split}\mathrm{H}|+\rangle = |0\rangle \\ \mathrm{H}|-\rangle = |1\rangle \\\end{split}\]

Remember that both \(|+\rangle\) and \(|-\rangle\), when measured in the computational basis, have 0.5 probability of beign \(|0\rangle\) and 0.5 probability of beign \(|1\rangle\). In other words, one can perceive the behaviour of the hadamard gate as deterministically turning a “random state” into a classical one.

Identity

The identity element of the unitary group \(U(2)\). This does not change the quantum state, so it can be perceived as the absence of a gate.

\[\begin{split}\mathrm{I} = \pmatrix{1&0 \\ 0&1}\end{split}\]

Pauli-X

The Pauli X gate swaps the amplitudes of the quantum base states. As \(X|0\rangle = |1\rangle\) and \(X|1\rangle = |0\rangle\), this gate is also known as \(\mathrm{NOT}\).

\[\begin{split}\sigma_x = \mathrm{X} = \pmatrix{0&1 \\ 1&0}\end{split}\]

Pauli-Y

\[\begin{split}\sigma_y = \mathrm{Y} = \pmatrix{0&-i \\ i&0}\end{split}\]

Pauli-Z

The Pauli Z gate inverts the sign of the second amplitudes of a quantum state.

\[\begin{split}\sigma_z = \mathrm{Z} = \pmatrix{1&0 \\ 0&-1}\end{split}\]

Phase

\[\begin{split}\mathrm{S} = \pmatrix{1&0 \\ 0&i}\end{split}\]

T

\[\begin{split}\mathrm{T} = \pmatrix{1&0 \\ 0&e^{i\frac{\pi}{4}}}\end{split}\]

Two-qubit gates

Name(s)

Symbol

tweedledum symbol

Controlled X, Controlled NOT, CNOT

\(\mathrm{CX}\)

gate_lib::cx

Controlled Y

\(\mathrm{CY}\)

gate_lib::cy

Controlled Z

\(\mathrm{CZ}\)

gate_lib::cz

Swap

\(\mathrm{SWAP}\)

gate_lib::swap

CX

\[\begin{split}\mathrm{CX} = \pmatrix{1&0&0&0 \\ 0&1&0&0 \\ 0&0&0&1 \\ 0&0&1&0}\end{split}\]

CY

\[\begin{split}\mathrm{CX} = \pmatrix{1&0&0&0 \\ 0&1&0&0 \\ 0&0&0&-i \\ 0&0&i&0}\end{split}\]

CZ

\[\begin{split}\mathrm{CZ} = \pmatrix{1&0&0&0 \\ 0&1&0&0 \\ 0&0&1&0 \\ 0&0&0&-1}\end{split}\]

Swap

\[\begin{split}\mathrm{SWAP} = \pmatrix{1&0&0&0 \\ 0&0&1&0 \\ 0&1&0&0 \\ 0&0&0&1}\end{split}\]

N-qubit gates

Name(s)

Symbol

tweedledum symbol

n-Controlled NOT, Toffoli

gate_lib::ncx

n-Controlled Y

gate_lib::ncy

n-Controlled Z

gate_lib::ncz

MCX

\[\begin{split}\mathrm{MCR}_x = \pmatrix{1&&&0&0 \\ &\ddots&&\vdots&\vdots \\ &&1&0&0 \\ 0&\cdots&0&0&1\\ 0&\cdots&0&1&0 }\end{split}\]

MCY

\[\begin{split}\mathrm{MCR}_y = \pmatrix{1&&&0&0 \\ &\ddots&&\vdots&\vdots \\ &&1&0&0 \\ 0&\cdots&0&0&-i \\ 0&\cdots&0&i&0 }\end{split}\]

MCZ

\[\begin{split}\mathrm{MCR}_z = \pmatrix{1&&&0&0 \\ &\ddots&&\vdots&\vdots \\ &&1&0&0 \\ 0&\cdots&0&1&0 \\ 0&\cdots&0&0&-1 }\end{split}\]

Parameterisable gates

One-qubit gates

Name(s)

Symbol

tweedledum symbol

Rotation 1, Phase shift

\(\mathrm{R}_1\)

gate_lib::r1

Rotation X

\(\mathrm{R}_x\)

gate_lib::rx

Rotation Y

\(\mathrm{R}_y\)

gate_lib::ry

Rotation Z

\(\mathrm{R}_z\)

gate_lib::rz

U

\(\mathrm{U}\)

gate_lib::u3

R1

This is a parameterisable conditional phase shift gate. This gate leaves the basis state \(|0\rangle\) unchanged and map \(|1\rangle\) to \(e^{{i\theta }}|1\rangle\). It does not affect probability of measuring a \(|0\rangle\) or \(|1\rangle\), however it modifies the phase of the quantum state. The angle of rotation must be specified in radians and can be positive or negative. It’s matrix form is:

\[\begin{split}\mathrm{R}_1(\theta) = \pmatrix{1&0 \\ 0&e^{i\theta}}\end{split}\]

The gates \(\mathrm{T}\), \(\mathrm{S}\), \(\mathrm{Z}\), \(\mathrm{S}^{\dagger}\), and \(\mathrm{T}^{\dagger}\) can be implemented using this gate:

\[\begin{split}\mathrm{T} &= \mathrm{R}_1(\pi \mathbin{/} 4) \\ \mathrm{S} &= \mathrm{R}_1(\pi \mathbin{/} 2) = \mathrm{T}^2 \\ \mathrm{Z} &= \mathrm{R}_1(\pi) = \mathrm{T}^4 \\ \mathrm{S}^{\dagger} &= \mathrm{R}_1(3\pi \mathbin{/} 2) = \mathrm{T}^6 \\ \mathrm{T}^{\dagger} &= \mathrm{R}_1(7\pi \mathbin{/} 4) = \mathrm{T}^7\end{split}\]

Note that one can obtain it’s adjoint by changing the sign of \(\theta\), i.e.:

\[\mathrm{R}^{\dagger}_1(\theta) = \mathrm{R}_1(-\theta).\]

Note

One might be asking: “Why \(\theta\) is not devided by two?”. As you can see, on all other parameterisable gates this is the case. Well, the answer lies on the following equation:

\[\mathrm{R}_1(\theta) = e^{i\frac{\theta}{2}}\mathrm{R}_z(\theta).\]

This means that \(\mathrm{R}_1(\theta)\) is up to global phase equal to \(\mathrm{R}_z(\theta)\). As long as we don’t do anything that could make the global phases relevant, e.g. adding a control to \(\mathrm{R}_z\), those gates can have the same implementation.

Rx

On the Bloch sphere, this gate corresponds to rotating the qubit state around the x axis by the given angle \(\theta\). The angle of rotation must be specified in radians and can be positive or negative. It’s matrix form is:

\[\begin{split}\mathrm{R}_x(\theta) = \pmatrix{\cos\frac\theta2 & -i\sin\frac\theta2 \\ -i\sin\frac\theta2 & \cos\frac\theta2}\end{split}\]

Ry

On the Bloch sphere, this gate corresponds to rotating the qubit state around the y axis by the given angle \(\theta\). The angle of rotation must be specified in radians and can be positive or negative. It’s matrix form is:

\[\begin{split}\mathrm{R}_y(\theta) = \pmatrix{\cos\frac\theta2 & -\sin\frac\theta2 \\ \sin\frac\theta2 & \cos\frac\theta2}\end{split}\]

Rz

On the Bloch sphere, this gate corresponds to rotating the qubit state around the z axis by the given angle \(\theta\). The angle of rotation must be specified in radians and can be positive or negative. It’s matrix form is

\[\begin{split}\mathrm{R}_z(\theta) = \pmatrix{e^{-i\frac\theta2}&0 \\ 0&e^{i\frac\theta2}}\end{split}\]

U

\[\begin{split}\mathrm{U}(\theta, \phi, \lambda) = \pmatrix{\cos\frac\theta2 & -e^{i\lambda}\sin\frac\theta2 \\ e^{i\phi}\sin\frac\theta2 & e^{i(\lambda + \phi)}\cos\frac\theta2}\end{split}\]

Most one-qubit gates can be implemented using this gates:

\[\begin{split}\mathrm{H} &= \mathrm{U}(\pi \mathbin{/} 2, 0, \pi) \\ \mathrm{I} &= \mathrm{U}(0, 0, 0) \\ \mathrm{X} &= \mathrm{U}(\pi, 0, \pi) \\ \mathrm{Y} &= \mathrm{U}(\pi, \pi \mathbin{/} 2, \pi \mathbin{/} 2) \\ \mathrm{Z} &= \mathrm{U}(0, 0, \pi) \\ \mathrm{S} &= \mathrm{U}(0, 0, \pi \mathbin{/} 2) \\ \mathrm{T} &= \mathrm{U}(0, 0, \pi \mathbin{/} 4) \\ \mathrm{S}^\dagger &= \mathrm{U}(0, 0, -\pi \mathbin{/} 2) = \mathrm{U}(0, 0, 3\pi \mathbin{/} 2)\\ \mathrm{T}^\dagger &= \mathrm{U}(0, 0, -\pi \mathbin{/} 4) = \mathrm{U}(0, 0, 7\pi \mathbin{/} 4) \\ \mathrm{R}_1(\theta) &= \mathrm{U}(0, 0, \theta) \\ \mathrm{R}_x(\theta) &= \mathrm{U}(\theta, -\pi \mathbin{/} 2, \pi \mathbin{/} 2) \\ \mathrm{R}_y(\theta) &= \mathrm{U}(\theta, 0, 0) \\\end{split}\]

Two-qubit gates

Name(s)

Symbol

tweedledum symbol

Controlled rotation X

\(\mathrm{CR}_x\)

gate_lib::crx

Controlled rotation Y

\(\mathrm{CR}_y\)

gate_lib::cry

Controlled rotation Z

\(\mathrm{CR}_z\)

gate_lib::crz

CRx

\[\begin{split}\mathrm{CR}_x = \pmatrix{1&0&0&0 \\ 0&1&0&0 \\ 0&0&\cos\frac\theta2&-i\sin\frac\theta2 \\ 0&0&-i\sin\frac\theta2&\cos\frac\theta2}\end{split}\]

CRy

\[\begin{split}\mathrm{CR}_y = \pmatrix{1&0&0&0 \\ 0&1&0&0 \\ 0&0&\cos\frac\theta2&-\sin\frac\theta2 \\ 0&0&\sin\frac\theta2&\cos\frac\theta2}\end{split}\]

CRz

\[\begin{split}\mathrm{CR}_z = \pmatrix{1&0&0&0 \\ 0&1&0&0 \\ 0&0&e^{-i\frac\theta2}&0 \\ 0&0&0&e^{i\frac\theta2}}\end{split}\]

N-qubit gates

Name(s)

Symbol

tweedledum symbol

n-Controlled rotation X

\(\mathrm{MCR}_x\)

gate_lib::ncrx

n-Controlled rotation Y

\(\mathrm{MCR}_y\)

gate_lib::ncry

n-Controlled rotation Z

\(\mathrm{MCR}_z\)

gate_lib::ncrz

NCRx

\[\begin{split}\mathrm{MCR}_x = \pmatrix{1&&&0&0 \\ &\ddots&&\vdots&\vdots \\ &&1&0&0 \\ 0&\cdots&0&\cos\frac\theta2&-i\sin\frac\theta2 \\ 0&\cdots&0&-i\sin\frac\theta2&\cos\frac\theta2 }\end{split}\]

NCRy

\[\begin{split}\mathrm{MCR}_y = \pmatrix{1&&&0&0 \\ &\ddots&&\vdots&\vdots \\ &&1&0&0 \\ 0&\cdots&0&\cos\frac\theta2&-\sin\frac\theta2 \\ 0&\cdots&0&\sin\frac\theta2&\cos\frac\theta2 }\end{split}\]

NCRz

\[\begin{split}\mathrm{MCR}_z = \pmatrix{1&&&0&0 \\ &\ddots&&\vdots&\vdots \\ &&1&0&0 \\ 0&\cdots&0&e^{-i\frac\theta2}&0 \\ 0&\cdots&0&0&e^{i\frac\theta2} }\end{split}\]