Search

Programming quantum circuits

Quantum Computing illustration

Overview

Secondary School

Physics, Mathematics, Computer Science, Engineering

Quantum Computing

English

Summary

This tutorial introduces two practical ways to program quantum circuits for teaching and learning: using a visual drag‑and‑drop interface and writing code with Qiskit. You will learn how to build, visualise, and run simple quantum circuits on simulators or real quantum computers, with step‑by‑step guidance for IBM Quantum and IQM platforms. The focus is on hands‑on experimentation that is accessible for classroom use and teacher training.

Author(s): Christian Datzko (CH), Jörg Gutschank (DE)

This tutorial is part of the teaching material Quantum Computing in STEM Education.

Programming quantum circuits

Quantum circuits can be programmed by simply dragging and dropping the corresponding quantum gates in a designated field.

In the case of the IBM Quantum Composer, operations are dragged from a set of operations at the top left into the field in the middle of the screen. The number of qubits and the number of classical bits for the quantum circuit can be set under <Edit>–<Manage Registers>. The probability and the state of the system are predicted at the bottom of the screen, and export options – for example to Qiskit – are offered on the right.

You can run your circuit on a real IBM quantum computer if you have an account and are logged in. If not, you can use the built-in simulator, which runs the circuit on a classical computer and shows what would happen in an ideal, noise-free quantum system.[1]

Screenshot Composer IBM Quantum Platform
© Screenshot Composer IBM Quantum Platform

How to use Qiskit to run a programme on a quantum computer

Quantum computers may also be programmed with Qiskit. Qiskit is an open source quantum computing framework that allows creating a quantum circuit by typing code lines instead of clicking on visual elements in a graphical interface. The latter can become confusing with larger quantum circuits. Qiskit provides Python modules that can be used on almost any computer. Qiskit not only provides a framework to access real quantum computers, but also to simulators and other useful tools like graphics generation.

Depending on the provider, the ways to access real quantum hardware differ slightly. Below, you find information on how to access quantum computers at IQM, a Finnish quantum hardware provider and at IBM Quantum.

Although a dedicated Python environment is not strictly necessary to run a single example, we use Miniforge to create a clearly defined and isolated Python environment. This is particularly useful for teachers who wish to experiment with both IBM Quantum and IQM backends, as these platforms may, at times, rely on different Python versions or package dependencies.

Access quantum computers at IQM

  1. Install Miniforge for your computer platform in order to create a clearly defined Python environment.
    https://conda-forge.org/miniforge/
     
  2. Create a Python environment using Python version 3.11 (sic!)[2] with the name iqm (for instance) and activate it:

    conda create --name iqm python=3.11
    conda activate iqm
  3. Install the IQM client software that includes also Qiskit:

    pip install "iqm-client[qiskit]"

Note the double quotation marks, without which the installation will not work on a unix or linux shell like zsh or bash.

It might also be useful to further install the python packages numpy, scipy, matplotlib, pylatexenc, and qiskit-aer with:

pip install numpy scipy matplotlib pylatexenc qiskit-aer
  1. Create an account at IQM following this link:
    https://resonance.meetiqm.com/sign-up/scienceonstage
     
  2. Navigate to your profile, create and copy your API token from there.
     
  3. Run the file connection_test_iqm.py (download the file)

    python connection_test_iqm.py

When you are asked for your API token paste it onto the command line and hit enter. The reply IQM backend shows that you successfully connected to IQM. If you prefer, you can also store your API token in advance (for example as an environment variable) so that you do not need to enter it interactively each time (as shown at the end of this introduction in “Creating a simple quantum circuit – Example using IBM”).

  1. Optional: Run the file 1plus1_iqm.py (download the file)

    python 1plus1_iqm.py

