Deutsch's Algorithm
Historically the first algorithm to demonstrate a quantum speedup: with a single oracle query, decide whether a one-bit function is constant or balanced — where a classical deterministic algorithm must query twice. Deutsch's algorithm needs a single oracle query and is always correct.
The problem it solves
Consider a Boolean function f that takes one bit in and returns one bit out. There
are only four such functions, and they fall into two classes:
| Class | Functions | Signature |
|---|---|---|
| Constant | f(x)=0 or f(x)=1 | both inputs give the same output |
| Balanced | f(x)=x or f(x)=1⊕x | the two inputs give different outputs |
We do not care which specific function f is — only which class it belongs to.
Classically, knowing f(0) alone (or f(1) alone) settles nothing: you must learn both values and
compare them. A classical deterministic algorithm therefore needs 2 queries;
Deutsch's algorithm needs just 1 oracle query, and is always correct.
Intuition — asking for a global property in one question
The key realisation is that "constant vs. balanced" is a global property: it depends only on the parity (XOR) of the two values, f(0)⊕f(1). A constant function has parity 0; a balanced function has parity 1. A classical circuit can only probe the function at one point per query, so it can never read out this global parity directly.
A quantum circuit can feed both inputs through the oracle in superposition at once, then use interference to collect "the difference between the two points" into a single measurement. Instead of evaluating the function point by point, we ask directly: "are these two points the same or not?"
Why it works — phase kickback
The trick is to prepare the auxiliary qubit in the state |−⟩ = (|0⟩ − |1⟩)/√2 (the code
does this with an x followed by an h). When the reversible oracle
|x⟩|y⟩ → |x⟩|y⊕f(x)⟩ acts on |−⟩, something elegant happens: the XOR no longer
flips the auxiliary qubit, but instead kicks back a phase of (−1)f(x)
onto the data qubit:
|x⟩|−⟩ → (−1)f(x) |x⟩|−⟩
So the data qubit goes from (|0⟩+|1⟩)/√2 to
((−1)f(0)|0⟩ + (−1)f(1)|1⟩)/√2. The relative phase between the two
components encodes exactly the parity f(0)⊕f(1) we are after:
- If f(0)=f(1) (constant), the two phases agree and the state is proportional to
|0⟩+|1⟩ = |+⟩. - If f(0)≠f(1) (balanced), the two phases differ and the state is proportional to
|0⟩−|1⟩ = |−⟩.
A final Hadamard on the data qubit maps |+⟩ back to |0⟩ and |−⟩
back to |1⟩. The measurement is therefore deterministic: read 0 for
constant, read 1 for balanced.
The mechanism
| Step | Role |
|---|---|
| Prepare |−⟩ auxiliary | Converts the oracle's output XOR into a kick-backable phase rather than an actual flip of the auxiliary qubit. |
| Superpose the data qubit | Lets the oracle act on |0⟩ and |1⟩ "at once", folding both values of f into one state. |
| Phase kickback | Writes (−1)f(x) into the relative phase of the data qubit's components. |
| Closing Hadamard interference | Translates the phase difference into a readable 0/1, interfering constant and balanced onto different measurement basis states. |
What it shows — and what it doesn't
- A toy, but a genuine one. Deutsch's algorithm has no practical use of its own, but it is the first clean proof that quantum can solve a problem with fewer queries — the advantage is in query complexity, not runtime or memory.
- The advantage is deterministic. There is no probabilistic trade-off here: a classical deterministic algorithm needs 2 queries, quantum needs 1, and it is right every time.
- It generalises. Extended to an n-bit function (promised constant or balanced) it becomes the Deutsch–Jozsa algorithm: classically up to 2n−1+1 queries in the worst case, quantum still just 1 — from exponential to constant. (This compares against deterministic/exact classical algorithms; a bounded-error randomized classical algorithm also needs only a constant number of queries.)
- It breaks nothing. The real legacy is phase kickback itself — Bernstein–Vazirani, Simon, and even Grover all reuse it.
The algorithm, step by step
- Prepare the auxiliary qubit in
|−⟩(flip withx, thenh). - Apply
hto the data qubit to make the|+⟩superposition. - Call the oracle; via phase kickback, the parity f(0)⊕f(1) is written into the data qubit's relative phase.
- Apply
hagain to the data qubit, turning the phase difference into a computational 0 or 1. - Measure: 0 ⇒ constant, 1 ⇒ balanced.
Seeing it in code
Read it line by line against the theory above: x(q[1]) followed by h(q[1])
prepares the auxiliary qubit in |−⟩; h(q[0]) superposes the data qubit; when
oracle_balanced=True is passed, the x.ctrl(q[0], q[1]) CNOT is the balanced
oracle f(x)=x, and it is what triggers phase kickback; the closing h(q[0]) completes the
interference so that mz(q[0]) reports the function's class deterministically.
The example only demonstrates the constant oracle f(x)=0 and the balanced oracle f(x)=x. To
realize f(x)=1, add one x(q[1]) on the auxiliary qubit in the oracle; to realize
f(x)=1⊕x, add an auxiliary flip on top of the CNOT. Whichever constant or balanced oracle you pick,
the measurement still stabilizes to 0 (constant) or 1 (balanced) respectively.
import qalgora
@qalgora.kernel
def deutsch(oracle_balanced: bool):
q = qalgora.qvector(2)
x(q[1])
h(q[0]); h(q[1])
if oracle_balanced: # f(x) = x -> CNOT oracle
x.ctrl(q[0], q[1])
h(q[0])
mz(q[0]) # 0 => constant, 1 => balanced
print(qalgora.sample(deutsch, True)) # balanced -> always 1
print(qalgora.sample(deutsch, False)) # constant -> always 0
x on q[1] after the
CNOT) and confirm the result still locks to 1. Then try the two constant oracles — you will see the
qubit's counts always collapse to a single deterministic peak, a direct demonstration of
interference being exact.
References
- D. Deutsch, "Quantum theory, the Church-Turing principle and the universal quantum computer," Proc. R. Soc. Lond. A 400, 97-117 (1985). doi:10.1098/rspa.1985.0070
Deutsch 算法
历史上第一个展示量子加速的算法:仅凭一次谕示(oracle)查询,就能判断一个一比特函数是常值还是平衡——而经典确定性算法必须查询两次。
它解决的问题
设想一个布尔函数 f,输入一个比特、输出一个比特。它只可能是以下四种之一,并被划入两类:
| 类型 | 函数 | 特征 |
|---|---|---|
| 常值 | f(x)=0 或 f(x)=1 | 两个输入给出相同输出 |
| 平衡 | f(x)=x 或 f(x)=1⊕x | 两个输入给出不同输出 |
我们不关心 f 具体是哪一个,只想知道它属于哪一类。经典上,单看 f(0) 或 f(1) 中任意一个都无法定论——你必须把两个值都问出来,再比较。也就是说,经典确定性算法需要 2 次查询;Deutsch 算法只需 1 次 oracle 查询,并且确定正确。
直觉 一次提问问出全局性质
关键的认识是:常值与平衡的区别其实是一个全局属性——它取决于 f(0) 与 f(1) 的奇偶(异或),即 f(0)⊕f(1)。常值函数该奇偶为 0,平衡函数该奇偶为 1。经典电路一次只能探测函数在某一个点的值,因此无法直接读出这个全局奇偶。
量子电路则可以把两个输入做成叠加同时送入谕示,再用干涉把"两点之差"这一全局信息汇聚到一次测量里。换句话说,我们不去逐点求值,而是直接询问"这两点是否相同"。
为何成立 相位回踢
诀窍在于把辅助比特预备成 |−⟩ = (|0⟩ − |1⟩)/√2 这一状态(代码中先 x 再 h 得到)。当谕示以可逆形式 |x⟩|y⟩ → |x⟩|y⊕f(x)⟩ 作用在 |−⟩ 上时,会发生一件漂亮的事:异或不再改变辅助比特,而是把一个 (−1)f(x) 的相位回踢到数据比特上:
|x⟩|−⟩ → (−1)f(x) |x⟩|−⟩
于是数据比特从 (|0⟩+|1⟩)/√2 变成 ((−1)f(0)|0⟩ + (−1)f(1)|1⟩)/√2。两个分量的相对相位恰好编码了我们想要的奇偶 f(0)⊕f(1):
- 若 f(0)=f(1)(常值),两相位同号,状态正比于
|0⟩+|1⟩ = |+⟩。 - 若 f(0)≠f(1)(平衡),两相位反号,状态正比于
|0⟩−|1⟩ = |−⟩。
最后再对数据比特施加一个 Hadamard:它把 |+⟩ 映回 |0⟩、把 |−⟩ 映回 |1⟩。因此测量结果是确定的——读到 0 就是常值,读到 1 就是平衡。
核心机制
| 步骤 | 作用 |
|---|---|
| 制备 |−⟩ 辅助比特 | 把谕示的输出"异或"转化为一个可回踢的相位,而非真正翻转辅助比特。 |
| 数据比特叠加 | 令谕示在 |0⟩ 与 |1⟩ 上"同时"作用,把 f 的两个取值并入同一状态。 |
| 相位回踢 | 把 (−1)f(x) 写进数据比特各分量的相对相位。 |
| 末端 Hadamard 干涉 | 将相位差转译为可读的 0/1,让常值与平衡彼此干涉到不同的测量基矢上。 |
它能说明什么 又不能说明什么
- 它是一个玩具,但意义真实。Deutsch 算法本身没有实用价值,但它是第一个干净地证明"量子能用更少查询解决问题"的范例——优势体现在查询复杂度,而非运行时间或内存。
- 优势是确定性的。这里没有概率取舍:经典确定性算法需要 2 次、量子只需 1 次,每次都对。
- 它会推广。把它扩展到 n 比特函数(保证常值或平衡),就得到 Deutsch–Jozsa 算法:经典最坏需 2n−1+1 次查询,量子仍只需 1 次——从指数到常数。(此处对照的是确定性/精确经典算法;若允许有界误差的随机经典算法,则经典亦仅需常数次查询。)
- 它不"破解"任何东西。相位回踢这套手法才是真正的遗产——Bernstein–Vazirani、Simon、乃至 Grover 都在复用它。
算法逐步拆解
- 把辅助比特预备为
|−⟩(先x翻转、再h)。 - 对数据比特施加
h,制备|+⟩叠加。 - 调用谕示;通过相位回踢,奇偶 f(0)⊕f(1) 被写入数据比特的相对相位。
- 对数据比特再施加
h,把相位差转为计算基上的 0 或 1。 - 测量:0 ⇒ 常值,1 ⇒ 平衡。
对照代码理解
请逐行对照上文原理来读:x(q[1]) 接 h(q[1]) 把辅助比特制成 |−⟩;h(q[0]) 给数据比特制备叠加;当传入 oracle_balanced=True 时,x.ctrl(q[0], q[1]) 这条 CNOT 就是平衡谕示 f(x)=x,正是它触发了相位回踢;末端的 h(q[0]) 完成干涉,使 mz(q[0]) 的结果确定地报告函数类别。
示例代码只演示了常值函数 f(x)=0 与平衡函数 f(x)=x。若要实现 f(x)=1,可在 oracle 中对辅助比特加一次 x(q[1]);若要实现 f(x)=1⊕x,可在 CNOT 基础上加入一次辅助比特翻转。无论选择哪一个常值或平衡 oracle,最终测量结果仍分别稳定为 0 或 1。
import qalgora
@qalgora.kernel
def deutsch(oracle_balanced: bool):
q = qalgora.qvector(2)
x(q[1])
h(q[0]); h(q[1])
if oracle_balanced: # f(x) = x -> CNOT oracle
x.ctrl(q[0], q[1])
h(q[0])
mz(q[0]) # 0 => constant, 1 => balanced
print(qalgora.sample(deutsch, True)) # balanced -> always 1
print(qalgora.sample(deutsch, False)) # constant -> always 0
q[1] 多加一个 x),确认结果仍稳定为 1。再试两个常值谕示——你会发现量子比特的计数始终聚成单一确定峰,这正是干涉确定性的直接体现。
参考文献
- D. Deutsch, "Quantum theory, the Church-Turing principle and the universal quantum computer," Proc. R. Soc. Lond. A 400, 97-117 (1985). doi:10.1098/rspa.1985.0070