Skip to the content
Kets & Gates homeOpen the app

Lesson 12: Circuits as code

Write circuits in Qiskit, run them, and see where simulation runs out

about 45 min12 partsbest after lesson 11

Start the interactive lesson

The interactive version checks every answer, gives hints and saves your progress in this browser. This page is the same lesson on one page, with the answers folded away.

1 / 12 · Learn

Before you start

Lesson 11 built circuits from a small set of gates and counted what they cost. Real algorithms run to thousands of gates, so people write them as actual programs. This lesson teaches the most widely used toolkit, Qiskit, in an editor that runs it in this page, and ends with a question every simulator meets: how many qubits can an ordinary computer keep up with?

By the end of this lesson you can:

  • write and run a circuit in Qiskit (QuantumCircuit, one method call per gate, measure_all()) and read the counts;
  • convert between Qiskit’s bitstrings (qubit 0 on the right) and the kets in these lessons (qubit 0 on the left);
  • build circuits of any size with loops, and set rotation angles with pi;
  • say what a simulator can show you that a quantum computer can’t;
  • work out the memory a full simulation of nn qubits needs, and why that limit holds only for general circuits;
  • run the same program in Python on your own computer.

Check yourself

A warm-up: make a guess before reading on. The lesson comes back to it.

A Qiskit program on 3 qubits applies X to qubit 0 and nothing else, then measures every qubit with measure_all(). What does Qiskit print for every shot?

  1. A100
  2. B001
  3. C000
  4. D1
Show the answer

Answer: B. 001

Only qubit 0 reads 1. As a ket in these lessons that is ∣100⟩\ket{100}. Qiskit writes qubit 0 as the rightmost bit, so it prints 001.

Why not the others

  • A. That is the order of a ket in these lessons, ∣100⟩\ket{100}, with qubit 0 first. Qiskit writes qubit 0 last, so the 1 for qubit 0 sits at the right end.
  • C. All zeros would mean that nothing flipped. X on qubit 0 makes qubit 0 read 1.
  • D. measure_all() measures every qubit, so each result has 3 bits, one per qubit, including the ones that stayed 0.

Check yourself

A warm-up: make a guess before reading on. The lesson comes back to it.

A laptop with 16 GiB of memory can just hold the full state of 30 qubits for a simulation. A machine with 32 GiB (twice as much) runs the same kind of simulation. About how many qubits can it handle?

  1. A30
  2. B31
  3. C32
  4. D60
Show the answer

Answer: B. 31

Each qubit doubles the memory a full simulation needs. Twice as much memory is 1 doubling, so it holds 1 more qubit: 31.

Why not the others

  • A. More memory does buy more qubits, just not many: each doubling of the memory adds one.
  • C. 2 more qubits would need 22=42^{2} = 4 times the memory, not 2 times: each qubit doubles it.
  • D. That assumes the memory grows in proportion to the number of qubits. Each qubit doubles the number of amplitudes, so twice as much memory buys only 1 more qubit. 60 qubits would need 2302^{30} times the memory of 30.

2 / 12 · Learn

A circuit as a program

A diagram works for a dozen gates. Real algorithms have thousands, built from repeated patterns, so people write them as programs: a two-line loop can lay down a whole layer of gates. The most widely used toolkit is Qiskit, IBM’s open-source Python library. Cirq (from Google), PennyLane (from Xanadu) and Q# (from Microsoft) are others; the ideas carry over, only the spelling changes.

A Qiskit program builds a QuantumCircuit one line at a time. QuantumCircuit(2) makes two qubits, numbered 0 and 1, both starting in ∣0⟩\ket0. Each gate is a method named after it, with qubit numbers as arguments: qc.h(0) adds HH on qubit 0, and qc.cx(0, 1) adds a CNOT with control 0 and target 1 (the control comes first). qc.measure_all() measures every qubit at the end. Here is the Bell-pair circuit of Lesson 7 as code.

Each line adds one piece, in order: line 3 makes the two wires, both starting in ∣0⟩\ket0, lines 4 and 5 the gates, line 6 a meter on every wire. The program reads like the circuit, left to right.

Check yourself

A program makes qc = QuantumCircuit(3), then runs qc.x(2) and qc.cx(2, 0). Which state does it leave? (Kets as in these lessons: ∣q0q1q2⟩\ket{q_0q_1q_2}.)

  1. A∣001⟩\ket{001}
  2. B∣111⟩\ket{111}
  3. C∣100⟩\ket{100}
  4. D∣101⟩\ket{101}
Hints
  1. Which number in qc.cx(2, 0) is the control?
  2. The control comes first. Is qubit 2 a 1 when the CNOT acts?
Show the answer

Answer: D. ∣101⟩\ket{101}

qc.x(2) gives ∣001⟩\ket{001}. In qc.cx(2, 0) the control is qubit 2, which is 1, and the target is qubit 0, which flips: ∣101⟩\ket{101}.

Why not the others

  • A. That is what you’d get if the CNOT did nothing, for example if qubit 0 were its control. In qc.cx(2, 0) the control comes first: qubit 2, which qc.x(2) set to 1, so the target, qubit 0, flips.
  • B. Only the gates written down act: X on qubit 2, then a CNOT that flips qubit 0. Nothing touches qubit 1, so it stays 0.
  • C. A CNOT doesn’t move a 1 from one qubit to another: it flips its target and leaves its control as it is. Qubit 2 stays 1, and qubit 0 becomes 1 as well.

To run a program is to simulate the circuit and sample it. Each shot prepares the state afresh and measures every qubit, and the result is a dictionary of counts: each bitstring with the number of shots that gave it, such as {'00': 507, '11': 493}.

The editor below runs Qiskit-style Python in this page. Press Run and it draws the circuit, shows the state just before the measurements, and plots the counts from 1000 shots. You can change any line and run it again; Reset code brings back the original.

Check yourself

You run the Bell-pair program with 1000 shots. Which printout could you get?

  1. A{'00': 1000}
  2. B{'00': 512, '11': 488}
  3. C{'00': 254, '01': 246, '10': 251, '11': 249}
  4. D{'01': 498, '10': 502}
Show the answer

Answer: B. {'00': 512, '11': 488}

The program makes ∣β00⟩=(∣00⟩+∣11⟩)/2\ket{\beta_{00}} = (\ket{00} + \ket{11})/\sqrt2: 00 and 11 each with probability 12\tfrac12, the other two never. 512 and 488 is a typical split of 1000 shots.