This program uses a quantum computer to add one and one. Decide for yourself if it is a good idea to use a quantum computer for this task.

  1. Optional: Install Visual Studio Code (https://code.visualstudio.com) as a graphical frontend.

The above procedure is an installation that works on almost any computer with an internet connection. You may of course use different frontends or so-called Jupyter Notebooks as you prefer.

Access quantum computers at IBM Quantum

  1. Install Miniforge for your computer platform in order to create a clearly defined Python environment.
    https://conda-forge.org/miniforge/
     
  2. Create a Python environment with the name ibm (for instance) and activate it:

    conda create --name ibm python
    conda activate ibm
  3. Install Qiskit (see https://quantum.cloud.ibm.com/docs/en/guides/install-qiskit):

    pip install qiskit
    pip install qiskit-ibm-runtime

It might also be useful to further install the python packages numpy, scipy, matplotlib, pylatexenc, and qiskit-aer.

  1. Create an account at IBM following this link:
    https://quantum.cloud.ibm.com/docs/en/guides/cloud-setup

Note: If you want permanent accounts for your students that do not require to give credit card numbers to IBM after a short trial period, you and every student need a so-called IBM cloud feature code before the account is created. You can get such a code with an academic institution email address only. If in doubt, use a trial account with a separate email address or ask for help at IBM beforehand.

  1. Create and copy your API token from here:
    https://cloud.ibm.com/iam/apikeys

Make sure to directly copy the token after you have created it. The token has 44 characters. When trying to copy it later on, only 43 of the 44 characters are left!

  1. Copy your instance (starts with crn:) from here:
    https://quantum.cloud.ibm.com/instances
     
  2. Run the file connection_test_ibm.py (download the file)

    python connection_test_ibm.py

When you are asked for your API token paste it into the command line and hit enter. Paste in your instance when you are asked for it and hit enter. A reply starting with ibm_ shows that you successfully connected to IBM. If you prefer, you can also store your API token in advance (for example as an environment variable) so that you do not need to enter it interactively each time (as shown at the end of this introduction in “Creating a simple quantum circuit – Example using IBM”)

  1. Optional: Run the file 1plus1_ibm.py (download the file)

    python 1plus1_ibm.py

This program uses a quantum computer to add one and one. Decide for yourself if it is a good idea to use a quantum computer for this task.

  1. Optional: Install Visual Studio Code (https://code.visualstudio.com) as a graphical frontend.

The above procedure is an installation that works on almost any computer with an internet connection. You may of course use different frontends or so-called Jupyter Notebooks as you prefer.

Creating a simple quantum circuit

To create a simple quantum circuit, you have to go through three steps: prepare and initialise the system, assemble the quantum circuit and optimise and execute the quantum circuit.

In the following examples, the same basic quantum operation is used in two different programming environments: a Pauli‑X gate applied to a single qubit. Although the code looks different in each case, it describes the same underlying operation. Differences in names, commands, or structure are often a matter of notation or programming style rather than a difference in quantum functionality.


import os
import getpass
from qiskit import transpile
from qiskit import QuantumCircuit, QuantumRegister, ClassicalRegister
from iqm.qiskit_iqm import IQMProvider

token = getpass.getpass("input IQM API Token: ")
os.environ["IQM_TOKEN"] = token

provider = IQMProvider(
    url="https://resonance.meetiqm.com/",
    # quantum_computer="sirius"
    # quantum_computer="garnet"
    quantum_computer="emerald"
)

backend = provider.get_backend()

qubit_register = QuantumRegister(4, 'q')
bit_register = ClassicalRegister(2, 'c')
qcirc = QuantumCircuit(qubit_register, bit_register)

# setting the input values:
# applying Pauli-X to set a=1
qcirc.x(qubit_register[0])
# applying Pauli-X to set b=1
qcirc.x(qubit_register[1])

# applying quantum gates:
# Toffoli gate
qcirc.ccx(qubit_register[0], qubit_register[1], qubit_register[3])
# CNOT
qcirc.cx(qubit_register[0], qubit_register[1])
# Toffoli
qcirc.ccx(qubit_register[1], qubit_register[2], qubit_register[3])
# CNOT
qcirc.cx(qubit_register[1], qubit_register[2])

# measure qubits 2 and 3
qcirc.measure(qubit_register[2], bit_register[0])
qcirc.measure(qubit_register[3], bit_register[1])

qcirc_transpiled = transpile(qcirc, backend)
job = backend.run(qcirc_transpiled, shots=1024)

print("job id: ", job.job_id())

result = job.result()
counts = result.get_counts()

print(
    "1 + 1 was measured 1024 times. The results are displayed as a binary number followed by the absolute frequency of the respective result."
)
print(counts)

# Create a quantum circuit
from qiskit import QuantumRegister, ClassicalRegister, QuantumCircuit
# Optimise the quantum circuit
from qiskit.transpiler.preset_passmanagers import generate_preset_pass_manager
# Access IBM Quantum
from qiskit_ibm_runtime import QiskitRuntimeService, SamplerV2 as Sampler

service = QiskitRuntimeService(channel="ibm_quantum", token="Insert your API token here, see Profile Settings -> API token")
# Choose the least busy quantum computer as backend
backend = service.least_busy(operational=True, simulator=False) 
# Create a sampler, that will run the job on the chosen backend
sampler = Sampler(backend)
# Create a pass manager that will optimise the quantum circuit for the chosen backend; optimisation level 3 is the highest possible level. Lower levels are easier to understand but produce less accurateresults
passmanager = generate_preset_pass_manager(3, backend=backend) 

# One quantum register is required.
quantum_registers = QuantumRegister(1, 'q')
# One classical register is required.
classical_registers = ClassicalRegister(1, 'c') 
# Both registers are added to the quantum circuit.
circuit = QuantumCircuit(quantum_registers, classical_registers)
# The Pauli-X gate is applied to the quantum register.
circuit.x(quantum_registers[0])
# A measurement is performed on the quantum register and the result is “delivered” to the classical register.
circuit.measure(quantum_registers[0], classical_registers[0])

# Create the optimised quantum circuit
optimized_circuit = passmanager.run(circuit)

# Add the quantum circuit as a job to the job queue
job = sampler.run([optimized_circuit], shots=1000)
# Print the Job ID
print("job id:", job.job_id())
# Wait for the results; this can take some time, but the results will also be available on the IBM Quantum platform if the job is interrupted
result = job.result()
print(result[0].data.c.get_counts())

The code above includes a so-called transpiler that optimises the quantum circuit. This is necessary because real quantum computers do not always offer all the desired gates. Some optimisations also reduce the quantum circuit’s noise and achieve better results.

Different ways to display quantum circuits visually using Qiskit

In addition to executing quantum circuits, Qiskit also offers the option to show quantum circuits in other representations, e.g. instead of executing the circuit, it can be visualised as text, as LaTeX source code or as image file (pixel graphics or vector graphics). Additional formats may be found at https://docs.quantum.ibm.com/api/qiskit/qiskit.visualization.circuit_drawer

# Import register:
from qiskit import QuantumRegister, ClassicalRegister, QuantumCircuit
# For output in LaTeX or as an image:
from qiskit.visualization import circuit_drawer
# For output as a matrix:
from qiskit.quantum_info import Operator
# Prepare the qubits:
quantum_registers = QuantumRegister(1, 'q')
# Prepare the bits:
classical_registers = ClassicalRegister(1, 'c')
# Create a quantum circuit:
circuit = QuantumCircuit(quantum_registers, classical_registers)
# Add a measurement:
circuit.measure(quantum_registers[0], classical_registers[0])
# Output as text:
print("The quantum circuit:")
print(circuit)
print("----------")
# Output in LaTeX:
print("The quantum circuit in LaTeX code:")
circuit_image = circuit_drawer(circuit, output="latex_source")
print(circuit_image)
print("----------")
# Output as image:
print("The quantum circuit as an image, saved as Example.png and Example.svg.")
circuit_image = circuit_drawer(circuit, output="mpl")
circuit_image.savefig("Example.png") # saved as pixel graphics
circuit_image.savefig("Example.svg") # saved as vector graphics
print("----------")

A quantum circuit can also be represented as a matrix that is being applied to one or more qubits that are represented as vectors (or kets). However, this representation does not allow to include measurements. Measurements irreversibly collapse the quantum state and produce random classical results.

The following example shows a quantum circuit with a Hadamard gate

# Prepare the qubits:
quantum_registers = QuantumRegister(1, 'q')
# Prepare the bits:
classical_registers = ClassicalRegister(1, 'c')
# Create a quantum circuit:
circuit = QuantumCircuit(quantum_registers, classical_registers)
circuit.h(quantum_registers[0])
# Matrix output as text
print("The matrix is (text):")
circuit_operator = Operator.from_circuit(circuit)
print(circuit_operator.draw("text"))
print("----------")
# Matrix output
print("The matrix is (LaTeX code):")
circuit_operator = Operator.from_circuit(circuit)
print(circuit_operator.draw("latex_source"))
  1. IQM is only compatible with Python 3.11.

  2. https://docs.quantum.ibm.com/migration-guides/local-simulators

  3. https://quantum.ibm.com/composer/

  4. https://conda-forge.org/miniforge/

Teaching Materials

Close search