Demo 3:矩阵秩

第 11 章 查询复杂度 · 本章演示 · 代码演示总索引

可视化:3 子图 —— 4×4 高斯消元 + 量子查询复杂度

对应教程:第 11 章 查询复杂度 中相关小节 · 依赖安装:pip install "unified-quantum[visualization,simulation]"

实现要点

核心:构造 4x4 二值矩阵 A (rank=3), 演示 (左上) 矩阵 A 热图 + rank + 奇异值 (右上) 高斯消元 4 步 row-echelon 形式 (经典 nm = 16 次 oracle 查询基线) (左下) 经典 O(nm) vs 量子 O(sqrt(r(n-r+1)) L T) 查询数对比 (右下) uniqc 验证 16 个 entry oracle: A[i,j]=0 -> P(0)~1; A[i,j]=1 -> P(0)~0

完整源码

demos/ch11-query-complexity/03_matrix_rank.py
  1"""
  2ch11 演示 3:矩阵秩判定查询复杂度对比 + Gaussian 消元步骤可视化
  3
  4对应教程:chenzhaoyun.com/quantum-tutorial/ch11-query-complexity/matrix-rank.html
  5核心:构造 4x4 二值矩阵 A (rank=3), 演示
  6     (左上) 矩阵 A 热图 + rank + 奇异值
  7     (右上) 高斯消元 4 步 row-echelon 形式 (经典 nm = 16 次 oracle 查询基线)
  8     (左下) 经典 O(nm) vs 量子 O(sqrt(r(n-r+1)) L T) 查询数对比
  9     (右下) uniqc 验证 16 个 entry oracle: A[i,j]=0 -> P(0)~1; A[i,j]=1 -> P(0)~0
 10
 11依赖:pip install unified-quantum[visualization]
 12运行:python demos/ch11-query-complexity/03_matrix_rank.py
 13"""
 14from pathlib import Path
 15
 16import matplotlib
 17matplotlib.use("Agg")
 18import matplotlib.pyplot as plt
 19import numpy as np
 20
 21from uniqc import Circuit, submit_task, wait_for_result
 22
 23OUT = Path(__file__).parent
 24SHOTS = 150  # 16 entry probes * 150 = 2400 total, < 3000 budget
 25
 26# === 4x4 binary matrix A (rank = 3) ===
 27A = np.array([[1, 1, 0, 1], [0, 1, 1, 1], [1, 0, 1, 0], [1, 1, 0, 1]], dtype=int)
 28
 29
 30def gaussian_steps(M: np.ndarray) -> list[np.ndarray]:
 31    A = M.astype(float).copy()
 32    n, m = A.shape
 33    steps = [A.copy()]
 34    for k in range(min(n, m)):
 35        pivot = next((i for i in range(k, n) if abs(A[i, k]) > 1e-9), None)
 36        if pivot is None:
 37            continue
 38        if pivot != k:
 39            A[[k, pivot]] = A[[pivot, k]]
 40        for i in range(n):
 41            if i != k and abs(A[i, k]) > 1e-9:
 42                A[i] -= (A[i, k] / A[k, k]) * A[k]
 43        steps.append(A.copy())
 44    return steps
 45
 46
 47def entry_oracle_p(row: int, col: int) -> float:
 48    """1-qubit RX(theta) oracle: P(0) = cos^2(pi*A[i,j]/2)."""
 49    c = Circuit()
 50    c.rx(0, float(np.pi * A[row, col]))
 51    c.measure(0)
 52    r = wait_for_result(submit_task(circuit=c, backend="dummy:local:simulator", shots=SHOTS))
 53    return float(r.probabilities.get("0", 0.0))
 54
 55
 56def belovs_Q(n: int, r: int, gap: float = 0.3) -> float:
 57    """Q = sqrt(r(n-r+1)) L T (dense oracle, T=1, L = sqrt(r)/gap)."""
 58    return np.sqrt(r * (n - r + 1)) * np.sqrt(r) / gap
 59
 60
 61# === 矩阵性质 ===
 62print("ch11-query-complexity demo 3: matrix rank via Gaussian elim + span program")
 63print(f"  matrix A shape = {A.shape}")
 64print(f"  A =\n{A}")
 65_, s, _ = np.linalg.svd(A.astype(float))
 66rank = int(np.sum(s > 1e-9))
 67print(f"  rank(A) = {rank},  sigma = {np.round(s, 4).tolist()}")
 68
 69# === Gaussian 消元 ===
 70gauss_steps = gaussian_steps(A)
 71
 72# === Oracle 验证 (16 个 entry) ===
 73n, m = A.shape
 74oracle_p0 = np.array([[entry_oracle_p(i, j) for j in range(m)] for i in range(n)])
 75print(f"  matrix entry oracle probes (16 entries, all P(0) in {{0, 1}}):")
 76for i in range(n):
 77    for j in range(m):
 78        print(f"    P(0|A[{i},{j}]={A[i,j]}) = {oracle_p0[i,j]:.3f}", end="  ")
 79    print()
 80
 81# === 复杂度曲线 ===
 82N_DIM_LIST = [4, 8, 16, 32, 64, 128, 256]
 83classical_curve = np.array([float(d * d) for d in N_DIM_LIST])
 84quantum_dense = np.array([belovs_Q(d, d // 2) for d in N_DIM_LIST])
 85quantum_midrank = np.array([belovs_Q(d, d // 4) for d in N_DIM_LIST])
 86quantum_sparse = np.array([belovs_Q(d, 1) for d in N_DIM_LIST])
 87
 88# === 画图 ===
 89fig, axes = plt.subplots(2, 2, figsize=(14.5, 9.5))
 90
 91# (左上) A 热图
 92ax = axes[0, 0]
 93im = ax.imshow(A, cmap="Blues", vmin=0, vmax=1)
 94for i in range(n):
 95    for j in range(m):
 96        ax.text(j, i, str(A[i, j]), ha="center", va="center", fontsize=14, fontweight="bold",
 97                color="white" if A[i, j] > 0.5 else "black")
 98ax.set_xticks(np.arange(m))
 99ax.set_yticks(np.arange(n))
100ax.set_xticklabels([f"col {j}" for j in range(m)])
101ax.set_yticklabels([f"row {i}" for i in range(n)])
102ax.set_title(f"binary matrix A (n x m = {n} x {m})\n"
103             f"rank = {rank},  sigma = {np.round(s, 3).tolist()}")
104plt.colorbar(im, ax=ax, fraction=0.046, pad=0.04)
105
106# (右上) Gaussian 4 步
107ax = axes[0, 1]
108ax.axis("off")
109inner = ax.get_subplotspec().subgridspec(2, 2, hspace=0.35, wspace=0.2)
110for k, step in enumerate(gauss_steps[:4]):
111    rk, ck = divmod(k, 2)
112    sax = fig.add_subplot(inner[rk, ck])
113    sax.imshow(np.abs(step), cmap="Oranges", vmin=0, vmax=2)
114    sax.set_xticks(np.arange(m))
115    sax.set_yticks(np.arange(n))
116    sax.set_xticklabels([str(j) for j in range(m)], fontsize=7)
117    sax.set_yticklabels([str(i) for i in range(n)], fontsize=7)
118    sax.set_title(f"step {k}" + (" (start)" if k == 0 else f" after pivot {k}"), fontsize=9)
119    for i in range(n):
120        for j in range(m):
121            sax.text(j, i, f"{step[i, j]:.1f}", ha="center", va="center", fontsize=7)
122ax.set_title(f"Gaussian elimination: {len(gauss_steps)-1} pivot steps\n"
123             f"classical baseline = n*m = {n*m} oracle queries", fontsize=10)
124
125# (左下) 复杂度对比
126ax = axes[1, 0]
127ax.loglog(N_DIM_LIST, classical_curve, "o-", color="#d62728", lw=2, ms=8, label=r"classical $Q = nm$")
128ax.loglog(N_DIM_LIST, quantum_dense, "s-", color="#1f77b4", lw=2, ms=8, label=r"quantum $r = n/2$ (dense)")
129ax.loglog(N_DIM_LIST, quantum_midrank, "^-", color="#2ca02c", lw=2, ms=7, label=r"quantum $r = n/4$")
130ax.loglog(N_DIM_LIST, quantum_sparse, "v-", color="#9467bd", lw=2, ms=7, label=r"quantum $r = 1$ (OR)")
131for x, yc, yd in zip(N_DIM_LIST, classical_curve, quantum_dense):
132    ax.annotate(f"{int(yc)}", (x, yc), textcoords="offset points", xytext=(4, 4),
133                fontsize=7, color="#d62728")
134    ax.annotate(f"{yd:.0f}", (x, yd), textcoords="offset points", xytext=(4, -12),
135                fontsize=7, color="#1f77b4")
136ref_x = np.array([N_DIM_LIST[0], N_DIM_LIST[-1]], dtype=float)
137ax.loglog(ref_x, ref_x ** 2, ":", color="#d62728", alpha=0.4)
138ax.loglog(ref_x, ref_x ** 1.5 * 0.5, ":", color="#1f77b4", alpha=0.4)
139ax.set_xlabel(r"matrix dim $n$  ($m = n$)")
140ax.set_ylabel(r"# oracle queries")
141ax.set_title(r"matrix rank decision: classical $nm$ vs quantum $O(\sqrt{r(n-r+1)} L T)$")
142ax.legend(loc="upper left", fontsize=8)
143ax.grid(alpha=0.3, which="both")
144
145# (右下) oracle 实测 P(0) 热图
146ax = axes[1, 1]
147im = ax.imshow(oracle_p0, cmap="viridis_r", vmin=0, vmax=1)
148for i in range(n):
149    for j in range(m):
150        ax.text(j, i, f"{oracle_p0[i, j]:.2f}", ha="center", va="center", fontsize=10,
151                color="white" if oracle_p0[i, j] > 0.5 else "black")
152ax.set_xticks(np.arange(m))
153ax.set_yticks(np.arange(n))
154ax.set_xticklabels([f"j={j}" for j in range(m)])
155ax.set_yticklabels([f"i={i}" for i in range(n)])
156ax.set_title("measured P(0) on matrix entry oracle\n"
157             "A_ij=0 -> P(0)~1 ;  A_ij=1 -> P(0)~0")
158plt.colorbar(im, ax=ax, fraction=0.046, pad=0.04)
159
160fig.suptitle("ch11 demo 3: matrix rank — Gaussian elimination vs Belovs span program",
161             y=1.01, fontsize=13)
162plt.tight_layout()
163out_path = OUT / "03_matrix_rank.png"
164plt.savefig(out_path, dpi=120, bbox_inches="tight")
165plt.close()
166
167print(f"  Gaussian elim: {len(gauss_steps)-1} pivots, classical baseline {n*m} queries")
168print(f"  Belovs span upper bound for n={n}, r={rank}: "
169      f"Q = sqrt({rank} * {n - rank + 1}) * L * T = {belovs_Q(n, rank):.1f} queries")
170print(f"  complexity scaling (n=m, dense oracle, gap=0.3):")
171for d, qc, qd, qs in zip(N_DIM_LIST, classical_curve, quantum_dense, quantum_sparse):
172    print(f"    n = {d:>4d}   classical = {int(qc):>6d}   "
173          f"quantum r=n/2 = {qd:>7.1f}   quantum r=1 = {qs:>6.1f}")
174print(f"  saved: {out_path}")

运行结果

Demo 3:矩阵秩

运行方式

# 仓库根目录执行;输出 PNG 到 demos/ch11-query-complexity/03_matrix_rank.png,关键统计到 stdout
.venv/bin/python3 demos/ch11-query-complexity/03_matrix_rank.py

← 本章演示 · ↑ 代码演示总索引 · ⌂ 教程门户