Why not the others

  • A. The Hadamard puts qubit 0 in an equal superposition, and the CNOT copies its value in each branch. So 11 turns up in about half the shots.
  • C. That is two independent fair coins. After the CNOT the qubits always agree: ∣β00⟩=(∣00⟩+∣11⟩)/2\ket{\beta_{00}} = (\ket{00} + \ket{11})/\sqrt2 has no ∣01⟩\ket{01} or ∣10⟩\ket{10} part, so 01 and 10 never appear.
  • D. Those are the results of ∣β01⟩=(∣01⟩+∣10⟩)/2\ket{\beta_{01}} = (\ket{01} + \ket{10})/\sqrt2, whose qubits always disagree. This program starts from ∣00⟩\ket{00} and makes ∣β00⟩\ket{\beta_{00}}, whose qubits always agree.

Check yourself

Starting from ∣xy⟩\ket{xy}, the circuit HH on qubit 0, then a CNOT from qubit 0 to qubit 1, makes the Bell state ∣βxy⟩\ket{\beta_{xy}} (Lesson 7). The program below starts from ∣00⟩\ket{00}. Add lines so that it leaves the qubits in ∣β11⟩=(∣01⟩−∣10⟩)/2\ket{\beta_{11}} = (\ket{01} - \ket{10})/\sqrt2.

from qiskit import QuantumCircuit

qc = QuantumCircuit(2)
# prepare |11> here
qc.h(0)
qc.cx(0, 1)

Write the program in the app’s code editor (Python with Qiskit’s circuit methods), run it, and check it.

Hints
  1. Which input does ∣β11⟩\ket{\beta_{11}} come from, and which gate turns ∣0⟩\ket0 into ∣1⟩\ket1?
  2. Put qc.x(0) and qc.x(1) before the Hadamard, so that the circuit starts from ∣11⟩\ket{11}.
Show the answer

One program that works:

from qiskit import QuantumCircuit

qc = QuantumCircuit(2)
qc.x(0)
qc.x(1)
qc.h(0)
qc.cx(0, 1)

qc.x(0) and qc.x(1) prepare ∣11⟩\ket{11}. HH on qubit 0 then gives 12(∣01⟩−∣11⟩)\tfrac{1}{\sqrt2}(\ket{01} - \ket{11}), and the CNOT flips qubit 1 in the second branch: 12(∣01⟩−∣10⟩)\tfrac{1}{\sqrt2}(\ket{01} - \ket{10}).

3 / 12 · Learn

Qiskit’s bit order

Run qc.x(0) on three qubits and Qiskit prints {'001': 1000}. These lessons write that state as ∣100⟩\ket{100}: qubit 0 is the top wire and the leftmost label, ∣q0q1q2⟩\ket{q_0q_1q_2}. Qiskit reads a bitstring as a binary number in which qubit kk is worth 2k2^k, so qubit 0 is the lowest digit and comes last: it prints q2q1q0q_2q_1q_0. This convention is called little-endian.

Neither spelling is wrong, and the circuit diagram is the same in both, with qubit 0 on top. To convert, reverse the string: Qiskit’s 001 is ∣100⟩\ket{100} here, and ∣011⟩\ket{011} here is Qiskit’s 110. The editor shows both. Its state view uses kets in lesson order; its counts use Qiskit’s strings, and a toggle under them shows the counts as kets.

X on qubit 0 of three. Each wire reads one bit. The ket ∣100⟩\ket{100} lists them from qubit 0 and Qiskit’s 001 from qubit 2, so qubit 0 (ringed) is at opposite ends.

Check yourself

A program leaves its 4 qubits in the basis state ∣1011⟩\ket{1011}, written as in these lessons. What does Qiskit print for every shot?

  1. A0010
  2. B1101
  3. C0100
  4. D1011
Hints
  1. Which end of a ket is qubit 0, and which end of Qiskit’s string?
  2. Reverse the order of the characters. Each one keeps its value.
Show the answer

Answer: B. 1101

A ket here starts with qubit 0; Qiskit’s string ends with it. Reversing ∣1011⟩\ket{1011} gives 1101.

Why not the others

  • A. That reverses the order but also flips every bit. Converting changes only the order: each qubit keeps its value, so a 1 stays a 1.
  • C. That flips every bit and keeps the ket’s order. Converting does the opposite: it keeps every value and reverses the order.
  • D. That copies the ket. A ket here starts with qubit 0, and Qiskit writes qubit 0 last: reverse the string.

Check yourself

Three qubits start in ∣000⟩\ket{000}. Add gates so that every shot of this program prints 110 in Qiskit’s counts.

from qiskit import QuantumCircuit

qc = QuantumCircuit(3)
# add your gates here
qc.measure_all()

Write the program in the app’s code editor (Python with Qiskit’s circuit methods), run it, and check it.

Hints
  1. Which qubit is the rightmost bit of 110, and is it 0 or 1?
  2. Read 110 from the right: qubit 0 is 0, qubit 1 is 1, qubit 2 is 1.
Show the answer

One program that works:

from qiskit import QuantumCircuit

qc = QuantumCircuit(3)
qc.x(1)
qc.x(2)
qc.measure_all()

Reading 110 from the right, qubit 0 is 0 and qubits 1 and 2 are 1, so the program needs qc.x(1) and qc.x(2). In these lessons the state is ∣011⟩\ket{011}.

4 / 12 · Explore

Amplitudes or counts

Predict, then see

This program puts qubit 0 in ∣+⟩\ket+ (with HH) and qubit 1 in ∣−⟩\ket- (with XX, then HH), then measures both. ∣+⟩\ket+ and ∣−⟩\ket- differ only in the sign of their ∣1⟩\ket1 amplitude. What will the counts from 1000 shots look like?

  1. AMostly results in which qubit 1 reads 1, because of the XX
  2. BFewer results in which qubit 1 reads 1: the minus sign lowers their chance
  3. COnly 00 and 01: the minus signs cancel the results in which qubit 1 reads 1
  4. DAll four results, each about 250 times, just as with HH on both qubits

Why do the counts look the same as with HH on both qubits, and what did the extra HH change? A sentence or two is enough.

Show what happens

What happens: D. All four results, each about 250 times, just as with HH on both qubits

