This page was generated from notebooks/gates.ipynb [download].

Supported Gates

The pyzx library supports a variety of gates, including all the commonly-used gates in the OpenQASM standard library. It also supports a subset of the OpenQASM file format.

Here are some examples illustrating the usage:

[2]:
import pyzx as zx
from pyzx.circuit import Circuit, CNOT

# Add pyzx gates.
c = Circuit(2)
c.add_gate("CNOT", 0, 1)
c.add_gate(CNOT(1, 0))

# Adding qasm gates.
s = """
OPENQASM 2.0;
include "qelib1.inc";
qreg q[1];
z q[0];
"""

c1 = zx.qasm(s)
c2 = Circuit.from_qasm(s)  # or: Circuit.from_qasm_file("filename.qasm")

print(c2.to_qasm())
OPENQASM 2.0;
include "qelib1.inc";
qreg q[1];
z q[0];

The set of supported gates are listed below for reference, using the following function to draw their graphs. (Set simplify to True to reduce the graphs, and set show_matrix to True to output their matrices.)

[3]:
from pyzx.circuit.qasmparser import QASMParser

def _print_gate_name(gate):
    print(gate.name + (" (adjoint)" if hasattr(gate, "adjoint") and gate.adjoint else ""))

def draw_zx_diagram(num_qubits, gate_or_qasm, simplify=False, show_matrix=False):
    if isinstance(gate_or_qasm, str):
        qasm = gate_or_qasm
        c = QASMParser().parse(f"qreg q[{num_qubits}];\n" + qasm, strict=False)
        for gate in c.gates:
            _print_gate_name(gate)
        print(qasm)
    else:
        gate = gate_or_qasm
        c = Circuit(num_qubits)
        c.add_gate(gate)
        _print_gate_name(gate)
        print("(no simple qasm command)")

    g = c.to_graph()
    if simplify:
        g.auto_detect_io()
        zx.simplify.full_reduce(g)
    zx.draw(g)
    if show_matrix:
        print(g.to_matrix())

One-qubit gates

Pauli gates and Hadamard

[4]:
draw_zx_diagram(1, 'x q;')
draw_zx_diagram(1, 'y q;')
draw_zx_diagram(1, 'z q;')
draw_zx_diagram(1, 'h q;')
NOT
x q;
Y
y q;
Z
z q;
HAD
h q;

Parametrized one-qubit gates

These are shown with a phase of π/8 for illustrative purposes.

[5]:
draw_zx_diagram(1, 'rx(0.125*pi) q;')
draw_zx_diagram(1, 'ry(0.125*pi) q;')
draw_zx_diagram(1, 'rz(0.125*pi) q;')  # can also use 'p' or 'u1'

draw_zx_diagram(1, 'u2(0.125*pi,0.125*pi) q[0];')
draw_zx_diagram(1, 'u3(0.125*pi,0.125*pi,0.125*pi) q[0];')
XPhase
rx(0.125*pi) q;
YPhase
ry(0.125*pi) q;
ZPhase
rz(0.125*pi) q;
U2
u2(0.125*pi,0.125*pi) q[0];
U3
u3(0.125*pi,0.125*pi,0.125*pi) q[0];

Fixed Z- and X- rotations defined for convenience

[6]:
draw_zx_diagram(1, 's q;')
draw_zx_diagram(1, 'sdg q;')
draw_zx_diagram(1, 't q;')
draw_zx_diagram(1, 'tdg q;')
draw_zx_diagram(1, 'sx q;')
draw_zx_diagram(1, 'sxdg q;')
S
s q;
S (adjoint)
sdg q;
T
t q;
T (adjoint)
tdg q;
SX
sx q;
SX (adjoint)
sxdg q;

Two-qubit gates

Swap

[7]:
draw_zx_diagram(2, 'swap q[0], q[1];')
SWAP
swap q[0], q[1];

Two-qubit rotations

[8]:
draw_zx_diagram(2, 'rxx(0.125*pi) q[0], q[1];')
draw_zx_diagram(2, 'rzz(0.125*pi) q[0], q[1];')
RXX
rxx(0.125*pi) q[0], q[1];
RZZ
rzz(0.125*pi) q[0], q[1];

Controlled versions of (non-parametrized) one-qubit gates

[9]:
from pyzx.circuit import XCX
draw_zx_diagram(2, 'cx q[0], q[1];')
draw_zx_diagram(2, 'cy q[0], q[1];')
draw_zx_diagram(2, 'cz q[0], q[1];')
draw_zx_diagram(2, 'ch q[0], q[1];')
draw_zx_diagram(2, 'csx q[0], q[1];')
draw_zx_diagram(2, XCX(0, 1))
CNOT
cx q[0], q[1];
CY
cy q[0], q[1];
CZ
cz q[0], q[1];
CHAD
ch q[0], q[1];
CSX
csx q[0], q[1];
XCX
(no simple qasm command)

Controlled versions of parametrized one-qubit gates

These are shown with a phase of π/8 for illustrative purposes.

[10]:
draw_zx_diagram(2, 'crx(0.125*pi) q[0], q[1];')
draw_zx_diagram(2, 'cry(0.125*pi) q[0], q[1];')
draw_zx_diagram(2, 'crz(0.125*pi) q[0], q[1];')

# Note that this differs from 'crz' by a relative phase.
draw_zx_diagram(2, 'cp(0.125*pi) q[0], q[1];')  # can also use 'cphase' or 'cu1'

draw_zx_diagram(2, 'cu3(0.125*pi,0.125*pi,0.125*pi) q[0], q[1];')
draw_zx_diagram(2, 'cu(0.125*pi,0.125*pi,0.125*pi,0.125*pi) q[0], q[1];')
CRX
crx(0.125*pi) q[0], q[1];
CRY
cry(0.125*pi) q[0], q[1];
CRZ
crz(0.125*pi) q[0], q[1];
CPhase
cp(0.125*pi) q[0], q[1];
CU3
cu3(0.125*pi,0.125*pi,0.125*pi) q[0], q[1];
CU
cu(0.125*pi,0.125*pi,0.125*pi,0.125*pi) q[0], q[1];

Three-qubit gates

Controlled versions of two-qubit gates

[11]:
draw_zx_diagram(3, 'cswap q[0], q[1], q[2];')  # Fredkin
CSWAP
cswap q[0], q[1], q[2];

Doubly-controlled one-qubit gates

[12]:
draw_zx_diagram(3, 'ccx q[0], q[1], q[2];')  # Toffoli
draw_zx_diagram(3, 'ccz q[0], q[1], q[2];')
Tof
ccx q[0], q[1], q[2];
CCZ
ccz q[0], q[1], q[2];

Other gates

[13]:
from pyzx.circuit import ParityPhase, FSim

draw_zx_diagram(4, ParityPhase(0.5, 0, 1, 2, 3))
draw_zx_diagram(2, FSim(0, 1, 1/2, 1))
ParityPhase
(no simple qasm command)
FSim
(no simple qasm command)