Quantum Teleportation in Quantum Computing, and Why It Isn’t Cloning

QUANTUM SERIES 2026
Moving a qubit you are forbidden to copy.

Teleportation is the most over-sold word in quantum computing. It conjures Star Trek transporters and faster-than-light messaging, and almost every popular account quietly implies you end up with a copy of the original. You do not. Quantum teleportation moves an unknown quantum state from one qubit to another while destroying the original, and that destruction is not an incidental detail. It is the mechanism that keeps the protocol on the right side of the no-cloning theorem.


1  ·  A quick word on no-cloning

This whole protocol is haunted by the no-cloning theorem: there is no operation that copies an arbitrary unknown quantum state. That proof and its consequences are covered in a recent post, The No-Cloning Theorem in Quantum Computing: Why You Can’t Copy a Qubit, and are not re-derived here.

The single fact needed going forward: you cannot deterministically duplicate an unknown qubit. The qualifiers matter, because teleportation lives in the gaps between them. The theorem forbids copying unknown states (a known state you can re-prepare at will), it forbids deterministic, perfect copies, and it is a statement about unitary operations — and measurement, which teleportation leans on at the decisive moment, is not unitary.

2  ·  Why teleportation is not cloning

Here is the distinction in one sentence: cloning would leave |ψ⟩ in two places; teleportation leaves it in exactly one.

Partway through the protocol, Alice’s message qubit is measured. Measurement collapses it into a classical basis state — a plain |0⟩ or |1⟩ carrying none of the original amplitudes. By the time Bob’s qubit holds |ψ⟩, Alice’s qubit demonstrably does not. The state was relocated, and the accounting is exact: one copy in, one copy out. No moment ever exists where two qubits both carry |ψ⟩, so there is nothing for the no-cloning theorem to object to.

This also kills the faster-than-light fantasy. The protocol forces Alice to send Bob two ordinary classical bits. Until they arrive, Bob’s qubit is information-free, as the algebra below shows.

3  ·  The complete circuit

Here is the whole protocol in a single circuit. Read it left to right; the amber dashed dividers mark the three stages. The message qubit q0 starts in the unknown state |ψ⟩, while q1 and q2 both start in |0⟩.

1. Bell pair2. Alice measures3. Bob corrects
q0:HM
q1:H+M
q2:+XZ

Stage 1 — Bell pair. Alice and Bob share an entangled pair: an H on q1 followed by a CNOT from q1 onto q2 prepares (|00⟩ + |11⟩)/√2 across the two halves.

Stage 2 — Alice measures. Alice folds her message into the pair (a CNOT from q0 onto q1, then an H on q0) and measures both of her qubits, collapsing them to two classical bits.

Stage 3 — Bob corrects. Depending on those two bits, Bob applies an X and/or a Z to q2 — the X controlled by Alice’s q1 bit, the Z by her q0 bit — and q2 emerges as |ψ⟩. The next section is the algebra that fixes exactly which correction each outcome needs.

4  ·  The protocol in bra-ket and tensor form

Now the algebra behind that circuit. Three qubits: q0 carries |ψ⟩ = α|0⟩ + β|1⟩ (Alice), q1 is Alice’s half of the Bell pair, and q2 is Bob’s half. They pre-share |Φ+⟩ = (|00⟩ + |11⟩)/√2 on q1 q2.

Step 1 — the starting state. Tensor the message against the Bell pair:

|ψ⟩ = α|0⟩ + β|1⟩            (the unknown message on q0)

|ψ⟩ ⊗ |Φ+⟩ = (α|0⟩ + β|1⟩) ⊗ (|00⟩ + |11⟩)/√2
           = (1/√2) [ α|000⟩ + α|011⟩ + β|100⟩ + β|111⟩ ]

Step 2 — Alice’s CNOT (control q0, target q1):

CNOT (control q0, target q1)  flips q1 wherever q0 = 1:

= (1/√2) [ α|000⟩ + α|011⟩ + β|110⟩ + β|101⟩ ]

Step 3 — Alice’s Hadamard on q0. Substitute |0⟩ → (|0⟩+|1⟩)/√2 and |1⟩ → (|0⟩−|1⟩)/√2, then collect by the value of (q0 q1):

H on q0, then collect by the pair Alice will measure (q0 q1):