Each basis state has amplitude ±12\pm\tfrac12, so each result has probability 14\tfrac14: about 250 shots each, exactly as for ∣+⟩∣+⟩\ket+\ket+. The minus signs are in the state view and nowhere in the counts. Counts only estimate probabilities in the 0/1 basis, so a relative phase is invisible to them. The extra HH turns ∣−⟩\ket- into ∣1⟩\ket1; then qubit 1, the left bit of Qiskit’s strings, reads 1 every time, and only 10 and 11 appear. A gate before the measurement turned the phase into something the counts can see.

Why not the others

  • A. The XX comes before the HH, and H∣1⟩=∣−⟩H\ket1 = \ket-, which reads 0 or 1 with probability 12\tfrac12 each. In Qiskit’s strings qubit 1 is the left bit, and the counts show it 0 and 1 about equally often.
  • B. A probability is the squared magnitude of an amplitude, and ∣−12∣2=∣12∣2=14\abs{-\tfrac12}^2 = \abs{\tfrac12}^2 = \tfrac14. The sign leaves every count where it was.
  • C. Cancelling needs two contributions to the same outcome. Here each outcome has exactly one amplitude, ±12\pm\tfrac12, so nothing cancels; another HH on qubit 1 would be needed to make the branches interfere.

The editor shows two kinds of output, and they come from different places. The state is the simulator’s own bookkeeping: it applies each gate to the full list of amplitudes, so it knows every one exactly. That is a privilege of simulation. A quantum computer has no such readout; all it returns is counts, one bitstring per shot (Lesson 1). Counts estimate probabilities, with a sampling error of about p(1−p)/N\sqrt{p(1-p)/N} for NN shots, and they can’t see a relative phase unless a gate before the measurement turns phase into probability (Lesson 5).

In Python, Statevector(qc) (from qiskit.quantum_info) gives the amplitudes of a circuit without measurements, listed in Qiskit’s order; a sampler gives counts. Quantum algorithms are designed so that the answer comes out in the counts.

Two programs whose amplitudes differ in sign, +12+\tfrac12 or −12-\tfrac12, and whose counts differ only by sampling noise. A quantum computer gives you only the lower view.

Check yourself

All you have is counts: 1000 shots of a two-qubit program on a real device. Which of these can you learn about the state just before the measurement?

Select all that apply.

  1. AThe exact probability of each result
  2. BRoughly how likely each of the four results is
  3. CWhether qubit 1 is ∣+⟩\ket+ or ∣−⟩\ket-, if you first add qc.h(1) before measuring
  4. DWhether qubit 1 is ∣+⟩\ket+ or ∣−⟩\ket-, from these counts as they are
Hint
  1. Counts estimate probabilities in the 0/1 basis. Which of these are such probabilities?
Show the answer

Answers: B. Roughly how likely each of the four results is; C. Whether qubit 1 is ∣+⟩\ket+ or ∣−⟩\ket-, if you first add qc.h(1) before measuring

Counts estimate the 0/1 probabilities and nothing else. A relative phase shows up only after a gate that makes the branches interfere: with HH added, ∣+⟩\ket+ reads 0 every time and ∣−⟩\ket- reads 1 every time.

Why not the others

  • A. Counts are samples, so they only estimate the probabilities. With 1000 shots and p=14p = \tfrac14 the typical error is p(1−p)/1000≈0.014\sqrt{p(1-p)/1000} \approx 0.014, about 14 shots either way.
  • D. ∣+⟩\ket+ and ∣−⟩\ket- give the same 0/1 probabilities, so they give the same counts, as the figure shows. The same counts don’t mean the same state: counts just can’t see a relative phase.

5 / 12 · Learn

Loops and angles

Code pays off when circuits grow. A Python for loop runs the indented lines under it once for each value. range(n) counts 0,1,…,n−10, 1, \ldots, n-1: it starts at 0 and stops before nn. range(a, b) runs from aa to b−1b - 1.

In the program below, the line for q in range(n): and the indented qc.h(q) under it put HH on every qubit, whatever nn is. With n=3n = 3 that makes all 8 three-bit strings equally likely, each with probability 18\tfrac18. A short loop can also sit on one line, for q in range(n): qc.h(q), which is how this lesson writes loops in sentences. Python is strict about indentation; the editor indents for you after a line that ends in a colon.

Check yourself

A program runs qc = QuantumCircuit(4), then for q in range(2, 3): qc.x(q), then qc.measure_all(). What does Qiskit print for every shot?

  1. A0111
  2. B0010
  3. C1100
  4. D0100
Hints
  1. List the values the loop runs through: range(a, b) starts at aa and stops before bb.
  2. Those qubits read 1. Then write the bits with qubit 0 on the right.
Show the answer

Answer: D. 0100

range(2, 3) gives 2, so qubit 2 read 1: as a ket here, ∣0010⟩\ket{0010}. Qiskit writes qubit 0 last, so it prints 0100.

Why not the others

  • A. range(2, 3) starts at 2, not at 0, so the loop never touches qubits 0 to 1.
  • B. That has the right qubits in the order of a ket, qubit 0 first. Qiskit prints qubit 0 last, so reverse it.
  • C. range(2, 3) stops before 3: it gives 2. Qubit 3 is never flipped.

Gates can take numbers too. qc.ry(theta, q) turns qubit qq about the yy axis of the Bloch sphere. From ∣0⟩\ket0 it gives

cos⁡(θ/2)∣0⟩+sin⁡(θ/2)∣1⟩,\cos(\theta/2)\ket0 + \sin(\theta/2)\ket1,

the state at polar angle θ\theta (Lesson 3). Angles are in radians and written with pi, after from math import pi (or as np.pi after import numpy as np): qc.ry(pi / 2, 0) makes ∣+⟩\ket+. Similarly qc.p(phi, q) multiplies the ∣1⟩\ket1 amplitude by eiϕe^{i\phi}, so qc.p(pi / 2, q) is SS and qc.p(pi / 4, q) is TT. Mind the half angle: θ\theta is the angle on the sphere, and the amplitudes use θ/2\theta/2. A loop can give each qubit its own angle, as in for q in range(n): qc.ry(pi / (q + 1), q).

Check yourself

Which angle θ\theta between 0 and π\pi makes qc.ry(theta, 0) turn ∣0⟩\ket0 into a state that reads 0 with probability 34\tfrac34? Enter it in radians, using pi.

