← Back to list

Multi‑Qubit Gates: CNOT, CZ, and SWAP Demystified

Build circuits with controlled gates and show their truth tables using the statevector simulator.

Rahul Tech Articles · 2026-07-25 10:30 · 0 claps · 5.3 min read
#quantum-computing #quantum-gate #qiskit #python-programming #quantum-programming
Open on Medium ↗
Wiki topics: RAG · RAG & Retrieval 💻 · Programming ⚛️ · Physics 📊 · Economic Policy

Multi‑Qubit Gates: CNOT, CZ, and SWAP Demystified

Build circuits with controlled gates and show their truth tables using the statevector simulator.

Introduction

Building on our exploration of single‑qubit gates on the Bloch sphere, we now step into the realm of multi‑qubit gates. These gates are essential for creating entanglement and form the backbone of quantum algorithms such as teleportation, superdense coding, and quantum error correction.

In this article, we’ll demystify three fundamental multi‑qubit gates:

  • CNOT (Controlled‑NOT)
  • CZ (Controlled‑Z)
  • SWAP

We’ll use Qiskit with the Aer simulator to build circuits with these gates and visualise their truth tables using the statevector simulator. The code is designed to run in Jupyter Notebook or Google Colab, making it accessible for both beginners and experienced developers exploring quantum computing.

Setting Up Your Environment

First, set up your Python environment. I recommend using a virtual environment for clean dependency management:

For Windows:

python -m venv medium_quantum_venv
medium_quantum_venv\Scripts\activate

For macOS/Linux:

python3 -m venv medium_quantum_venv
source medium_quantum_venv/bin/activate

Now install the required packages:

pip install qiskit qiskit-aer matplotlib numpy

For the complete notebook with all visualisations, check out the GitHub repository.

Importing Required Libraries

Create a new Jupyter notebook and start with these imports:

from qiskit import QuantumCircuit
from qiskit_aer import AerSimulator
from qiskit.visualization import plot_bloch_multivector
import matplotlib.pyplot as plt
import numpy as np
from IPython.display import display

Helper Function for Visualisation

We’ll create a reusable function to visualise the state vector of any quantum circuit:

def visualize_statevector(circuit, title="Statevector"):
    # Visualize the quantum state as a probability bar chart
    simulator = AerSimulator()
    circuit.save_statevector()
    result = simulator.run(circuit).result()
    statevector = result.get_statevector(circuit)

    # Create bar chart
    n_qubits = circuit.num_qubits
    num_states = 2 ** n_qubits
    states = [format(i, f'0{n_qubits}b') for i in range(num_states)]
    probs = np.abs(statevector) ** 2

    plt.figure(figsize=(14, 6))
    bars = plt.bar(states, probs, color='#1f77b4')
    plt.title(title)
    plt.xlabel('State')
    plt.ylabel('Probability')
    plt.ylim(0, 1)

    # Add value labels on top of bars
    for bar, prob in zip(bars, probs):
        if prob > 0.01:
            plt.text(bar.get_x() + bar.get_width()/2, bar.get_height() + 0.02,
                     f'{prob:.3f}', ha='center', va='bottom')

    plt.show()

    print(f"Statevector: {statevector}")
    return statevector

The CNOT (Controlled‑NOT) Gate

The CNOT gate is a two‑qubit gate that flips the target qubit if the control qubit is in state |1⟩.

Let’s build a circuit to demonstrate the CNOT gate:

# Create a 2-qubit circuit
qc_cnot = QuantumCircuit(2)

# Initialize the state |10⟩ (qubit 0 is control, qubit 1 is target)
# We start with |00⟩, then flip qubit 0 to |1⟩
qc_cnot.x(0)

# Apply CNOT with qubit 0 as control and qubit 1 as target
qc_cnot.cx(0, 1)

# Visualize the statevector
state = visualize_statevector(qc_cnot, "CNOT Gate: |10⟩ → |11⟩")

Expected Output:

  • A bar chart showing probability 1.0 for state |11⟩
  • Statevector: [0.+0.j, 0.+0.j, 0.+0.j, 1.+0.j]

Example: CNOT with Control in |0⟩

# Create a 2-qubit circuit
qc_cnot_2 = QuantumCircuit(2)

# Start with |01⟩ (qubit 0 is 0, qubit 1 is 1)
qc_cnot_2.x(1)

# Apply CNOT with qubit 0 as control and qubit 1 as target
qc_cnot_2.cx(0, 1)

# Visualize the statevector
state = visualize_statevector(qc_cnot_2, "CNOT Gate: |01⟩ → |01⟩")

Expected Output:

  • A bar chart showing probability 1.0 for state |01⟩
  • Statevector: [0.+0.j, 1.+0.j, 0.+0.j, 0.+0.j]

The CZ (Controlled‑Z) Gate

The CZ gate applies a Z gate (phase flip) to the target qubit if the control qubit is in state |1⟩.

# Create a 2-qubit circuit
qc_cz = QuantumCircuit(2)

# Start with |11⟩ (both qubits in |1⟩)
qc_cz.x(0)
qc_cz.x(1)

# Apply CZ gate
qc_cz.cz(0, 1)