= (1/2) [ |00⟩ (α|0⟩ + β|1⟩)    ← case A
        + |01⟩ (α|1⟩ + β|0⟩)    ← case B
        + |10⟩ (α|0⟩ − β|1⟩)    ← case C
        + |11⟩ (α|1⟩ − β|0⟩) ]  ← case D

Each bracketed q2 state is the original |ψ⟩ acted on by a known Pauli. Alice measures, gets one of four outcomes (each with probability 1/4), sends the two bits to Bob, and Bob undoes the Pauli. The Case column ties each row back to the matching line in Step 3:

Case
Alice measures (q0 q1)
Bob holds on q2
Relation to |ψ⟩
Bob applies
A
00
α|0⟩ + β|1⟩
I |ψ⟩
nothing
B
01
α|1⟩ + β|0⟩
X |ψ⟩
X
C
10
α|0⟩ − β|1⟩
Z |ψ⟩
Z
D
11
α|1⟩ − β|0⟩
ZX |ψ⟩
X then Z

Bob applies Zm0 Xm1 — an X if m1 = 1, then a Z if m0 = 1 — and every branch lands back on α|0⟩ + β|1⟩ = |ψ⟩.

5  ·  Qiskit — classical feed-forward

This version measures mid-circuit and uses real classical conditioning via if_test, the honest picture of the protocol. The verification trick: rather than read out Bob’s state, apply the inverse of the preparation to q2. If teleportation worked, that must collapse q2 to |0⟩ on every shot.

import numpy as np
from qiskit import QuantumCircuit, QuantumRegister, ClassicalRegister, transpile
from qiskit.circuit.library import StatePreparation
from qiskit.quantum_info import random_statevector
from qiskit_aer import AerSimulator

# Unknown state to teleport (StatePreparation is unitary -> invertible)
psi  = random_statevector(2)
prep = StatePreparation(psi)

q   = QuantumRegister(3, “q”)     # q0 message, q1 Alice, q2 Bob
mz  = ClassicalRegister(1, “mz”)  # q0 result -> drives Z
mx  = ClassicalRegister(1, “mx”)  # q1 result -> drives X
out = ClassicalRegister(1, “out”) # verification bit
qc  = QuantumCircuit(q, mz, mx, out)

qc.append(prep, [0]); qc.barrier()        # 1. load |ψ⟩ onto q0
qc.h(1); qc.cx(1, 2); qc.barrier()        # 2. Bell pair on (q1,q2)
qc.cx(0, 1); qc.h(0)                      # 3. Alice’s basis change
qc.measure(0, mz); qc.measure(1, mx); qc.barrier()

with qc.if_test((mx, 1)):                 # 4. Bob’s corrections
    qc.x(2)
with qc.if_test((mz, 1)):
    qc.z(2)
qc.barrier()

qc.append(prep.inverse(), [2])            # 5. un-prepare on Bob: must read 0
qc.measure(2, out)

counts = AerSimulator().run(transpile(qc, AerSimulator()), shots=4000).result().get_counts()
clean  = all(k.split()[0] == “0” for k in counts)   # leftmost bit = out
print(counts); print(“Teleportation verified:”, clean)
The out bit comes back 0 on 100% of shots regardless of the random (mx, mz) branch — exactly the claim that Bob reconstructs |ψ⟩ in every case.

6  ·  No faster-than-light, and the takeaway

Before Bob learns (m0, m1), his qubit is an equal mixture of the four branch states. Averaging the four projectors gives the Pauli twirl:

ρ_Bob = (1/4)( |ψ⟩⟨ψ| + X|ψ⟩⟨ψ|X
              + Z|ψ⟩⟨ψ|Z + XZ|ψ⟩⟨ψ|ZX )  =  I/2   for every |ψ⟩

for any |ψ⟩. Bob’s local state is identical no matter what Alice sent, so no information has reached him yet. The classical bits are not a formality — they are the only thing that carries the state across, and they travel no faster than light.

Takeaway. No-cloning forbids duplicating an unknown qubit (proof here). Teleportation never attempts a copy: it entangles the message with a shared Bell pair, measures the original out of existence, and ships two classical bits naming which of four Pauli corrections rebuilds the state on the other end. Exactly one copy before, exactly one after. No-cloning is not a bug the protocol works around — it is the reason the protocol has to look the way it does.

Quantum Series 2026  ·  Built with Qiskit 1.x

✦ This article was generated with the assistance of Claude by Anthropic

The No-Cloning Theorem in Quantum Computing: Why You Can’t Copy a Qubit