Hints
  1. After qc.ry(theta, 0) the amplitudes are cos⁡(θ/2)\cos(\theta/2) and sin⁡(θ/2)\sin(\theta/2). Which one belongs to the outcome asked about?
  2. Square it, set it equal to the probability, and solve for θ/2\theta/2 first.
Show the answer

Answer: 1.0471.047

cos⁡2(θ/2)=34\cos^2(\theta/2) = \tfrac34 gives θ/2=π/6\theta/2 = \pi/6, so θ=π/3\theta = \pi/3.

After qc.ry(theta, 0) the state is cos⁡(θ/2)∣0⟩+sin⁡(θ/2)∣1⟩\cos(\theta/2)\ket0 + \sin(\theta/2)\ket1, so the chance of reading 0 is cos⁡2(θ/2)\cos^2(\theta/2). Setting cos⁡2(θ/2)=34\cos^2(\theta/2) = \tfrac34 gives θ/2=π/6\theta/2 = \pi/6 (the solution between 0 and π/2\pi/2), and so θ=π/3\theta = \pi/3.

Common slips

  • 0.5240.524: That is θ/2\theta/2, the angle inside the amplitudes. ry takes the angle on the Bloch sphere, which is twice as large: cos⁡2(θ/2)=34\cos^2(\theta/2) = \tfrac34 gives θ/2=π/6\theta/2 = \pi/6, so θ=π/3\theta = \pi/3.
  • 2.0942.094: With that angle the probabilities come out the other way round: 0 turns up with probability 14\tfrac14, not 34\tfrac34.
  • 34\frac{3}{4}: That is the probability itself, not an angle. The angle comes from cos⁡2(θ/2)=34\cos^2(\theta/2) = \tfrac34.
  • 2.3562.356: That is the probability times π\pi, but the probability does not grow in proportion to the angle. Solve cos⁡2(θ/2)=34\cos^2(\theta/2) = \tfrac34 instead.

6 / 12 · Worked example

Worked example: a GHZ state from a loop

States are kets in lesson order, ∣q0q1…⟩\ket{q_0q_1\ldots}. The code steps run in the editor; nothing is graded until you press Check.

Worked example

Three qubits by hand, then a loop for five

The GHZ state on nn qubits, 12(∣0…0⟩+∣1…1⟩)\tfrac{1}{\sqrt2}(\ket{0\ldots0} + \ket{1\ldots1}), is the Bell pair’s big sibling: all nn qubits read 0, or all read 1, at random. Its circuit is one Hadamard and a chain of CNOTs. First n=3n = 3, traced by hand; then you write the loop.

  1. Hadamard

    qc.h(0) on ∣000⟩\ket{000} gives 12(∣000⟩+∣100⟩)\tfrac{1}{\sqrt2}(\ket{000} + \ket{100}). Qubit 0 is in superposition; qubits 1 and 2 are still 0.

  2. First CNOT

    qc.cx(0, 1) flips qubit 1 in the branch where qubit 0 is 1: 12(∣000⟩+∣110⟩)\tfrac{1}{\sqrt2}(\ket{000} + \ket{110}). In each branch, qubit 1 now holds a copy of qubit 0’s value.

  3. Second CNOT

    qc.cx(1, 2) does the same one step down: 12(∣000⟩+∣111⟩)\tfrac{1}{\sqrt2}(\ket{000} + \ket{111}). The pattern is qc.cx(i, i + 1) for i=0i = 0 and i=1i = 1: a chain in which each qubit passes the value on to the next.

  4. Your turn: the loop

    Now write the chain as a loop, for five qubits. range(n - 1) gives 0,1,…,n−20, 1, \ldots, n - 2.

    Your turn

    Complete the program with a for loop of CNOTs, so that it leaves five qubits in 12(∣00000⟩+∣11111⟩)\tfrac{1}{\sqrt2}(\ket{00000} + \ket{11111}).

    from qiskit import QuantumCircuit
    
    n = 5
    qc = QuantumCircuit(n)
    qc.h(0)
    # loop here

    Write the program in the app’s code editor (Python with Qiskit’s circuit methods), run it, and check it.

    Hints
    1. After the Hadamard, which gate copies qubit 0’s value onto qubit 1, and then qubit 1’s onto qubit 2?
    2. Two lines: for i in range(n - 1): and, indented under it, qc.cx(i, i + 1).
    Show the answer

    One program that works:

    from qiskit import QuantumCircuit
    
    n = 5
    qc = QuantumCircuit(n)
    qc.h(0)
    for i in range(n - 1):
        qc.cx(i, i + 1)

    for i in range(n - 1): qc.cx(i, i + 1) runs i=0,1,2,3i = 0, 1, 2, 3: four CNOTs that pass qubit 0’s value down the chain, so all five qubits agree in each branch. With the Hadamard that is five gates for five qubits.

  5. Your turn: one pass too many

    Your turn

    A classmate writes the chain as for i in range(n): qc.cx(i, i + 1), with n = 5. What happens when the program runs?

    1. AIt makes the state, but leaves qubit 4 at 0
    2. BAn error: the last pass asks for qc.cx(4, 5), and a five-qubit circuit has only qubits 0 to 4
    3. CEach CNOT runs twice and undoes itself
    4. DIt works: the extra CNOT changes nothing
    Show the answer

    Answer: B. An error: the last pass asks for qc.cx(4, 5), and a five-qubit circuit has only qubits 0 to 4

    range(n) runs i=0,…,4i = 0, \ldots, 4, so the last pass is qc.cx(4, 5). The qubits are numbered 0 to 4, so Qiskit, and this editor, stop with an error there. range(n - 1) stops one pass earlier.

    Why not the others

    • A. Qubit 4 is reached by the pass i=3i = 3, qc.cx(3, 4), as before. The trouble is the extra pass i=4i = 4, which asks for a qubit 5 that doesn’t exist.
    • C. Each value of ii runs once. range(5) just has one more value than range(4): i=4i = 4, which asks for qubit 5.
    • D. range(5) gives 0 to 4, so the last pass is qc.cx(4, 5). There is no qubit 5 in a five-qubit circuit, so the program stops with an error on that line.

The same state from a different loop, fully worked.

Another worked example

