3.2 雙量子位元閘 CNOT 與糾纏#
概念說明#
CNOT(controlled-NOT,控制反閘)是第一個雙量子位元閘,也是量子電路中唯一「把兩個位元綁在一起」的基本閘。它的真值表:
| 控制 | 標的 | 輸出 |
|---|---|---|
| 0 | 0 | 00 |
| 0 | 1 | 01 |
| 1 | 0 | 11 |
| 1 | 1 | 10 |
規則:控制位元為 1 時,翻轉標的位元。矩陣形式(基底順序 \(|00\rangle,|01\rangle,|10\rangle,|11\rangle\) ):
\[ \mathrm{CNOT} = \begin{pmatrix}1&0&0&0\\0&1&0&0\\0&0&0&1\\0&0&1&0\end{pmatrix} \]
CNOT 最大的功勞是製造糾纏。標準程序:
- H 作用在控制位元: \(|00\rangle \to \frac{|00\rangle+|10\rangle}{\sqrt2}\) ;
- CNOT: \(\to \frac{|00\rangle+|11\rangle}{\sqrt2} = |\Phi^+\rangle\) (Bell 態)。
直觀理解:H 之後控制位元處於「0 與 1 的疊加」,CNOT 則讓「若為 1 就翻轉標的」這條規則作用在整個疊加上,於是兩個位元的命運被綁在一起——這是古典邏輯閘做不到的,因為古典 XOR 不可逆,而 CNOT 是可逆的(再作用一次就還原)。
CNOT 與單量子位元閘的組合可以建構交換(SWAP)、受控相位(CZ = H·CNOT·H)等更大結構。
Python 範例#
import numpy as np
ket0 = np.array([1, 0], dtype=complex)
ket1 = np.array([0, 1], dtype=complex)
H = np.array([[1, 1], [1, -1]], dtype=complex) / np.sqrt(2)
CNOT = np.array([[1,0,0,0],[0,1,0,0],[0,0,0,1],[0,0,1,0]], dtype=complex)
def kron(*vecs):
out = np.array([1], dtype=complex)
for v in vecs:
out = np.kron(out, v)
return out
# Bell 態電路:H(控制) 後接 CNOT
bell = CNOT @ kron(H @ ket0, ket0)
print("Bell 態:", np.round(bell, 3))
print("糾纏嗎? 秩 =", np.linalg.matrix_rank(bell.reshape(2, 2))) # 2 > 1
# CNOT 是可逆的:作用兩次=恆等
print("CNOT^2 == I:", np.allclose(CNOT @ CNOT, np.eye(4)))
# SWAP = 3 個 CNOT
CNOT_r = CNOT # 此基底下對稱
SWAP = CNOT_r @ CNOT_r @ CNOT_r
x0 = kron(ket1, ket0) # |10>
print("SWAP|10> =", np.round(SWAP @ x0, 3)) # -> |01>
# 糾纏態的測量相關性:量第一個位元
rng = np.random.default_rng(0)
p = np.abs(bell)**2
samples = rng.choice(4, size=10000, p=p)
print("00 出現:", np.mean(samples == 0), " 11 出現:", np.mean(samples == 3))
# 01 與 10 從不出現:兩位元永遠相同
複雜度分析#
CNOT 作用在 \(n\) 位元狀態向量上:只交換「控制位元=1」的那一半振幅,成本 \(O(2^{n-1}) = O(2^n)\) 。SWAP 需 3 個 CNOT。一般受控 \(U\) 的稠密矩陣是 \(2^n \times 2^n\) ,但結構化的受控閘同樣只需 \(O(2^n)\) 更新。
練習#
- 計算 CNOT 作用在 \(\frac{|00\rangle-|11\rangle}{\sqrt2}\) 的結果,說明為什麼 Bell 態經 CNOT 後仍是糾纏態。
- 用 H 與 CNOT 製造 \(|\Psi^+\rangle = \frac{|01\rangle+|10\rangle}{\sqrt2}\) ,並寫程式驗證。
- (程式)實作「標的位元在第 0 位」的 CNOT(即控制與標的互換),作用在 Bell 態上,觀察結果是否不變,並解釋原因。