量子计算入门:量子比特、基底与布洛赫球
一、经典比特 vs 量子比特
经典比特是计算机中最小的数据单元:只有0或1两种确定取值,一个占一个比特位。
量子比特完全不同。它用 |0⟩ 和 |1⟩ 的量子态来描述状态——不是一个确切的值,而是一个不确定的叠加态。通过狄拉克符号,量子态可以像向量一样做线性组合,组合出新的态。
| 经典比特 | 量子比特 |
|---|---|
| 只能是0或1 | 可以是0和1的叠加 |
| 像硬币躺平了 | 像硬币在空中转 |
| 一个确定状态 | 布洛赫球面上的任意一点 |
|0⟩ 和 |1⟩ 是最常用的基底——相当于向量空间里的坐标轴。之前学过的光偏振和S-G实验中,银原子通过加热后出现上下两个点(正态和负态),这就是两个量子态。按常理来说射出的范围应该是一个小圆圈,但实际是两个点——这正是量子现象的标志。
二、用Python表示量子态
在量子计算中,一个量子态用二维复数向量表示:
import numpy as np
# 计算基底
zero_qubit = np.matrix('1;0') # |0⟩ = [1, 0]ᵀ
one_qubit = np.matrix('0;1') # |1⟩ = [0, 1]ᵀ
np.matrix('1;0') 用字符串创建矩阵,; 分割行,1;0 表示两行一列的矩阵,等价于 np.matrix([[1], [0]])。
这两个向量是计算基态,也是基底——量子门和量子变换的常用输入。
制备叠加态的函数:
def mix(zero, one):
if zero + one != 1:
raise Exception("总概率不等于100%")
return np.sqrt(zero) * zero_qubit + np.sqrt(one) * one_qubit
zero 和 one 是概率比例(比如0.3和0.7),函数返回 √0.3 |0⟩ + √0.7 |1⟩。开根号是因为概率 = 概率幅的平方(玻恩定则)。
qubit_50_50 = mix(0.5, 0.5) # 各50%的叠加态 = |+⟩
qubit_30_70 = mix(0.3, 0.7) # 偏0.3-0.7的叠加态
三、X基底和Y基底——换个角度看同一个量子态
|0⟩ 和 |1⟩ 是Z基底(对应S-G实验中Z方向的上自旋和下自旋)。
但量子态还可以从其他方向来测量,这就引入了X基底和Y基底:
X基底
|+⟩ = (1/√2) |0⟩ + (1/√2) |1⟩
|-⟩ = (1/√2) |0⟩ − (1/√2) |1⟩
用Python表示:
plus_qubit = 1 / np.sqrt(2) * np.matrix("1;1")
minus_qubit = 1 / np.sqrt(2) * np.matrix("1;-1")
X基底的本质是换一个方向来看同一个量子态。就像二维空间里把一个东西斜着45°放置——从正面看,你只能看到50%的面和50%的另一个面;从斜45°方向看,就能100%看清。
物理含义:
- |+⟩ 对应S-G实验中X方向的一束
- |-⟩ 对应S-G实验中X方向的另一束
|+⟩ 不仅包含 |0⟩ 还包含 |1⟩。这意味着:
- 用Z基底测量 |+⟩ → 50%得到 |0⟩,50%得到 |1⟩
- 用X基底测量 |+⟩ → 100%得到 |+⟩,确定的结果
就像换了一个观测角度,同一个量子态在不同基底下完全有不同的表现。
Y基底
Y基底引入了虚数 i:
|↻⟩ = (1/√2) |0⟩ + (i/√2) |1⟩ 顺时针方向
|↺⟩ = (1/√2) |0⟩ − (i/√2) |1⟩ 逆时针方向
clockwise_qubit = 1/np.sqrt(2) * np.matrix([[1], [1j]])
counterclockwise_qubit = 1/np.sqrt(2) * np.matrix([[1], [-1j]])
Y基底与其他基底的关键区别:引入了虚数单位 i(1j在Python中表示虚数;单独的j不表示虚数,前面必须加数字)。这在物理上描绘的是Y轴方向的自旋,涉及量子的相位信息。
三组基底的关系
X、Y、Z三组基底都是正交归一的——类似于空间中的XYZ三轴互相垂直。1/√2 是归一化系数,保证量子态满足概率总和=1的规则。
在布洛赫球上,每组方向的一对态足以描述自己平面中的全部内容。Z基底只能表示 |0⟩ 和 |1⟩ 的线性组合,不能直接从Y轴的角度来描述。换基底就是换视角——这就是布洛赫球的用处。
四、布洛赫球——所有量子态构成一个球
为什么是球?
量子态通式:|ψ⟩ = α|0⟩ + β|1⟩,且 |α|² + |β|² = 1
α和β是两个复数,看起来有4个实数。但有两个约束条件:
| 约束 | 效果 |
|---|---|
| |α|² + |β|² = 1(归一化) | 减1个自由度 |
| 全局相位不可观测(|ψ⟩ 和 e^(iγ)|ψ⟩ 是同一个态) | 减1个自由度 |
| 剩下 | 2个实数 |
2个实数参数 → 可以画在一个球面上。 这就得到了布洛赫球。
球面上的两个角度 θ 和 φ
像地球上用经纬度定位:
|0⟩(北极,θ=0°)
↑
|
| · ← 某个量子态 (θ, φ)
| /
| /
|/
──────┼────────
/|
/ |
/ |
↓
|1⟩(南极,θ=180°)
- θ:从北极往南偏了多少(0°~180°)
- φ:绕赤道转了多少(0°~360°)
完整公式:
|ψ⟩ = cos(θ/2) |0⟩ + e^(iφ) sin(θ/2) |1⟩
为什么是 θ/2 而不是 θ?
这是布洛赫球最反直觉的地方。
在希尔伯特空间里,互相正交的态(内积=0)在布洛赫球上方向相反(夹角180°)。
如果你直接用 θ 作为参数:|ψ⟩ = cos(θ)|0⟩ + sin(θ)|1⟩
- θ=0° → |0⟩ ✅
- θ=180° → |1⟩ ✅(和|0⟩正交,没毛病)
但出问题在赤道上。θ=90°和θ=270°在球面上是对映点(方向相反),按理说应该正交:
θ=90°: |ψ₁⟩ = cos90°|0⟩ + sin90°|1⟩ = |1⟩
θ=270°: |ψ₂⟩ = cos270°|0⟩ + sin270°|1⟩ = -|1⟩
⟨ψ₁|ψ₂⟩ = -1 ≠ 0 ❌ 不正交!
用 θ/2 就对了:
θ=90°: cos(45°)|0⟩ + sin(45°)|1⟩ = (|0⟩+|1⟩)/√2 = |+⟩
θ=270°: cos(135°)|0⟩ + sin(135°)|1⟩ = (-|0⟩+|1⟩)/√2 = |-⟩
⟨+|−⟩ = 0 ✅ 正交!
θ/2 的本质:把希尔伯特空间里的「直角」翻译成布洛赫球面上的「对映点」。除以2就是这个翻译的代价。
φ 和 e^(iφ) 的作用
- θ 决定:测到 |0⟩ 的概率(= cos²(θ/2))
- φ 决定:|0⟩ 分量和 |1⟩ 分量之间的相对相位(经典世界不存在的属性)
| θ | φ | 态 | 在哪 |
|---|---|---|---|
| 0° | 任意 | |0⟩ | 北极 |
| 90° | 0° | |+⟩ = (|0⟩+|1⟩)/√2 | 赤道X正方向 |
| 90° | 90° | (|0⟩+i|1⟩)/√2 | 赤道Y正方向 |
| 90° | 180° | |-⟩ = (|0⟩−|1⟩)/√2 | 赤道X负方向 |
| 180° | 任意 | |1⟩ | 南极 |
赤道上φ=0°和φ=180°:|+⟩ 和 |-⟩ 的概率分布一样(各50%-50%),但因为相对相位不同,它们是两个完全不同的量子态。
为什么布洛赫球重要?
任意单量子比特态 → 球面上一个点
任意单量子比特门 → 球的某种旋转
量子态的演化 → 点在球面上移动的轨迹
量子门操作就是在旋转这个球:Hadamard门把北极点 |0⟩ 旋转到赤道上的 |+⟩,相当于绕Y轴转90°。
你只需要记住:Z轴两极是 |0⟩ 和 |1⟩,赤道一圈是50-50叠加态,X正方向是 |+⟩,Y正方向带虚数 i。
五、用Python计算布洛赫坐标
把量子态想象成从球心指向球面的箭头,用三维坐标 (x, y, z) 表示,取值范围 [-1, 1]。(0, 0, 1) 是正态,(0, 0, -1) 是负态,其他位置的箭头都是叠加态。
在真实的量子力学中,一旦测量,箭头就坍缩,只能得到0或1,没法直接测到 x, y, z 的数值。但可以通过多次测量来反推坐标值。
思路:从三个不同角度进行重复测量。
def get_bloch_coordinates(qubit):
# X轴坐标
def get_x_bloch(qubit):
qubit_x_basis = 1./np.sqrt(2) * np.matrix('1 1; 1 -1') * qubit
prob_zero_qubit = (qubit_x_basis.item(0) * qubit_x_basis.item(0).conjugate()).real
prob_one_qubit = (qubit_x_basis.item(1) * qubit_x_basis.item(1).conjugate()).real
return prob_zero_qubit - prob_one_qubit
# Y轴坐标
def get_y_bloch(qubit):
qubit_y_basis = 1./np.sqrt(2) * np.matrix('1 1; 1 -1') * np.matrix([[1,0], [0, 1j]]) * qubit
prob_zero_qubit = (qubit_y_basis.item(0) * qubit_y_basis.item(0).conjugate()).real
prob_one_qubit = (qubit_y_basis.item(1) * qubit_y_basis.item(1).conjugate()).real
return prob_zero_qubit - prob_one_qubit
# Z轴坐标
def get_z_bloch(qubit):
qubit_z_basis = qubit
prob_zero_qubit = (qubit_z_basis.item(0) * qubit_z_basis.item(0).conjugate()).real
prob_one_qubit = (qubit_z_basis.item(1) * qubit_z_basis.item(1).conjugate()).real
return prob_zero_qubit - prob_one_qubit
return (get_x_bloch(qubit), get_y_bloch(qubit), get_z_bloch(qubit))
三个方向的计算逻辑:
- Z轴(get_z_bloch):最直接,就是原始量子态。测上下的概率,Z坐标 = 测到0的概率 − 测到1的概率(0态在上面,1态在下面)。
- X轴(get_x_bloch):需要把球体「翻面」,让原来的左右变成上下。用阿达马矩阵(Hadamard Gate)来旋转量子比特,旋转后重算上下概率差,得到的就是X坐标。
- Y轴(get_y_bloch):需要旋转两次。先相位门旋转,再用阿达马矩阵旋转,得到Y坐标。
重要说明:这段代码是理论模拟器——直接用数学公式算概率,等于假设对同一个量子比特制造了无限个复制版同时测量。在真实的量子计算机上,不能只用一个量子比特运行这段代码,而是需要把量子态准备1000次,分别测量X/Y/Z各1000次才能得到三个坐标。代码中的 .conjugate() 是数学上的概率计算,只用于演示学习。
六、画出布洛赫球
def plot_bloch(qubit):
import matplotlib.pyplot as plt
fig = plt.figure() # 创建画布
ax = fig.add_subplot(111, projection='3d') # 3D子图
# 绘制球体线框
u, v = np.mgrid[0:2*np.pi:20j, 0:np.pi:10j] # 经纬线(球坐标)
x = np.cos(u) * np.sin(v) # 球坐标 → 直角坐标
y = np.sin(u) * np.sin(v)
z = np.cos(v)
ax.plot_wireframe(x, y, z, color="k", alpha=.1) # 透明线框球体
ax.grid(0)
# 画箭头:从球心指向球面
(x, y, z) = get_bloch_coordinates(qubit)
ax.quiver([0], [0], [0], [x], [y], [z], length=1, arrow_length_ratio=0.3)
# 坐标范围和视角
ax.set_xlim([-1, 1])
ax.set_ylim([-1, 1])
ax.set_zlim([-1, 1])
ax.view_init(azim=20)
return ax
逐段解释:
u, v:模拟经度和纬度,r=1所以不需要指定半径x, y, z:球坐标向直角坐标的标准转换plot_wireframe:把小格子连成透明线框,像球形铁笼子ax.quiver([0],[0],[0], [x],[y],[z]):从球心 (0,0,0) 出发,指向坐标 (x,y,z)set_xlim/set_ylim/set_zlim:把球固定在 [-1, 1] 范围
运行 plot_bloch(qubit_30_70) 就能看到量子态在布洛赫球上的位置:

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐



所有评论(0)