Another way: fan out from qubit 0

  1. Hadamard

    Four qubits this time. qc.h(0) gives 12(∣0000⟩+∣1000⟩)\tfrac{1}{\sqrt2}(\ket{0000} + \ket{1000}).

  2. Fan out

    for i in range(1, n): qc.cx(0, i) runs i=1,2,3i = 1, 2, 3, and every CNOT has qubit 0 as its control. In the branch where qubit 0 is 1, each one flips its target: ∣1000⟩→∣1100⟩→∣1110⟩→∣1111⟩\ket{1000} \to \ket{1100} \to \ket{1110} \to \ket{1111}. The branch ∣0000⟩\ket{0000} is left alone.

  3. Result

    The state is 12(∣0000⟩+∣1111⟩)\tfrac{1}{\sqrt2}(\ket{0000} + \ket{1111}), the same GHZ state the chain gives, with the same n−1=3n - 1 = 3 CNOTs. Different programs can make the same state; the loop only has to copy qubit 0’s value onto every other qubit.

Check yourself

Write a program, with a loop, that leaves four qubits in 12(∣0000⟩−∣1111⟩)\tfrac{1}{\sqrt2}(\ket{0000} - \ket{1111}).

from qiskit import QuantumCircuit

n = 4
qc = QuantumCircuit(n)
# your gates here

Write the program in the app’s code editor (Python with Qiskit’s circuit methods), run it, and check it.

Hints
  1. Start from the GHZ program. Which one-qubit gate puts a minus sign on the ∣1⟩\ket1 branch of qubit 0?
  2. Z∣+⟩=∣−⟩Z\ket+ = \ket-: add qc.z(0) right after qc.h(0) (or start qubit 0 in ∣1⟩\ket1 with qc.x(0) before the Hadamard).
Show the answer

One program that works:

from qiskit import QuantumCircuit

n = 4
qc = QuantumCircuit(n)
qc.h(0)
qc.z(0)
for i in range(n - 1):
    qc.cx(i, i + 1)

After qc.h(0) and qc.z(0), qubit 0 is 12(∣0⟩−∣1⟩)\tfrac{1}{\sqrt2}(\ket0 - \ket1). The CNOT chain copies its value in each branch and keeps the sign: 12(∣0000⟩−∣1111⟩)\tfrac{1}{\sqrt2}(\ket{0000} - \ket{1111}). A ZZ on any one qubit after the chain works too.

7 / 12 · Learn

How far simulation goes

The editor stores the full state: 2n2^n complex amplitudes for nn qubits. A computer keeps each amplitude as two 8-byte numbers, its real and imaginary parts, so 16 bytes in all, and a full statevector takes

16×2n bytes.16 \times 2^n \text{ bytes}.

Each extra qubit doubles the list of amplitudes, and so doubles the memory. Ten qubits, this editor’s limit, take 16×102416 \times 1024 bytes, which is 16 KiB. Thirty qubits take 2342^{34} bytes, or 16 GiB (1 GiB is 2302^{30} bytes): about what a laptop has. Thirty-one qubits need 32 GiB, thirty-two need 64 GiB. Adding a qubit is one more line of code, and it doubles what the simulator needs.

Each qubit doubles it: the real need doubles with each qubit (solid bars), while a need in proportion to nn (dashed) would barely move. Every 10 qubits multiply it by 210=10242^{10} = 1024.

Check yourself

How many GiB does the full statevector of 28 qubits take, at 16 bytes per amplitude? (1 GiB is 2302^{30} bytes.)

Hints
  1. How many amplitudes does the state have, and how many bytes is each?
  2. The state takes 16×2n=2n+416\times2^n = 2^{n+4} bytes. Divide by 2302^{30} to get GiB.
Show the answer

Answer: 44

28 qubits have 2282^{28} amplitudes at 16=2416 = 2^4 bytes each: 2322^{32} bytes, which is 22=42^{2} = 4 GiB.

Common slips

  • 14.93314.933: That grows the memory in proportion to the number of qubits, from 16 GiB at 30. But each qubit doubles the number of amplitudes: 28 qubits have 2282^{28} of them, so the memory is 16×22816\times2^{28} bytes =4= 4 GiB.
  • 14\frac{1}{4}: That is 2282^{28} bytes: one byte per amplitude. Each amplitude takes 16 bytes, so multiply by 16.
  • 22: That is 8 bytes per amplitude, enough for one real number. An amplitude is complex, a real and an imaginary part, so it takes 16 bytes.

Every ten qubits multiply the memory by 210=10242^{10} = 1024. Forty qubits need 16 TiB, more than one ordinary machine holds; fifty need 16 PiB, about as much as the very largest supercomputers have in all; sixty need 16 EiB, beyond any computer. The time grows the same way, since every gate updates the whole list.

Two caveats. First, this is the cost of a general circuit. Special circuits go much further. A circuit built only from HH, SS and CNOT (the Clifford gates) can be followed with a table whose size grows like n2n^2, and a circuit with little entanglement can be stored as a network of small pieces instead of one long list. Second, methods that save memory do exist, for example adding up the contributions to one amplitude one path at a time, but for a general circuit they pay with exponential time instead.

Check yourself

A news story says a team simulated a 1,000-qubit circuit on an ordinary laptop. Which response is most accurate?

  1. AImpossible: storing 210002^{1000} amplitudes needs more memory than any computer will ever have
  2. BPossible for any circuit: memory grows with the number of qubits, so 1,000 qubits take about 33 times the memory of 30
  3. CPossible for any circuit, as long as the laptop runs long enough
  4. DPossible if the circuit is special, for example built only from Clifford gates or with little entanglement; a general circuit that size is far out of reach
Hint
  1. Does every simulation have to store the full statevector?
Show the answer

Answer: D. Possible if the circuit is special, for example built only from Clifford gates or with little entanglement; a general circuit that size is far out of reach

A general circuit needs 16×2100016\times2^{1000} bytes for its statevector, or exponential time with methods that save memory. Special circuits, such as Clifford-only ones or ones with little entanglement, have structure that cleverer methods exploit, and those reach thousands of qubits.

Why not the others

  • A. True for the full statevector of a general circuit, but not every simulation stores one. A circuit made only of HH, SS and CNOT can be followed with a table of about 4n24n^2 bits, some 4,000,000 for 1,000 qubits. The claim depends on what the circuit is.
  • B. The memory for a full statevector doubles with each qubit, so 1,000 qubits need 29702^{970} times the memory of 30, not 33 times. Only special circuits avoid that.
  • C. Waiting helps only methods that trade memory for time, and for a general circuit that time grows exponentially too. A general circuit this size is out of reach whichever way you trade.