# Visualize the statevector
state = visualize_statevector(qc_cz, "CZ Gate: |11⟩ → -|11⟩")

Expected Output:

  • A bar chart showing probability 1.0 for state |11⟩
  • Statevector: [0.+0.j, 0.+0.j, 0.+0.j, -1.+0.j]

Example: CZ with Control in |0⟩

# Create a 2-qubit circuit
qc_cz_2 = QuantumCircuit(2)

# Start with |01⟩ (qubit 0 is 0, qubit 1 is 1)
qc_cz_2.x(1)

# Apply CZ gate
qc_cz_2.cz(0, 1)

# Visualize the statevector
state = visualize_statevector(qc_cz_2, "CZ Gate: |01⟩ → |01⟩")

Expected Output:

  • A bar chart showing probability 1.0 for state |01⟩
  • Statevector: [0.+0.j, 1.+0.j, 0.+0.j, 0.+0.j]

The SWAP Gate

The SWAP gate exchanges the states of two qubits.

# Create a 2-qubit circuit
qc_swap = QuantumCircuit(2)

# Start with |10⟩
qc_swap.x(0)

# Apply SWAP gate
qc_swap.swap(0, 1)

# Visualize the statevector
state = visualize_statevector(qc_swap, "SWAP Gate: |10⟩ → |01⟩")

Expected Output:

  • A bar chart showing probability 1.0 for state |01⟩
  • Statevector: [0.+0.j, 0.+0.j, 1.+0.j, 0.+0.j]

Example: SWAP with |01⟩

# Create a 2-qubit circuit
qc_swap_2 = QuantumCircuit(2)

# Start with |01⟩
qc_swap_2.x(1)

# Apply SWAP gate
qc_swap_2.swap(0, 1)

# Visualize the statevector
state = visualize_statevector(qc_swap_2, "SWAP Gate: |01⟩ → |10⟩")

Expected Output:

  • A bar chart showing probability 1.0 for state |10⟩
  • Statevector: [0.+0.j, 0.+0.j, 1.+0.j, 0.+0.j]

Visualising All Gates Together

Let’s display all gate effects in one figure for comparison:

# Define base circuits
gates = [
    ("CNOT: |10⟩ → |11⟩", QuantumCircuit(2)),
    ("CZ: |11⟩ → -|11⟩", QuantumCircuit(2)),
    ("SWAP: |10⟩ → |01⟩", QuantumCircuit(2)),
]

# Apply operations
# CNOT
gates[0][1].x(0)
gates[0][1].cx(0, 1)

# CZ
gates[1][1].x(0)
gates[1][1].x(1)
gates[1][1].cz(0, 1)

# SWAP
gates[2][1].x(0)
gates[2][1].swap(0, 1)

# Initialize simulator
simulator = AerSimulator()

# Simulate and display each statevector
for label, circuit in gates:
    circ_copy = circuit.copy()
    circ_copy.save_statevector()

    result = simulator.run(circ_copy).result()
    statevector = result.get_statevector(circ_copy)

    # Create bar chart
    n_qubits = circ_copy.num_qubits
    num_states = 2 ** n_qubits
    states = [format(i, f'0{n_qubits}b') for i in range(num_states)]
    probs = np.abs(statevector) ** 2

    plt.figure(figsize=(14, 6))
    bars = plt.bar(states, probs, color='#1f77b4')
    plt.title(label)
    plt.xlabel('State')
    plt.ylabel('Probability')
    plt.ylim(0, 1)

    for bar, prob in zip(bars, probs):
        if prob > 0.01:
            plt.text(bar.get_x() + bar.get_width()/2, bar.get_height() + 0.02,
                     f'{prob:.3f}', ha='center', va='bottom')

    plt.show()
    print(f"Statevector: {statevector}\n")

Expected Output:

  • Three bar charts showing the results of CNOT, CZ, and SWAP gates
  • Each chart clearly shows the resulting state after applying the gate
  • The CZ gate shows a negative phase on the |11⟩ component

Summary of Gate Operations

Conclusion

Multi‑qubit gates are essential for creating entanglement and building powerful quantum algorithms. In this article, we explored three fundamental gates:

  • CNOT is the workhorse of quantum computing, creating entanglement and enabling conditional operations.
  • CZ applies a phase flip based on the control qubit’s state, which is useful in many quantum algorithms.
  • SWAP exchanges qubit states, which is crucial for routing information in quantum circuits.

By visualising the state vectors as probability distributions, we can clearly see how these gates transform qubit states and intuitively understand their truth tables.

The complete code is available in the GitHub repository linked above. Feel free to experiment by modifying the initial states or applying sequences of gates to see how the state vectors change!


메타데이터
post_id
08ac2882e543
slug
multi-qubit-gates-cnot-cz-and-swap-demystified-08ac2882e543
url
https://medium.com/@rahul.techarticles/multi-qubit-gates-cnot-cz-and-swap-demystified-08ac2882e543
canonical_url
https://medium.com/@rahul.techarticles/multi-qubit-gates-cnot-cz-and-swap-demystified-08ac2882e543
author_url
https://medium.com/@rahul.techarticles
status
ok
fetched_at
2026-08-03 11:07:46