Demo 3:QFT 振幅相位¶
可视化:双图:振幅+相位 —— QFT_4|0010⟩ 16 个分量的极坐标散点
对应教程:第 3 章 量子算法基础 中相关小节 · 依赖安装:pip install "unified-quantum[visualization,simulation]"
实现要点¶
完整源码¶
demos/ch03-algo-basics/03_qft_4qubit.py¶
1"""
2ch03 演示 3:QFT_4 作用在 |0010⟩ 上,画振幅-相位极坐标散点
3
4对应教程:chenzhaoyun.com/quantum-tutorial/ch03-algo-basics/quantum-fourier-transform.html
5依赖:pip install unified-quantum[visualization]
6运行:python demos/ch03-algo-basics/03_qft_4qubit.py
7"""
8from uniqc import Circuit, qft_circuit, submit_task, wait_for_result
9import matplotlib
10matplotlib.use("Agg")
11import matplotlib.pyplot as plt
12import numpy as np
13from pathlib import Path
14
15OUT = Path(__file__).parent
16N_QUBITS = 4
17INPUT_INT = 2 # |0010>
18SHOTS = 2000
19
20# === 1. 构造 |0010> + QFT_4,并跑 dummy backend 拿计数做交叉验证 ===
21prep = Circuit()
22# 把 qubit 1 翻成 1,得到 |0010>(qubit 0 是最低位)
23prep.x(1)
24prep.add_circuit(qft_circuit(n_qubits=N_QUBITS, swaps=True))
25for q in range(N_QUBITS):
26 prep.measure(q)
27
28result = wait_for_result(
29 submit_task(circuit=prep, backend="dummy:local:simulator", shots=SHOTS)
30)
31counts = result.counts
32total = sum(counts.values())
33
34# === 2. 用 Circuit.get_matrix() 解析地拿 4-qubit 状态向量(拿相位) ===
35qft = qft_circuit(n_qubits=N_QUBITS, swaps=True)
36U = qft.get_matrix()
37state_in = np.zeros(2 ** N_QUBITS, dtype=complex)
38state_in[INPUT_INT] = 1.0
39state_out = U @ state_in # QFT|0010> 的精确振幅
40
41amps = np.abs(state_out) ** 2
42phases = np.angle(state_out) # in (-pi, pi]
43labels = [f"{i:0{N_QUBITS}b}" for i in range(2 ** N_QUBITS)]
44
45# 模拟测量的频率(仅用来显示在标注里)
46empirical = np.array([counts.get(lbl, 0) / total for lbl in labels])
47
48# === 3. matplotlib 极坐标散点(振幅半径、相位角度) ===
49fig, axes = plt.subplots(1, 2, figsize=(13, 6),
50 subplot_kw={"projection": "polar"})
51
52# 左图:所有 16 个分量的振幅-相位
53ax = axes[0]
54ax.scatter(phases, amps, s=120, c="#1f77b4", edgecolor="black", zorder=3)
55ax.set_theta_zero_location("E")
56ax.set_theta_direction(1)
57ax.set_ylim(0, 0.30)
58ax.set_yticks([0.0625, 0.125, 0.1875])
59ax.set_yticklabels(["1/16", "1/8", "3/16"], fontsize=8)
60ax.set_xlabel("phase (rad)")
61ax.set_title(
62 f"QFT_4 |{INPUT_INT:0{N_QUBITS}b}> : all 16 amplitudes\n"
63 f"|amplitude|^2 = {amps.mean():.3f} (uniform → 1/{2**N_QUBITS})",
64 fontsize=10,
65 pad=18,
66)
67
68# 右图:仅展示相位(半径固定),突出 QFT 相位编码
69ax = axes[1]
70fixed_r = 0.25
71ax.scatter(phases, np.full_like(phases, fixed_r), s=140, c="#d62728",
72 edgecolor="black", zorder=3)
73# 用线连接相邻角度方便观察
74order = np.argsort(phases)
75ax.plot(phases[order], np.full_like(phases[order], fixed_r),
76 color="#888", alpha=0.5, lw=1)
77ax.set_theta_zero_location("E")
78ax.set_theta_direction(1)
79ax.set_ylim(0, 0.30)
80ax.set_yticks([fixed_r])
81ax.set_yticklabels([f"r={fixed_r}"], fontsize=8)
82ax.set_xlabel("phase (rad)")
83ax.set_title(
84 f"Phase pattern of QFT_4 |{INPUT_INT:0{N_QUBITS}b}>\n"
85 f"phase(k) = 2π·k·x / 2^n (x={INPUT_INT}, n={N_QUBITS})",
86 fontsize=10,
87 pad=18,
88)
89
90# 在散点旁标注 3 个有代表性的标签
91for k in (0, 4, 8):
92 ax = axes[0]
93 ax.annotate(
94 f"|{k:0{N_QUBITS}b}>",
95 xy=(phases[k], amps[k]),
96 xytext=(phases[k] + 0.15, amps[k] + 0.04),
97 fontsize=8, arrowprops=dict(arrowstyle="-", color="gray", lw=0.5),
98 )
99
100fig.suptitle(
101 f"Quantum Fourier Transform on {N_QUBITS} qubits, input |{INPUT_INT:0{N_QUBITS}b}> "
102 f"({SHOTS} shots cross-checked, dummy:local:simulator)",
103 fontsize=12, y=1.02,
104)
105plt.tight_layout()
106plt.savefig(OUT / "03_qft_4qubit.png", dpi=120, bbox_inches="tight")
107plt.close()
108
109# === 4. stdout 关键统计 ===
110print("ch03-algo-basics demo 3: QFT_4 amplitude + phase of |0010>")
111print(f" total shots: {total}")
112print(f" unique outcomes: {int((empirical > 0).sum())} / {2**N_QUBITS} "
113 f"(all 16 expected for a uniform Fourier image)")
114print(f" all probabilities ≈ 1/{2**N_QUBITS} = {1/2**N_QUBITS:.4f} "
115 f"(max-min range = {empirical.max()-empirical.min():.3f})")
116print(f" empirical mean |amp|^2 = {empirical.mean():.4f}")
117print(f" phase spread (rad): [{phases.min():+.3f}, {phases.max():+.3f}]")
118print(f" saved: {OUT / '03_qft_4qubit.png'}")
运行结果¶

运行方式¶
# 仓库根目录执行;输出 PNG 到 demos/ch03-algo-basics/03_qft_4qubit.png,关键统计到 stdout
.venv/bin/python3 demos/ch03-algo-basics/03_qft_4qubit.py