QUANTUM SERIES 2026
The no-cloning theorem: why an unknown quantum state cannot be copied, and what that buys us.

Copying is so ordinary in classical computing that we never think about it. Every assignment, every memory write, every Ctrl+C duplicates a bit string perfectly and at will. Quantum mechanics flatly refuses to do the same for an unknown state. There is no machine, no clever circuit, no sequence of gates that takes an arbitrary qubit and hands you back two identical copies of it. This is the no-cloning theorem, and far from being a limitation we tolerate, it is the structural reason quantum key distribution is secure, the reason entanglement cannot be used to signal faster than light, and the reason quantum error correction had to be reinvented from scratch.

The proof is short. It falls out of two properties we have already relied on throughout this series: linearity of quantum evolution, and unitarity. Below we prove it both ways, clear up the very common confusion about CNOT “copying” a qubit, walk through the consequences, and then watch a cloning attempt fail in Qiskit.


1  ·  What “cloning” would actually mean

A cloning machine would be a single fixed unitary U together with a standard blank register |e⟩, such that for every possible input state |ψ⟩ it produces:

U  ( |ψ⟩ ⊗ |e⟩ )  =  |ψ⟩ ⊗ |ψ⟩

Three pieces of that statement deserve unpacking, because the whole theorem turns on them.

What |e⟩ is, and what “blank” means. The register |e⟩ is simply the second slot, the one that will end up holding the copy. We call it “blank” by analogy with an empty sheet of paper or an uninitialised memory cell: before the operation it carries no information whatsoever about the input |ψ⟩. The conventional choice is |0⟩, or |0…0⟩ when the copy needs several qubits, but |e⟩ does not have to be the zero vector specifically. Any fixed pure state works equally well for the theorem. The property that actually matters is not its literal value but that it is independent of the unknown input. A register that already secretly equalled |ψ⟩ would not be blank, and you would not have copied anything, you would have been handed the answer.

What “fixed” means, for both U and |e⟩. Fixed means chosen in advance and identical on every run, never allowed to depend on which |ψ⟩ happens to come in. This is the condition that keeps the problem honest. If you were permitted to pick |e⟩ or U based on the input, you would first have to know what |ψ⟩ is, and at that point there is nothing left to clone: you could just prepare a second copy yourself. So the cloner gets one unitary and one starting register, and they must work for an arbitrary, unknown input. The claim of the theorem is that no such pair (U, |e⟩) exists.

Why cloning a known state is allowed, and how you do it. The theorem forbids copying an unknown arbitrary state. It says nothing about states you already understand, and there are two everyday ways such a state can be “known”:

You know… How you get two copies
The preparation recipe (the amplitudes, or the circuit that builds it) Just run the preparation twice on two fresh |0⟩ qubits. You are re-preparing from a known description, not copying an unknown state.
That the state is one of a known orthogonal set Measure in the basis that distinguishes the set. Orthogonal states are eigenstates of that measurement, so they survive it undisturbed. Read off the label, then re-prepare as many copies as you like.

As a concrete example of the first route, if you are told the state is |ψ⟩ = Ry(θ)|0⟩ for a known angle θ, you simply apply Ry(θ) to two separate qubits. No universal device is involved, and no rule is broken. The contradiction in the next two sections appears only when no such side information exists, that is, when the same machine must handle a continuum of unknown inputs at once.

The one-line distinction: you can always re-prepare a state you know how to build, and you can copy states that act like classical labels. What you cannot do is build one fixed machine that duplicates an arbitrary, unknown state handed to you blind.

2  ·  Proof I: linearity forbids it

Assume, for contradiction, that a universal cloner U exists. Pick two arbitrary states |ψ⟩ and |φ⟩. By assumption U clones both of them:

U |ψ⟩|e⟩  =  |ψ⟩|ψ⟩
U |φ⟩|e⟩  =  |φ⟩|φ⟩

Now feed the machine a superposition of the two inputs, |χ⟩ = (1/√2)(|ψ⟩ + |φ⟩). Quantum evolution is linear, so U acts term by term on the input:

U |χ⟩|e⟩  =  (1/√2) ( U|ψ⟩|e⟩  +  U|φ⟩|e⟩ )
         =  (1/√2) ( |ψ⟩|ψ⟩  +  |φ⟩|φ⟩ )

But if U is genuinely a cloner, then by definition it must also clone |χ⟩ itself, producing |χ⟩|χ⟩. Expanding that out:

|χ⟩|χ⟩  =  (1/2) ( |ψ⟩ + |φ⟩ )( |ψ⟩ + |φ⟩ )
      =  (1/2) ( |ψ⟩|ψ⟩ + |ψ⟩|φ⟩ + |φ⟩|ψ⟩ + |φ⟩|φ⟩ )

The two results disagree. Linearity gave us only the “diagonal” terms |ψ⟩|ψ⟩ and |φ⟩|φ⟩, whereas true cloning of |χ⟩ demands the cross terms |ψ⟩|φ⟩ and |φ⟩|ψ⟩ as well. They can only match if the cross terms vanish, which happens precisely when |ψ⟩ and |φ⟩ are identical or orthogonal. For general, non-orthogonal states the equality is impossible. The cloner cannot exist.

The contradiction is the same one that powers most quantum no-go results: a device defined by its action on a basis is forced, by linearity, into a behaviour on superpositions that contradicts the original specification.

3  ·  Proof II: unitarity forbids it

The linearity argument shows cloning fails for superpositions. A second proof, often considered the cleaner one, uses the fact that unitary operations preserve inner products. Suppose again that U clones two states:

U |ψ⟩|e⟩  =  |ψ⟩|ψ⟩
U |φ⟩|e⟩  =  |φ⟩|φ⟩

The inner product is taken over the full two-register states that U acts on, not over |ψ⟩ and |φ⟩ on their own. Label the two inputs and their images under U:

Input A   = |ψ⟩|e⟩        Output UA  = |ψ⟩|ψ⟩
Input B   = |φ⟩|e⟩        Output UB  = |φ⟩|φ⟩

If U is unitary, then   ⟨A|B⟩  =  ⟨UA|UB⟩

That identity, ⟨A|B⟩ = ⟨UA|UB⟩, is the definition of a unitary: it preserves inner products. U never acts on the inner product itself, which is only a number; it acts on the states, and unitarity says doing so cannot change their overlap. Now evaluate both sides, using the tensor-product factorisation ⟨a|⟨b| · |c⟩|d⟩ = ⟨a|c⟩ ⟨b|d⟩ and ⟨e|e⟩ = 1:

⟨A|B⟩   = ⟨ψ|⟨e| · |φ⟩|e⟩  =  ⟨ψ|φ⟩ ⟨e|e⟩  =  ⟨ψ|φ⟩
⟨UA|UB⟩ = ⟨ψ|⟨ψ| · |φ⟩|φ⟩  =  ⟨ψ|φ⟩ ⟨ψ|φ⟩  =  ⟨ψ|φ⟩²

so   ⟨ψ|φ⟩  =  ⟨ψ|φ⟩²

Write x = ⟨ψ|φ⟩. The condition x = x² rearranges to x(x − 1) = 0, whose only solutions are x = 0 or x = 1. In other words, cloning is consistent only when the two states are orthogonal (x = 0) or identical (x = 1). Any pair of distinct, non-orthogonal states, the generic case, breaks the equality. No universal cloner can exist.

⟨ψ|φ⟩ Relationship Cloneable?
0 Orthogonal (a known basis set) Yes, this is just classical copying
1 Identical (already known) Yes, trivially
anything else Distinct, non-orthogonal No

Both proofs converge on the same boundary. Orthogonal states carry distinguishable classical labels and can be copied; overlapping quantum states cannot.

4  ·  “But doesn’t CNOT copy a qubit?”

This is the single most common point of confusion, and it is worth resolving carefully. A CNOT with the input qubit as control and a fresh |0⟩ as target looks exactly like a copy operation. On computational basis states it behaves like one:

CNOT |0⟩|0⟩  =  |0⟩|0⟩
CNOT |1⟩|0⟩  =  |1⟩|1⟩

So far it really is copying: the second qubit ends up matching the first. The trouble appears the moment the control is a superposition. Take |ψ⟩ = a|0⟩ + b|1⟩ as control and |0⟩ as target:

CNOT ( a|0⟩ + b|1⟩ )|0⟩  =  a|00⟩ + b|11⟩

Compare that with what a true clone would have produced, namely |ψ⟩|ψ⟩:

|ψ⟩|ψ⟩  =  a²|00⟩ + ab|01⟩ + ab|10⟩ + b²|11⟩

