Why You Must Clean Up “Junk Bits” with Uncomputation
1. The “Observer” Effect
In quantum computing, anything that “knows” what a qubit is doing acts as a Witness. Leftover data (Junk Bits) on an ancilla qubit act as witnesses, destroying the interference your algorithm needs to work.
Mastering Reversibility, Ancilla Bits, and Unitary Logic
1. The Necessity of Reversibility
In classical logic, gates like AND are irreversible. In quantum computing, all operations must be Unitary ($U^{\dagger}U = I$), meaning they are perfectly reversible. Information is never lost; it is simply transformed.
AND
Out: ?
Information Loss: You cannot reconstruct inputs from the output.
2. Ancilla Bits & Uncomputation
Because we cannot erase information, we use Ancilla bits as temporary “scratch space.” However, if these qubits are left in an arbitrary state, they remain entangled with the computation. Uncomputation (running gates in reverse) resets them to |0>, “cleaning” the quantum workspace.
The Toffoli Gate (CCX)
The Toffoli gate is reversible because its mapping is bijective. No two inputs result in the same output.
Input (A, B, C)
Output (A, B, C ⊕ AB)
Status
0, 0, 0
0, 0, 0
Unique
1, 1, 0
1, 1, 1
Flipped (AND)
1, 1, 1
1, 1, 0
Flipped Back
The Fredkin Gate (CSWAP)
✕
✕
In: C
In: T1
In: T2
3. Mathematics: Unitary vs. Hermitian
Proof: Is Pauli-Y Unitary?
Y =
0
–i
i
0
Y† =
0
–i
i
0
Pauli-Y is Unitary (Y†Y = I). Because Y = Y†, it is also Hermitian.
Unitary but NOT Hermitian: The S Gate
S =
1
0
0
i
≠
S† =
1
0
0
–i
Since S ≠ S†, you must apply the S-Dagger gate to reverse an S rotation.
4. Qiskit Verification
from qiskit import QuantumCircuit, transpile
from qiskit_aer import AerSimulator
qc = QuantumCircuit(3)
qc.x([0, 1]) # Controls to |1># Toffoli is Hermitian (U = U†), so applying it twice cleans the ancilla
qc.ccx(0, 1, 2) # Calculation step
qc.ccx(0, 1, 2) # Uncomputation step
qc.measure_all()
counts = AerSimulator().run(transpile(qc, AerSimulator())).result().get_counts()
print(f"Resulting state: {counts}") # Expect {'011': 1024}
Deutsch Algorithm Revisited: Quantum vs Classical Implementation in Qiskit
A practical comparison showing the quantum advantage with working code
Introduction
In the previous post on the Deutsch algorithm, we explored the theoretical foundations of this groundbreaking quantum algorithm. Today, we’re taking it further by implementing both the quantum and classical approaches in Qiskit, allowing us to see the quantum advantage in action.
This hands-on implementation demonstrates why the Deutsch algorithm is considered the first example of quantum computational superiority—solving a problem with fewer oracle queries than any classical algorithm can achieve.
The Challenge
Given a black-box function f: {0,1} → {0,1}, determine whether it is:
Below are visual representations of the three circuit implementations. The classical approach requires two separate queries, while the quantum approach accomplishes the same task with a single query.
Classical Query 1: Evaluating f(0)
q[0]:
q[1]:
|0⟩
|0⟩
Oracle(Constant_0)
f(0)
Classical Query 1: Input qubit q[0] remains in state |0⟩ → Oracle processes the input → Output qubit q[1] is measured to obtain f(0)
Classical Query 2: Evaluating f(1)
q[0]:
q[1]:
|0⟩
|0⟩
X
|1⟩
Oracle(Constant_0)
f(1)
Classical Query 2: X gate flips q[0] from |0⟩ to |1⟩ → Oracle processes the input → Output qubit q[1] is measured to obtain f(1)
Quantum Deutsch Algorithm (Single Query)
q[0]:
q[1]:
|0⟩
|0⟩
X
H
H
Oracle(Constant_0)
H
0 or 1
Quantum Deutsch: Initialize |01⟩ → Hadamard gates create superposition → Oracle query (single query!) → Final Hadamard on q[0] → Measure q[0] to determine function type
💡 Understanding the Circuit Elements
🔵 Oracle Box: Represents the black-box function we’re querying
🟠 H Gates: Hadamard gates create quantum superposition
🔴 X Gates: Flip qubit states (NOT gate)
📊 Measurement: Extracts classical information from qubits
Notice that the classical circuits measure the output qubit (q[1]) to get the function values f(0) and f(1), while the quantum circuit measures the input qubit (q[0]) after interference. This fundamental difference allows the quantum algorithm to extract global properties of the function with a single query!
Sample Output
======================================================================
Testing: Constant 0 Oracle
======================================================================
[CLASSICAL APPROACH - Requires 2 queries]
Query 1: f(0) = 0
Query 2: f(1) = 0
Result: Function is CONSTANT
Total queries needed: 2
[QUANTUM APPROACH - Requires only 1 query]
Measurement results: {'0': 1000}
Result: Function is CONSTANT
Total queries needed: 1
✓ Both methods agree: True
======================================================================
Testing: Balanced (Identity) Oracle
======================================================================
[CLASSICAL APPROACH - Requires 2 queries]
Query 1: f(0) = 0
Query 2: f(1) = 1
Result: Function is BALANCED
Total queries needed: 2
[QUANTUM APPROACH - Requires only 1 query]
Measurement results: {'1': 1000}
Result: Function is BALANCED
Total queries needed: 1
✓ Both methods agree: True
Understanding the Quantum Advantage
Classical Approach
Evaluate f(0) explicitly
Evaluate f(1) explicitly
Compare the two results
2 queries required
Must check both inputs individually
Quantum Approach
Query with superposition of both inputs
Use interference to extract global property
Measure to get answer
1 query required
Exploits quantum parallelism
🎯 The Key Insight
The quantum algorithm queries the oracle with a superposition of both inputs simultaneously (|0⟩ + |1⟩), then uses quantum interference to extract global properties of the function without ever evaluating it on individual inputs. The measurement result directly tells us whether the function is constant or balanced.
Measurement Interpretation
Measurement Result
Function Type
Explanation
|0⟩
Constant
Constructive interference – f(0) ⊕ f(1) = 0
|1⟩
Balanced
Destructive interference – f(0) ⊕ f(1) = 1
Running the Code
To run this code yourself, you’ll need to install Qiskit:
pip install qiskit qiskit-aer
The complete code is available as a Python script that you can run directly. It will output the comparison for all four oracle types and display the results.
Conclusion
This implementation demonstrates the Deutsch algorithm’s quantum advantage in concrete terms:
Quantum speedup: 2x reduction in oracle queries (from 2 to 1)
First proof of concept: First algorithm to show quantum advantage over classical
While the speedup may seem modest for this toy problem, the techniques demonstrated here—querying a function with superposition and extracting global properties through interference—scale to more complex algorithms like Deutsch-Jozsa, Simon’s algorithm, and ultimately Shor’s algorithm for factoring.
🚀 Next Steps:
Experiment with the code and modify the oracles
Try visualizing the quantum states at each step
Explore the Deutsch-Jozsa algorithm (generalization to n-bit functions)
Study the mathematical foundations of quantum interference
Deutsch’s Algorithm determines if a function f(x) is Constant or Balanced using only a single query. First, we examine how these functions are physically built.
The 4 Possible Functions
In these examples, we set the bottom input to 0 so the output is exactly f(x).
1. Constant ZeroFunction: f(x) = 0
x
0
Identity (No Gates)
2. Constant OneFunction: f(x) = 1
X
3. Balanced IDFunction: f(x) = x
+
4. Balanced NOTFunction: f(x) = ¬x
+
X
The General Oracle (Uf)
x
y
Uf
x
y ⊕ f(x)
The Complete Circuit
To detect the function type, we initialize the bottom wire to |1⟩ and use Hadamard gates to create superposition.
In standard classical logic, a Control Bit dictates what happens to a target. However, in quantum mechanics, the relationship is symmetric. When the target qubit is in an eigenstate of the operator, the phase is “kicked back” to the control qubit.
|+⟩
|−⟩
|−⟩
|−⟩
CNOT CIRCUIT
Notice above: The Target qubit remains unchanged (|−⟩), but the Control qubit flips from |+⟩ to |−⟩.
Target flips (0↔1) only if Control is 1:
|ψ1⟩ = ½ [ |00⟩ − |01⟩ + |11⟩ − |10⟩ ]
STEP 4: FACTOR & REARRANGE
Group terms by the control qubit:
|ψ1⟩ = ½ [ |0⟩(|0⟩ − |1⟩) − |1⟩(|0⟩ − |1⟩) ]
∴ |ψ1⟩ = |−⟩ ⊗ |−⟩
Why is this important?
The math shows that while we applied the gate to the target, the relative phase of the control qubit changed from positive to negative. This mechanism is the foundation of quantum algorithms like Shor’s and Grover’s.