Quantum Computing is the field of technology that uses principles of quantum mechanics (i.e. Superposition and Entanglement) to process information in a fundamentally different way than classical computers. To put it in simple words, instead of bits (0 or 1), quantum computers use qubits to solve complex, high-dimensional problems in chemistry, material science, and optimization, potentially in seconds rather than years.
In practice, problems are solved by building mathematical models called quantum circuits: sequences of operations and instructions that take some inputs and return an output (similarly to linear regression and neural networks). In quantum computing, those operations are called gates that modify data (qubits) in a different way. Basically, a circuit is a sentence, and the gates are the words composing the sentence.
Circuits are used to run experiments. Specifically, there are 2 types of quantum simulations:
- Using a normal computer to simulate a quantum computer. Like using Python to write a circuit, and a simulator to run it, while a real quantum computer would physically implement the circuit.
- Using a quantum computer to simulate a real quantum system (like atoms or electrons). In nature quantum systems already exist, and classical computers struggle to simulate them because the state space grows exponentially. On the other hand, quantum machines can model these systems more efficiently as they naturally follow the same rules.
In this tutorial, I will show you how to run a quantum simulation on your computer. This article is the sequel to “A Beginner’s Guide to Quantum Computing with Python“.
Setup
First of all, we need to install Qiskit (pip install qiskit), an open-source library for working with quantum computers developed by IBM that allows you to simulate a quantum device on your local machine.
The most basic code we can write is to create a quantum circuit (environment for quantum computation) with only one qubit and initialize it to 0. To measure the state of the qubit, we need a statevector, which basically tells you the current quantum reality of your circuit.
from qiskit import QuantumCircuit
from qiskit.quantum_info import Statevector
q = QuantumCircuit(1,0) #circuit with 1 quantum bit and 0 classic bit
state = Statevector.from_instruction(q) #measure state
state.probabilities() #print prob%
It means that the probability that the qubit is 0 (first element) is 100%, and the probability that the qubit is 1 (second element) is 0%. Let’s visualize the state:
from qiskit.visualization import plot_bloch_multivector
plot_bloch_multivector(state, figsize=(3,3))
Circuits
A quantum gate is a single operation that changes the quantum state. A quantum circuit is a sequence of gates applied to qubits over time.
Let’s start building a simple circuit.
q = QuantumCircuit(1,0) #circuit with 1 quantum bit and 0 classic bit
q.draw(output="mpl", scale=0.7) #show circuit with matplotlib
We have one qubit, but in order to measure it, we need to add a classical bit to our circuit.
q = QuantumCircuit(1,1) #add 1 classic bit
q.draw(output="mpl", scale=0.7)
In order to build a circuit, you should know what you want to achieve, or to put it another way, you need to know the gates and what they do. The approach is similar to Neural Networks: you just use one layer after another to get the desired output (i.e. Convolutions on images and Embeddings on text). The most common operation is the Hadamard Gate (H-gate), which applies Superposition to a qubit.
q = QuantumCircuit(1,1)
q.h(0) #Hadamard gate (Superposition)
q.draw(output="mpl", scale=0.7)
From the image, we see that the red H-gate is applied to the qubit, turning it from a definite 0 into a 50/50 mix of 0 and 1. Let’s add a measurement box, which collapses that Superposition into a real value (either 0 or 1), by storing that result into the classical bit.
q = QuantumCircuit(1,1)
q.h(0)
q.measure(qubit=0, cbit=0) #measure qubit with classic bit
q.draw(output="mpl", scale=0.7)
The circuit has been mathematically designed by my classical computer as it was written on paper, but it hasn’t been executed yet.
Simulation
A quantum simulation is when you use a computer to model the behavior of a quantum system. If you write a circuit (like I did above), you are just describing the mathematical model. To run it, you need a backend engine that executes the quantum circuit in simulation.
Qiskit-Aer (pip install qiskit-aer) is the engine that executes quantum circuits in simulation. Aer lets you run quantum circuits on your computer, simulating different aspects of real quantum hardware (quantum state, measurement, noisy system).
I’m going to run the experiment with the circuit written earlier (a classical bit + a qubit in Superposition) 1000 times.
from qiskit_aer import AerSimulator
sim = AerSimulator()
result = sim.run(q, shots=1000).result()
result.get_counts()
The qubit was measured 1000 times, resulting in 1 for 500 times and 0 for the other 500 times. We can visualize it:
from qiskit.visualization import plot_histogram
plot_histogram(result.get_counts(),
figsize=(5,4), color="black", title="1-qubit in Superposition")
The result is perfectly even because Aer can simulate perfect quantum states, which would be impossible to have on real hardware. In the real world, quantum information is extremely fragile, and it works under the assumption that the system is perfect and stable, allowing particles to exist in multiple states (Coherence). But the moment the qubit interacts with anything, like heat or vibrations, the system loses its harmony and quantum properties (Decoherence).
Therefore, you can visualize a qubit in Superposition (both 0 and 1 at the same time) only in a simulation, but never in the real world. Because the moment you observe the qubit, you bring noise and the system collapses to a single number (0 or 1). In practice, real quantum computers are only for results measurement, while simulations are used for designing quantum models.
To make the experiment more realistic, one can add noise to the simulation.
from qiskit_aer import noise
n = noise.NoiseModel()
error = noise.depolarizing_error(param=0.10, num_qubits=1) #10% error probability
n.add_all_qubit_quantum_error(error=error, instructions=['h'])
sim = AerSimulator(noise_model=n)
result = sim.run(q, shots=1000).result()
plot_histogram(result.get_counts(),
figsize=(5,4), color="black", title="1-qubit in Superposition")
Conclusion
This article has been a tutorial to introduce quantum simulations with Python and Qiskit. We learned what is the difference between a real hardware and a quantum experiment. We also learned how to design quantum circuits and to run a simulation on a classical machine.
Full code for this article: GitHub
I hope you enjoyed it! Feel free to contact me for questions and feedback or just to share your interesting projects.
👉 Let’s Connect 👈

(All images are by the author unless otherwise noted)