These are different states. The CNOT output a|00⟩ + b|11⟩ is an entangled pair, not two independent copies. If you discard the original and look at the “copy” on its own, you do not find |ψ⟩; you find a mixed state that has lost the phase relationship between a and b entirely. CNOT copies the value in the computational basis but destroys the superposition structure that made the state quantum in the first place. That is exactly the gap between copying classical information, which is always allowed, and cloning a quantum state, which is not.

Rule of thumb: CNOT copies basis labels, not quantum states. The instant the input is in superposition, the “copy” is entanglement, not duplication.

5  ·  Why this single theorem matters so much

No-cloning is not a footnote. Three of the most important results in quantum information rest directly on it.

Quantum key distribution. In BB84, Alice sends qubits encoded in randomly chosen bases. An eavesdropper, Eve, would love to intercept each qubit, keep a copy, and forward the original untouched so she can measure her copies later once the bases are announced. No-cloning makes that impossible. Eve cannot duplicate an unknown qubit, so she is forced to measure in transit, and measuring in the wrong basis disturbs the state and injects a detectable error rate. The security of the protocol is the no-cloning theorem wearing a different hat.

No faster-than-light signalling. Entanglement correlates distant measurement outcomes, which has always tempted people into superluminal-communication schemes. Many of those schemes secretly assume Bob can clone his half of an entangled pair, make many copies, and read off the statistics to learn which basis Alice measured in. No-cloning closes that loophole and is one of the reasons quantum mechanics and relativity coexist without paradox.

Quantum error correction. Classical error correction leans on the simplest trick imaginable: copy the bit several times and take a majority vote. That is illegal in the quantum setting, because you cannot copy an unknown logical state. Quantum codes had to be built on a different principle, spreading logical information across many physical qubits using entanglement and measuring error syndromes without ever reading or duplicating the encoded state. The whole architecture of fault tolerance is shaped by the fact that the obvious classical fix is off the table.

A useful way to hold it in your head: no-cloning is what stops quantum information from behaving like classical information. Almost everything that makes quantum protocols both powerful and secure traces back to that one restriction.

6  ·  Watching a clone fail in Qiskit

The abstract proof is convincing, but it is satisfying to watch the failure happen numerically. We attempt the naive CNOT “clone” of the state |+⟩ = H|0⟩, then measure how badly it falls short by two yardsticks: fidelity against the intended |+⟩|+⟩, and the purity of the copy qubit on its own.

Three terms in plain language:

Fidelity is a similarity score between two quantum states, from 0 to 1. Think of it as a match percentage: 1.0 means identical, 0 means completely unrelated.

Reduced state is the honest description of one qubit when you ignore its partner. Picture two coins glued so they always land the same way: cover one and look at just the other, and that single coin looks like a plain 50/50 flip. The “match” information lived in the pair, not in either coin alone. Discarding the partner mathematically is called tracing it out.

Purity tells you whether a state is sharp and definite or a blurry random mixture. Purity 1 is a clean, definite state. For a single qubit the lowest value is 0.5, called maximally mixed, which is total randomness, the quantum version of a fair coin holding no information.

from qiskit import QuantumCircuit
from qiskit.quantum_info import Statevector, partial_trace, state_fidelity

qc = QuantumCircuit(2)
qc.h(0)         # prepare |+> on qubit 0 (the “original”)
qc.cx(0, 1)    # naive “cloning” attempt via CNOT

state = Statevector(qc)
print(state)   # (|00> + |11>)/sqrt(2), a Bell state

target = Statevector.from_label(‘++’)   # what we wanted: |+>|+>
print(state_fidelity(state, target))   # 0.5

rho_copy = partial_trace(state, [0])   # trace out the original
print(rho_copy.data)   # I/2, maximally mixed
print(rho_copy.purity().real)   # 0.5

Running it gives:

Output state:  (√2/2)|00⟩ + (√2/2)|11⟩
Fidelity to |+⟩|+⟩:  0.5
Reduced state of copy:  [[0.5, 0], [0, 0.5]]
Purity of copy:  0.5

Every number tells the same story. The output is a maximally entangled Bell state, not the product |+⟩|+⟩ we were hoping for, and the fidelity to the intended clone is only 0.5. Trace out the original and the supposed “copy” is the maximally mixed state I/2, with purity 0.5 rather than 1. The copy retains no memory of the |+⟩ superposition at all; it is as good as a fair coin. The CNOT did precisely what the theorem says it must: it produced correlation, not duplication.