8 / 12 · Learn

Running it on your own computer

Everything you typed here is real Qiskit. To run it on your own computer, install Python, then type pip install qiskit in a terminal. One thing changes: this page runs the circuit for you, while in Python you hand it to a sampler, an object that runs circuits and returns counts. StatevectorSampler computes the exact state on your machine and samples from it, as this page does. Its result keeps the counts under the name of the classical bits that hold them, and measure_all() names those bits meas.

Check yourself

The program reads its counts with result[0].data.meas.get_counts(). Where does the name meas come from?

  1. A[0] picks qubit 0, and meas is its measurement
  2. Bmeasure_all() adds a set of classical bits named meas to hold the results
  3. CThe sampler always files counts under meas, whatever the circuit
Show the answer

Answer: B. measure_all() adds a set of classical bits named meas to hold the results

measure_all() adds classical bits named meas and measures every qubit into them, so the sampler files the counts under meas. result[0] is the first circuit in the list passed to run, here the only one.

Why not the others

  • A. [0] picks a circuit, not a qubit. run takes a list of circuits, [qc] here, and result[0] holds the results of the first. Its counts cover every qubit.
  • C. The sampler files counts under the name of the classical bits that hold them. measure_all() happens to call them meas; a circuit made with QuantumCircuit(2, 2) and measured into its own bits calls them c, and its counts are at data.c.

To use a real quantum computer, two more things change. The circuit is first transpiled: rewritten into the gates and connections that the chip actually has, using a universal gate set as in Lesson 11. And the sampler comes from qiskit_ibm_runtime, which sends the job to IBM’s hardware queue; IBM offers free, limited access to some of its quantum processors. The counts then contain errors. Gates and readout are imperfect, so a Bell pair gives mostly 00 and 11, plus a few percent of 01 and 10. Simulators have no such errors, which is one more reason to test programs on them first.

Check yourself

You run the Bell-pair program on a real device with 1000 shots and get {'00': 481, '11': 467, '01': 27, '10': 25}. What best explains the 52 shots that read 01 or 10?

  1. AHardware errors: real gates and readout are imperfect, so a few percent of shots come out wrong
  2. BQiskit’s bit order: 01 is really 10
  3. CSampling noise: with 1000 shots every possible result turns up now and then
Show the answer

Answer: A. Hardware errors: real gates and readout are imperfect, so a few percent of shots come out wrong

An ideal Bell pair gives only 00 and 11. The 5.2% of shots that read 01 or 10 come from errors in the gates and in the readout of a real device; a simulator would show none.

Why not the others

  • B. Reversing turns 01 into 10 and back, but a perfect Bell pair gives neither: its two qubits always agree. Bit order can’t explain results that shouldn’t appear in either order.
  • C. Sampling noise moves counts around their expected values, but a result with probability 0 never turns up in an ideal run. The simulator gives no 01 or 10 however many shots you take.

9 / 12 · Practice

Practice

Four items: a conversion, a memory sum, and two programs to write. Hints are there if you need them.

Check yourself

A program leaves its 3 qubits in the basis state ∣100⟩\ket{100}, written as in these lessons. What does Qiskit print for every shot?

  1. A110
  2. B011
  3. C001
  4. D100
Hints
  1. Which end of a ket is qubit 0, and which end of Qiskit’s string?
  2. Reverse the order of the characters. Each one keeps its value.
Show the answer

Answer: C. 001

A ket here starts with qubit 0; Qiskit’s string ends with it. Reversing ∣100⟩\ket{100} gives 001.

Why not the others

  • A. That reverses the order but also flips every bit. Converting changes only the order: each qubit keeps its value, so a 1 stays a 1.
  • B. That flips every bit and keeps the ket’s order. Converting does the opposite: it keeps every value and reverses the order.
  • D. That copies the ket. A ket here starts with qubit 0, and Qiskit writes qubit 0 last: reverse the string.

Check yourself

A computer has 256 GiB of memory free for a simulation. What is the largest number of qubits whose full statevector fits, at 16 bytes per amplitude?

Hints
  1. How many bytes does the statevector of nn qubits take?
  2. It takes 16×2n=2n+416\times2^n = 2^{n+4} bytes. Write the memory as a power of 2 too.
Show the answer

Answer: 3434

256 GiB is 2382^{38} bytes, and nn qubits take 16×2n=2n+416\times2^n = 2^{n+4} bytes, so n+4=38n + 4 = 38: 34 qubits. One more would need twice the memory.

Common slips

  • 480480: That scales the 30 qubits that fit in 16 GiB in proportion to the memory. But one more qubit already doubles the memory, so 256 GiB, which is 242^{4} times 16 GiB, buys only 4 more qubits: 34.
  • 3838: That allows one byte per amplitude. Each takes 16=2416 = 2^4 bytes, so nn qubits need 2n+42^{n+4} bytes, and n+4=38n + 4 = 38.
  • 3535: That allows 8 bytes per amplitude, one real number. An amplitude is complex and takes 16 bytes, so one qubit fewer fits.

Check yourself

Write a program, with a loop and ry at an angle between 0 and π\pi, that leaves three qubits each reading 1 with probability 14\tfrac14, independently of one another. The state view is off: work it out, or add qc.measure_all() and compare the counts.

from qiskit import QuantumCircuit
from math import pi

n = 3
qc = QuantumCircuit(n)
# your loop here

Write the program in the app’s code editor (Python with Qiskit’s circuit methods), run it, and check it.

Hints
  1. Which angle gives one qubit probability 14\tfrac14 of reading 1? You found it earlier in this lesson.
  2. sin⁡2(θ/2)=14\sin^2(\theta/2) = \tfrac14 gives θ=π/3\theta = \pi/3. Apply qc.ry(pi / 3, q) to each qubit in a loop.
Show the answer

One program that works:

from qiskit import QuantumCircuit
from math import pi

n = 3
qc = QuantumCircuit(n)
for q in range(n):
    qc.ry(pi / 3, q)

qc.ry(pi / 3, q) gives 32∣0⟩+12∣1⟩\tfrac{\sqrt3}{2}\ket0 + \tfrac12\ket1, which reads 1 with probability (12)2=14(\tfrac12)^2 = \tfrac14. Applied to each qubit separately it makes a product state, so the three results are independent: 000 comes up with probability (34)3=2764(\tfrac34)^3 = \tfrac{27}{64}.