Try changing qc.h(0) to any other single-qubit rotation, say qc.ry(0.7, 0). The fidelity stays stubbornly below 1 for every non-basis input, which is the no-cloning theorem reproduced one statevector at a time.

Quantum Series 2026  ·  Built with Qiskit 1.x

✦ This article was generated with the assistance of Claude by Anthropic

About the author

Malcolm Low is an Associate Professor at the Singapore Institute of Technology, writing on quantum computing, programming, and applied computing from Singapore.

Website: malcolmlow.com  ·  Singapore

Deutsch Algorithm Revisited: Quantum vs Classical Implementation in Qiskit

QUANTUM SERIES 2026
Quantum vs classical implementation of Deutsch’s Algorithm in Qiskit: same answer, half the queries.

The previous post covered the theory: four Boolean functions, the reversible oracle Uf, the phase-kickback derivation, and the single-query measurement result. This post puts it into running code. We implement the classical two-query approach and the quantum one-query approach side by side in Qiskit so the advantage is visible, not just promised.


1  ·  The Challenge

Given a black-box function f: {0,1} → {0,1}, determine whether it is constant (f(0) = f(1)) or balanced (f(0) ≠ f(1)).

Approach Oracle queries required Strategy
Classical 2 Evaluate f(0), then f(1), compare
Quantum (Deutsch) 1 Query in superposition, read phase via interference
The quantum advantage: instead of probing the function at individual inputs, the algorithm queries it at a superposition of both inputs simultaneously, then uses interference to extract a global property (constant vs balanced) with a single measurement.
2  ·  Oracle Functions

First we build the four oracle circuits. Each implements one of the four single-bit Boolean functions as a reversible quantum gate. The constant oracles ignore x; the balanced oracles use x as a control.

from qiskit import QuantumCircuit, QuantumRegister, ClassicalRegister
from qiskit_aer import AerSimulator

def create_constant_oracle(constant_value):
    “””Creates a constant oracle (returns 0 or 1 for all inputs)”””
    oracle = QuantumCircuit(2, name=f”Constant_{constant_value}”)
    if constant_value == 1:
        oracle.x(1)  # Flip the output qubit
    return oracle

def create_balanced_oracle(balance_type):
    “””Creates a balanced oracle”””
    oracle = QuantumCircuit(2, name=f”Balanced_{balance_type}”)
    if balance_type == ‘identity’:
        # f(x) = x
        oracle.cx(0, 1)
    elif balance_type == ‘negation’:
        # f(x) = NOT x
        oracle.x(0)
        oracle.cx(0, 1)
        oracle.x(0)
    return oracle
3  ·  Classical Approach: Two Queries Required

The classical algorithm calls the oracle twice: once with input 0 to learn f(0), and once with input 1 to learn f(1). Each query is a separate circuit run.

def classical_deutsch_query1(oracle):
    “””First query: Evaluate f(0)”””
    qr = QuantumRegister(2, ‘q’)
    cr = ClassicalRegister(1, ‘c’)
    qc = QuantumCircuit(qr, cr)
    # Input: x = 0 (already initialised to |0>)
    qc.barrier()
    qc.compose(oracle, inplace=True)
    qc.barrier()
    qc.measure(1, 0)  # Measure output to get f(0)
    return qc

def classical_deutsch_query2(oracle):
    “””Second query: Evaluate f(1)”””
    qr = QuantumRegister(2, ‘q’)
    cr = ClassicalRegister(1, ‘c’)
    qc = QuantumCircuit(qr, cr)
    qc.x(0)  # Input: x = 1
    qc.barrier()
    qc.compose(oracle, inplace=True)
    qc.barrier()
    qc.measure(1, 0)  # Measure output to get f(1)
    return qc
Classical bottleneck: two separate measurements, two separate circuit executions. The classical algorithm measures the output qubit q[1] in both cases to read the function values directly.
4  ·  Quantum Approach: One Query Suffices

The quantum circuit initialises q[1] = |1⟩, applies Hadamard gates to both wires, queries the oracle exactly once, then applies a final Hadamard to q[0] before measuring it. The oracle is never called again.

def deutsch_algorithm(oracle):
    “””Implements Deutsch’s algorithm — requires only ONE query”””
    qr = QuantumRegister(2, ‘q’)
    cr = ClassicalRegister(1, ‘c’)
    qc = QuantumCircuit(qr, cr)

    # Step 1: Initialise q[1] to |1>
    qc.x(1)
    qc.barrier()

    # Step 2: Hadamard on both wires (superposition)
    qc.h(0)
    qc.h(1)
    qc.barrier()

    # Step 3: Single oracle query
    qc.compose(oracle, inplace=True)
    qc.barrier()

    # Step 4: Final Hadamard on q[0]
    qc.h(0)
    qc.barrier()

    # Step 5: Measure q[0] — the INPUT qubit, not the output
    qc.measure(0, 0)
    return qc

The quantum circuit measures q[0], the input qubit. The classical circuits measure q[1], the output qubit. That structural difference is the entire quantum advantage: the quantum algorithm reads a global property of the function via interference, not an individual function value.

5  ·  Running the Comparison

Test all four oracles with both approaches and compare query counts.

oracles = [
    (“Constant 0”,           create_constant_oracle(0)),
    (“Constant 1”,           create_constant_oracle(1)),
    (“Balanced (Identity)”, create_balanced_oracle(‘identity’)),
    (“Balanced (Negation)”, create_balanced_oracle(‘negation’))
]
simulator = AerSimulator()

for name, oracle in oracles:
    # Classical: 2 queries
    f_0 = int(list(simulator.run(classical_deutsch_query1(oracle), shots=1).result().get_counts().keys())[0])
    f_1 = int(list(simulator.run(classical_deutsch_query2(oracle), shots=1).result().get_counts().keys())[0])
    classical_result = “CONSTANT” if f_0 == f_1 else “BALANCED”

    # Quantum: 1 query
    counts = simulator.run(deutsch_algorithm(oracle), shots=1000).result().get_counts()
    quantum_result = “CONSTANT” if ‘0’ in counts else “BALANCED”

    print(f”{name}: Classical={classical_result}, Quantum={quantum_result}”)

Sample output:

Constant 0:          Classical=CONSTANT, Quantum=CONSTANT
Constant 1:          Classical=CONSTANT, Quantum=CONSTANT
Balanced (Identity): Classical=BALANCED, Quantum=BALANCED
Balanced (Negation): Classical=BALANCED, Quantum=BALANCED
Both methods always agree. The quantum result is deterministic: the simulator returns 100% |0⟩ for constant oracles and 100% |1⟩ for balanced ones, with zero noise on shots=1000.
6  ·  Circuit Overview

Classical Query 1 — Evaluate f(0)
q[0] stays in |0⟩, both wires pass through Uf, and q[1] is measured to read f(0).

q[0]: |0⟩ (not measured)
Uf
q[1]: |0⟩ M f(0)

Classical Query 2 — Evaluate f(1)
An X gate flips q[0] to |1⟩, both wires pass through Uf, and q[1] is measured to read f(1).

q[0]: |0⟩ X (not measured)
Uf
q[1]: |0⟩ M f(1)

Quantum Deutsch — Single Query
H gates create superposition on both wires, one oracle query encodes f(0) ⊕ f(1) as a phase, the final H on q[0] converts phase to amplitude, and measuring q[0] gives the answer directly.

q[0]: |0⟩ H H M 0=const, 1=bal
Uf
q[1]: |1⟩ H
The structural difference: the classical circuits measure the output qubit q[1] to read individual function values. The quantum circuit measures the input qubit q[0] after interference to read a global property of the function. That is what lets a single query reveal whether the function is constant or balanced.
7  ·  Measurement Interpretation and Conclusion

The measurement result on q[0] maps directly to the function type:

Measure q[0] Function type Interference mechanism
0 Constant f(0) ⊕ f(1) = 0 → constructive on |0⟩
1 Balanced f(0) ⊕ f(1) = 1 → destructive on |0⟩, constructive on |1⟩

The quantum speedup is 2x here (one query instead of two). Modest for a two-input function, but the same technique scales: Deutsch-Jozsa extends this to n-bit functions, cutting 2n−1+1 classical queries down to one. Simon’s algorithm extends it further. Shor’s algorithm for factoring, the most consequential quantum algorithm known, relies on the same architectural idea: query in superposition, encode information as phase, extract via interference and measurement.

To run the code: pip install qiskit qiskit-aer. The full comparison script outputs all four oracle types side by side. Try modifying the oracle functions to explore how each gate sequence implements f.

Quantum Series 2026  ·  Built with Qiskit 1.x

✦ This article was generated with the assistance of Claude by Anthropic

What to do with 100+ qubits?

https://youtube.com/live/L7Kk_lR1Y2M?si=uH9l3Y8Hksr9Djk4