Check yourself

Write a program on four qubits whose counts show only 0001 and 1110, about half each. (These are Qiskit’s strings: qubit 0 is on the right.)

from qiskit import QuantumCircuit

qc = QuantumCircuit(4)
# your gates here
qc.measure_all()

Write the program in the app’s code editor (Python with Qiskit’s circuit methods), run it, and check it.

Hints
  1. Write the two strings as kets first: reverse them. How do the qubits relate in each?
  2. As kets they are ∣1000⟩\ket{1000} and ∣0111⟩\ket{0111}: qubits 1 to 3 always hold the opposite of qubit 0. Build a GHZ-style state from qubit 0, then flip qubits 1, 2 and 3.
Show the answer

One program that works:

from qiskit import QuantumCircuit

qc = QuantumCircuit(4)
qc.h(0)
for q in range(1, 4):
    qc.cx(0, q)
    qc.x(q)
qc.measure_all()

Reversed, the strings are ∣1000⟩\ket{1000} and ∣0111⟩\ket{0111}: every other qubit is the opposite of qubit 0. HH on qubit 0, a CNOT from qubit 0 to each other qubit, and an XX on each of them give 12(∣0111⟩+∣1000⟩)\tfrac{1}{\sqrt2}(\ket{0111} + \ket{1000}).

10 / 12 · Explain

Explain it

Explain it

Your laptop simulates 30-qubit circuits easily. Explain why a general 60-qubit circuit is out of reach for it, and for every other computer, while some special circuits with hundreds of qubits are not.

Show a model answer

A full simulation stores the statevector: 2n2^n complex amplitudes at 16 bytes each. Every extra qubit doubles that, so 60 qubits need 2302^{30} times the memory of 30, about 16 EiB instead of 16 GiB, far more than any computer has. Methods that use less memory exist, but for a general circuit they take exponentially long instead. Special circuits have structure that a cleverer method can exploit: a circuit built only from Clifford gates (HH, SS, CNOT) can be followed with a table whose size grows like n2n^2, and a circuit with little entanglement can be stored as a network of small pieces. A general circuit offers neither shortcut.

A good answer covers

  • A full statevector holds 2n2^n amplitudes of 16 bytes each, so each extra qubit doubles the memory
  • 60 qubits need 2302^{30} times the memory of 30; trading memory for time doesn’t rescue a general circuit, because the time then grows exponentially
  • Special circuits (Clifford-only, or with little entanglement) have structure that other methods exploit, so they can be simulated at large sizes

11 / 12 · Mastery check

Mastery check

Check yourself

A Qiskit program on 4 qubits applies X to qubit 3 and nothing else, then measures every qubit with measure_all(). What does Qiskit print for every shot?

  1. A1000
  2. B0001
  3. C0011
  4. D1
Show the answer

Answer: A. 1000

Only qubit 3 reads 1. As a ket in these lessons that is ∣0001⟩\ket{0001}. Qiskit writes qubit 0 as the rightmost bit, so it prints 1000.

Why not the others

  • B. That is the order of a ket in these lessons, ∣0001⟩\ket{0001}, with qubit 0 first. Qiskit writes qubit 0 last, so the 1 for qubit 3 sits 3 places from the right end.
  • C. That is the number 3 written in binary. Here a bitstring has one character per qubit, and only qubit 3 reads 1.
  • D. measure_all() measures every qubit, so each result has 4 bits, one per qubit, including the ones that stayed 0.

Check yourself

Write a program that leaves two qubits in ∣β10⟩=(∣00⟩−∣11⟩)/2\ket{\beta_{10}} = (\ket{00} - \ket{11})/\sqrt2.

from qiskit import QuantumCircuit

qc = QuantumCircuit(2)
# your gates here

Write the program in the app’s code editor (Python with Qiskit’s circuit methods), run it, and check it.

Hints
  1. Start from the right input ∣xy⟩\ket{xy}: an x gate on each qubit whose bit is 1.
  2. Then HH on qubit 0, and a CNOT with control 0 and target 1.
Show the answer

One program that works:

from qiskit import QuantumCircuit

qc = QuantumCircuit(2)
qc.x(0)
qc.h(0)
qc.cx(0, 1)

∣β10⟩\ket{\beta_{10}} comes from the input ∣10⟩\ket{10}: qc.x(0) prepares it. Then qc.h(0) and qc.cx(0, 1) turn it into the Bell state.

Check yourself

Write a program on 3 qubits so that every shot prints 011 in Qiskit’s counts.

from qiskit import QuantumCircuit

qc = QuantumCircuit(3)
# your gates here
qc.measure_all()

Write the program in the app’s code editor (Python with Qiskit’s circuit methods), run it, and check it.

Hints
  1. Which end of Qiskit’s string is qubit 0?
  2. Read the string from the right: character kk from the right is qubit kk. Put an X on each qubit that should read 1.
Show the answer

One program that works:

from qiskit import QuantumCircuit

qc = QuantumCircuit(3)
qc.x(0)
qc.x(1)
qc.measure_all()

Read 011 from the right: its last character is qubit 0. The 1s belong to qubits 0 and 1, so the program needs qc.x(0) and qc.x(1). As a ket here the state is ∣110⟩\ket{110}.

Check yourself

A laptop with 16 GiB of memory can just hold the full state of 30 qubits for a simulation. A machine with 128 GiB (8 times as much) runs the same kind of simulation. About how many qubits can it handle?

  1. A30
  2. B33
  3. C38
  4. D240
Show the answer

Answer: B. 33

Each qubit doubles the memory a full simulation needs. 8 times as much memory is 3 doublings, so it holds 3 more qubits: 33.

Why not the others

  • A. More memory does buy more qubits, just not many: each doubling of the memory adds one.
  • C. 8 more qubits would need 28=2562^{8} = 256 times the memory, not 8 times: each qubit doubles it.
  • D. That assumes the memory grows in proportion to the number of qubits. Each qubit doubles the number of amplitudes, so 8 times as much memory buys only 3 more qubits. 240 qubits would need 22102^{210} times the memory of 30.

Check yourself

How many GiB does the full statevector of 29 qubits take, at 16 bytes per amplitude? (1 GiB is 2302^{30} bytes.)

Hints
  1. How many amplitudes does the state have, and how many bytes is each?
  2. The state takes 16×2n=2n+416\times2^n = 2^{n+4} bytes. Divide by 2302^{30} to get GiB.
Show the answer

Answer: 88

29 qubits have 2292^{29} amplitudes at 16=2416 = 2^4 bytes each: 2332^{33} bytes, which is 23=82^{3} = 8 GiB.

Common slips

  • 15.46715.467: That grows the memory in proportion to the number of qubits, from 16 GiB at 30. But each qubit doubles the number of amplitudes: 29 qubits have 2292^{29} of them, so the memory is 16×22916\times2^{29} bytes =8= 8 GiB.
  • 12\frac{1}{2}: That is 2292^{29} bytes: one byte per amplitude. Each amplitude takes 16 bytes, so multiply by 16.
  • 44: That is 8 bytes per amplitude, enough for one real number. An amplitude is complex, a real and an imaginary part, so it takes 16 bytes.

Check yourself

Program A applies qc.h(0) to one qubit; program B applies qc.x(0); qc.h(0). Both end with qc.measure_all() and run for 1000 shots on a real device. Which statement is right?

  1. AB shows more 1s than A, because of its extra gate
  2. BBoth show about 50/50, so the two programs prepare the same state
  3. CB shows 1 every time, because of the X
  4. DBoth show about 50% 0 and 50% 1, although they prepare different states
Show the answer

Answer: D. Both show about 50% 0 and 50% 1, although they prepare different states

A prepares ∣+⟩\ket+ and B prepares ∣−⟩=(∣0⟩−∣1⟩)/2\ket- = (\ket0 - \ket1)/\sqrt2. Both have ∣0⟩\ket0 and ∣1⟩\ket1 amplitudes of size 1/21/\sqrt2, so both read 0 and 1 half the time each. The relative phase differs, and counts can’t see it; an HH before the measurement would make their counts differ.

Why not the others

  • A. B prepares ∣−⟩=(∣0⟩−∣1⟩)/2\ket- = (\ket0 - \ket1)/\sqrt2. Its ∣1⟩\ket1 amplitude has the same size as A’s, 1/21/\sqrt2, and only a different phase, so the probability of 1 is 12\tfrac12 for both.
  • B. Matching counts in the 0/1 basis don’t make two states equal. A prepares ∣+⟩\ket+ and B prepares ∣−⟩=(∣0⟩−∣1⟩)/2\ket- = (\ket0 - \ket1)/\sqrt2: they differ by a relative phase, which shows up only after another gate, such as an HH just before the measurement.
  • C. The HH after the XX turns ∣1⟩\ket1 into ∣−⟩=(∣0⟩−∣1⟩)/2\ket- = (\ket0 - \ket1)/\sqrt2, which reads 0 or 1 with probability 12\tfrac12 each.

Check yourself

Write a program, with a loop, that leaves 5 qubits in 12(∣00000⟩+∣11111⟩)\tfrac{1}{\sqrt2}(\ket{00000} + \ket{11111}).

from qiskit import QuantumCircuit

n = 5
qc = QuantumCircuit(n)
# your gates here

Write the program in the app’s code editor (Python with Qiskit’s circuit methods), run it, and check it.

Hints
  1. Start like the GHZ program: one Hadamard, then a chain of CNOTs in a loop.
  2. If the state has a minus sign, add qc.z(0) right after qc.h(0).
Show the answer

One program that works:

from qiskit import QuantumCircuit

n = 5
qc = QuantumCircuit(n)
qc.h(0)
for i in range(n - 1):
    qc.cx(i, i + 1)

qc.h(0) put qubit 0 in ∣+⟩\ket+. The chain for i in range(n - 1): qc.cx(i, i + 1) copies its value down to qubit 4 in each branch and keeps the sign: 12(∣00000⟩+∣11111⟩)\tfrac{1}{\sqrt2}(\ket{00000} + \ket{11111}), with 5 gates.

12 / 12 · Recap

Recap

From memory

Before reading the summary, write down what you remember. Pulling it back from memory is what makes it last.

  1. Write the Qiskit program for a Bell pair, line by line, and say what each line does.

    Show the key points
    • qc = QuantumCircuit(2): two qubits, both starting in ∣0⟩\ket0
    • qc.h(0), then qc.cx(0, 1): HH on qubit 0, then a CNOT with control 0 (written first) and target 1
    • qc.measure_all(): measure every qubit; running it gives counts, 00 and 11 about half each
  2. How do you convert between Qiskit’s bitstrings and the kets in these lessons? Give an example.

    Show the key points
    • Qiskit puts qubit 0 on the right; kets here put it on the left
    • Reverse the string: Qiskit’s 001 is ∣100⟩\ket{100} here
    • The circuit diagram is the same in both, with qubit 0 on top
  3. What can a simulator show that a device can’t, and how much memory does a full simulation of nn qubits take?

    Show the key points
    • A simulator can show the amplitudes; a device returns only counts, which hide relative phases
    • 16×2n16 \times 2^n bytes: 16 GiB at 30 qubits, doubling with each qubit
    • Special circuits (Clifford-only, or with little entanglement) can be simulated much further

Key ideas

  1. A Qiskit program builds a circuit line by line: QuantumCircuit(n), one method per gate with the qubit numbers as arguments (control first), and measure_all() at the end. Running it samples the circuit and returns counts.

  2. Qiskit prints bitstrings with qubit 0 on the right; these lessons write ∣q0q1…⟩\ket{q_0q_1\ldots} with qubit 0 on the left. Reverse the string to convert.

  3. Loops and angles build families of circuits: for i in range(n - 1): qc.cx(i, i + 1) after qc.h(0) makes a GHZ state of any size, and qc.ry(theta, q) takes an angle written with pi (mind the half angle).

  4. A simulator knows every amplitude. A quantum computer gives only counts, which estimate 0/1 probabilities and can’t see relative phases without an extra gate.

  5. A full statevector needs 16×2n16 \times 2^n bytes: 16 GiB at 30 qubits, 16 TiB at 40, 16 PiB at 50. Special circuits can be simulated far beyond that; general ones can’t.

  6. In Python, pip install qiskit and a StatevectorSampler run the same program on your own computer; IBM offers free, limited access to real devices.

Go further

Free resources for when you want more than this lesson covers.

Start the interactive lesson