Bell态制备
使用 pyqpanda3 创建并验证 Bell(EPR)纠缠态。
问题
什么是Bell态?
Bell态(也称为 EPR 对,以 Einstein、Podolsky 和 Rosen 命名)是一对最大纠缠的量子比特。四个Bell态构成了双量子比特希尔伯特空间的一组完备正交基:
最常用的是 0,或者都产生 1。每种结果出现的概率为 01 和 10 结果永远不会出现。这种完美关联性与量子比特之间的物理距离无关。
为什么Bell态很重要?
Bell态是量子计算和量子信息的基础,原因如下:
纠缠验证。 Bell态是量子纠缠的最简单示例。它们用于 Bell不等式实验(CHSH 游戏)来证明自然界不能用局域隐变量理论描述。
量子隐形传态。 共享的Bell对是量子信道,能够仅通过经典通信传态任意量子比特态。
超密编码。 通过操控Bell对中的一个量子比特,发送方可以向持有两个量子比特的接收方传输两个经典比特。
量子密钥分发(QKD)。 如 E91 等协议使用Bell对生成具有信息论安全性的共享密钥。
纠错。 Bell态在容错协议中被消耗,例如基于传态的门操作和表面码的格点缝合。
基准测试。 制备和测量Bell态是真实量子硬件上评估双量子比特门保真度的标准校准程序。
方案
基本 Bell 态的电路
从初始态
- 对量子比特 0 施加 Hadamard 门。 这创建了均匀叠加态:
- 以量子比特 0 为控制、量子比特 1 为目标施加 CNOT 门。 这使两个量子比特纠缠:
- 测量两个量子比特以坍缩态并收集统计信息。
制备全部四个Bell态
每个Bell态都可以通过在纠缠前对其中一个量子比特施加 Pauli 门从
| 目标态 | 量子比特 1 上的额外门 | 电路 |
|---|---|---|
| (无) | H(0) -- CNOT(0,1) | |
| CNOT 前加 Z(1) | Z(1) -- H(0) -- CNOT(0,1) | |
| CNOT 前加 X(1) | X(1) -- H(0) -- CNOT(0,1) | |
| CNOT 前加 Y(1) | Y(1) -- H(0) -- CNOT(0,1) |
等效地,你可以在 CNOT 之后施加校正,这在组合电路时通常更方便:
| 目标态 | CNOT 后的校正 |
|---|---|
| (无) | |
| Z(0) | |
| X(0) | |
| Y(0) |
代码
基本Bell态制备与测量
这是最简示例:制备
from pyqpanda3 import core
# Build the Bell state circuit.
# QProg is the top-level container for quantum operations.
prog = core.QProg()
# Step 1: Apply Hadamard to qubit 0.
# This puts qubit 0 into the equal superposition (|0> + |1>) / sqrt(2).
prog << core.H(0)
# Step 2: Apply CNOT with qubit 0 as control, qubit 1 as target.
# This correlates the two qubits, producing the Bell state |Phi+>.
prog << core.CNOT(0, 1)
# Step 3: Measure both qubits into classical bits 0 and 1.
prog << core.measure([0, 1], [0, 1])
# Create the CPU statevector simulator and run 10,000 shots.
machine = core.CPUQVM()
machine.run(prog, shots=10000)
# Retrieve measurement counts.
counts = machine.result().get_counts()
print("Bell state |Phi+> counts:", counts)
# Expected: {'00': ~5000, '11': ~5000}, no '01' or '10'预期输出:
Bell state |Phi+> counts: {'00': 4973, '11': 5027}获取状态向量并验证振幅
当你需要直接检查量子态(而非通过测量统计)时,运行不带测量的电路并获取状态向量。
from pyqpanda3 import core
import numpy as np
# Build the Bell state circuit WITHOUT measurement.
prog = core.QProg()
prog << core.H(0)
prog << core.CNOT(0, 1)
# Run on CPUQVM. Without measurement, we get the full state vector.
machine = core.CPUQVM()
machine.run(prog, shots=1)
# Retrieve the state vector.
sv = machine.result().get_state_vector()
print("State vector:", sv)
# The Bell state |Phi+> should have amplitudes:
# |00>: 1/sqrt(2) ~ 0.7071
# |01>: 0
# |10>: 0
# |11>: 1/sqrt(2) ~ 0.7071
expected = np.array([1, 0, 0, 1]) / np.sqrt(2)
assert np.allclose(np.abs(sv), np.abs(expected), atol=1e-10), \
"State vector does not match expected Bell state amplitudes"
# Verify probabilities sum to 1.
probs = np.abs(sv) ** 2
print("Probabilities:", dict(zip(["00", "01", "10", "11"], probs)))
print("Sum of probabilities:", np.sum(probs))
# Expected: {'00': 0.5, '01': 0.0, '10': 0.0, '11': 0.5}, sum = 1.0预期输出:
State vector: [0.70710678+0.j 0.+0.j 0.+0.j 0.70710678+0.j]
Probabilities: {'00': 0.5, '01': 0.0, '10': 0.0, '11': 0.5}
Sum of probabilities: 1.0全部四个Bell态
本示例制备每个Bell态并打印测量分布,以便你看到它们之间的差异。
from pyqpanda3 import core
def make_bell_state(variant):
"""Prepare one of the four Bell states.
Args:
variant: One of 'phi+', 'phi-', 'psi+', 'psi-'.
Returns:
A QProg that prepares the requested Bell state and measures both qubits.
"""
prog = core.QProg()
prog << core.H(0)
prog << core.CNOT(0, 1)
# Apply the appropriate Pauli correction to select the Bell state variant.
if variant == "phi+":
pass # No correction needed
elif variant == "phi-":
prog << core.Z(0)
elif variant == "psi+":
prog << core.X(0)
elif variant == "psi-":
# Y = iXZ, but in the computational basis Y = [[0,-i],[i,0]].
# For measurement statistics, applying Z followed by X is equivalent
# to applying Y up to an irrelevant global phase.
prog << core.Z(0)
prog << core.X(0)
else:
raise ValueError(f"Unknown Bell state variant: {variant}")
prog << core.measure([0, 1], [0, 1])
return prog
# Run all four variants and display the results.
machine = core.CPUQVM()
shots = 10000
for variant in ["phi+", "phi-", "psi+", "psi-"]:
prog = make_bell_state(variant)
machine.run(prog, shots=shots)
counts = machine.result().get_counts()
print(f"|{variant:>4s}> : {counts}")预期输出:
|phi+> : {'00': 4985, '11': 5015}
|phi-> : {'00': 5008, '11': 4992}
|psi+> : {'01': 5023, '10': 4977}
|psi-> : {'01': 4961, '10': 5039}关于区分 00 和 11。相对相位(
通过关联性验证纠缠
通过确认两个量子比特完全关联来验证纠缠。本示例收集大量采样并检查是否没有非关联结果(01 或 10)出现。
from pyqpanda3 import core
# Prepare the Bell state |Phi+>.
prog = core.QProg()
prog << core.H(0)
prog << core.CNOT(0, 1)
prog << core.measure([0, 1], [0, 1])
machine = core.CPUQVM()
shots = 100000
machine.run(prog, shots=shots)
counts = machine.result().get_counts()
# The correlated outcomes.
correlated = counts.get("00", 0) + counts.get("11", 0)
# The uncorrelated outcomes (should be zero in a noiseless simulation).
uncorrelated = counts.get("01", 0) + counts.get("10", 0)
correlation_rate = correlated / shots
print(f"Correlated outcomes (00, 11): {correlated} / {shots} = {correlation_rate:.6f}")
print(f"Uncorrelated outcomes (01, 10): {uncorrelated}")
# In a noiseless simulation, the correlation should be exactly 1.0.
assert correlation_rate == 1.0, f"Unexpected uncorrelated outcomes: {uncorrelated}"
print("PASS: Perfect correlation confirmed (noiseless simulation).")预期输出:
Correlated outcomes (00, 11): 100000 / 100000 = 1.000000
Uncorrelated outcomes (01, 10): 0
PASS: Perfect correlation confirmed (noiseless simulation).在 DensityMatrixSimulator 上运行
DensityMatrixSimulator 可用于详细分析量子态——纯度、约化密度矩阵和精确概率——无需采样噪声。
from pyqpanda3 import core
import numpy as np
# Build the Bell state circuit without measurement.
prog = core.QProg()
prog << core.H(0)
prog << core.CNOT(0, 1)
# Run on the density matrix simulator.
dm_sim = core.DensityMatrixSimulator()
dm_sim.run(prog)
# Get exact probabilities for each basis state.
probs = dm_sim.state_probs()
print("Exact probabilities:")
for idx, p in enumerate(probs):
label = format(idx, "02b")
print(f" |{label}>: {p:.6f}")
# Get the full density matrix (4x4 for 2 qubits).
dm = dm_sim.density_matrix()
print(f"\nDensity matrix shape: {dm.shape}")
print(f"Density matrix:\n{dm}")
# Verify purity. For a pure state, Tr(rho^2) = 1.0.
purity = np.trace(dm @ dm).real
print(f"\nPurity Tr(rho^2): {purity:.6f}")
assert abs(purity - 1.0) < 1e-10, "State is not pure!"
# Compute the reduced density matrix for qubit 0 by tracing out qubit 1.
# For a maximally entangled state, each subsystem is maximally mixed: I/2.
reduced_q0 = dm_sim.reduced_density_matrix([0])
print(f"\nReduced density matrix (qubit 0):\n{reduced_q0}")
reduced_purity = np.trace(reduced_q0 @ reduced_q0).real
print(f"Reduced purity: {reduced_purity:.6f} (maximally mixed = 0.5)")预期输出:
Exact probabilities:
|00>: 0.500000
|01>: 0.000000
|10>: 0.000000
|11>: 0.500000
Density matrix shape: (4, 4)
Density matrix:
[[0.5+0.j 0. -0.j 0. -0.j 0.5+0.j]
[0. -0.j 0. +0.j 0. +0.j 0. -0.j]
[0. -0.j 0. +0.j 0. +0.j 0. -0.j]
[0.5+0.j 0. -0.j 0. -0.j 0.5+0.j]]
Purity Tr(rho^2): 1.000000
Reduced density matrix (qubit 0):
[[0.5+0.j 0. +0.j]
[0. +0.j 0.5+0.j]]
Reduced purity: 0.500000 (maximally mixed = 0.5)单个量子比特是最大混合态(
在 Stabilizer 模拟器上运行
Bell 态电路仅使用 Clifford 门(H 和 CNOT),因此可以在 Stabilizer 后端上高效模拟。这对于快速测试或量子比特数量较多时(全状态向量模拟代价较高)非常有用。
from pyqpanda3 import core
# The same Bell state circuit -- all gates are Clifford.
prog = core.QProg()
prog << core.H(0)
prog << core.CNOT(0, 1)
prog << core.measure([0, 1], [0, 1])
# The Stabilizer simulator tracks Pauli stabilizer generators instead of
# the full state vector. It runs in O(n^2) time per gate rather than O(2^n).
stab = core.Stabilizer()
stab.run(prog, shots=10000)
result = stab.result()
counts = result.get_counts()
print("Stabilizer Bell state counts:", counts)
# The results should match CPUQVM: only '00' and '11', roughly 50/50.预期输出:
Stabilizer Bell state counts: {'00': 4998, '11': 5002}带噪声模拟的Bell态
真实量子硬件会引入误差。本示例展示去极化噪声模型如何使之前被禁止的结果(01、10)以小但非零的概率出现。
from pyqpanda3 import core
# Build the Bell state circuit.
prog = core.QProg()
prog << core.H(0)
prog << core.CNOT(0, 1)
prog << core.measure([0, 1], [0, 1])
# Create a noise model with 2% depolarizing error on CNOT gates.
noise = core.NoiseModel()
noise.add_quantum_error(
core.depolarizing_error(0.02),
core.GateType.CNOT,
[0, 1]
)
# Add 1% depolarizing error on single-qubit gates.
noise.add_quantum_error(
core.depolarizing_error(0.01),
core.GateType.H,
[0]
)
noise.add_quantum_error(
core.depolarizing_error(0.01),
core.GateType.H,
[1]
)
# Run with noise on the CPUQVM.
machine = core.CPUQVM()
machine.run(prog, shots=10000, model=noise)
noisy_counts = machine.result().get_counts()
print("Noisy Bell state counts:", noisy_counts)
# Compute the Bell fidelity: fraction of outcomes that are correlated.
bell_fidelity = (noisy_counts.get("00", 0) + noisy_counts.get("11", 0)) / 10000
print(f"Bell fidelity: {bell_fidelity:.4f}")
# Also compare with the noiseless result.
machine.run(prog, shots=10000)
ideal_counts = machine.result().get_counts()
print(f"Ideal counts: {ideal_counts}")预期输出:
Noisy Bell state counts: {'00': 4872, '11': 4891, '01': 128, '10': 109}
Bell fidelity: 0.9763
Ideal counts: {'00': 4985, '11': 5015}噪声将概率泄漏到 01 和 10 结果中,使Bell保真度低于 1.0。泄漏量取决于噪声强度。
比较不同噪声信道对Bell态的影响
不同的物理噪声机制对Bell态的影响不同。本示例施加几种误差信道并测量每种如何降低Bell保真度。
from pyqpanda3 import core
def bell_fidelity(noise_model, shots=10000):
"""Run a Bell state circuit with the given noise model and return fidelity."""
prog = core.QProg()
prog << core.H(0)
prog << core.CNOT(0, 1)
prog << core.measure([0, 1], [0, 1])
machine = core.CPUQVM()
machine.run(prog, shots=shots, model=noise_model)
counts = machine.result().get_counts()
correlated = counts.get("00", 0) + counts.get("11", 0)
return correlated / shots, counts
# Define noise models with different error channels at 3% strength.
error_rate = 0.03
channels = {
"Bit Flip (X)": core.pauli_x_error(error_rate),
"Phase Flip (Z)": core.pauli_z_error(error_rate),
"Depolarizing": core.depolarizing_error(error_rate),
"Amplitude Damping": core.amplitude_damping_error(error_rate),
"Phase Damping": core.phase_damping_error(error_rate),
}
print(f"{'Channel':<22s} {'Fidelity':>8s} {'Counts'}")
print("-" * 70)
for name, error in channels.items():
noise = core.NoiseModel()
noise.add_quantum_error(error, core.GateType.CNOT, [0, 1])
noise.add_quantum_error(error, core.GateType.H, [0])
noise.add_quantum_error(error, core.GateType.H, [1])
fid, counts = bell_fidelity(noise)
print(f"{name:<22s} {fid:>8.4f} {counts}")预期输出(近似):
Channel Fidelity Counts
----------------------------------------------------------------------
Bit Flip (X) 0.9148 {'00': 4576, '11': 4572, '01': 424, '10': 428}
Phase Flip (Z) 0.9472 {'00': 4734, '11': 4738, '01': 264, '10': 264}
Depolarizing 0.8953 {'00': 4476, '11': 4477, '01': 526, '10': 521}
Amplitude Damping 0.9210 {'00': 4924, '11': 4286, '01': 410, '10': 380}
Phase Damping 0.9472 {'00': 4738, '11': 4734, '01': 264, '10': 264}主要观察:
- 去极化噪声最具破坏性,因为它同时施加了三种 Pauli 误差。
- 振幅阻尼具有不对称性:
比 获得更多计数,因为误差驱动 。 - 相位翻转(Z)不会改变单个量子比特的计算基测量结果,但仍然会降低Bell保真度,因为 CNOT 将相位误差转换为目标量子比特上的比特误差。
使用 DensityMatrixSimulator 进行精确噪声分析
对于无采样噪声的精确噪声分析,可使用带噪声模型的 DensityMatrixSimulator。
from pyqpanda3 import core
import numpy as np
# Build the Bell state without measurement.
prog = core.QProg()
prog << core.H(0)
prog << core.CNOT(0, 1)
# Define a noise model with depolarizing error on CNOT.
noise = core.NoiseModel()
noise.add_quantum_error(
core.depolarizing_error(0.02),
core.GateType.CNOT,
[0, 1]
)
# Ideal simulation.
dm_ideal = core.DensityMatrixSimulator()
dm_ideal.run(prog)
ideal_probs = dm_ideal.state_probs()
ideal_dm = dm_ideal.density_matrix()
# Noisy simulation.
dm_noisy = core.DensityMatrixSimulator()
dm_noisy.run(prog, model=noise)
noisy_probs = dm_noisy.state_probs()
noisy_dm = dm_noisy.density_matrix()
# Compare exact probabilities.
print("Basis | Ideal | Noisy")
print("--------|-----------|----------")
for idx in range(4):
label = format(idx, "02b")
print(f" |{label}> | {ideal_probs[idx]:.6f} | {noisy_probs[idx]:.6f}")
# Compute purity.
ideal_purity = np.trace(ideal_dm @ ideal_dm).real
noisy_purity = np.trace(noisy_dm @ noisy_dm).real
print(f"\nIdeal purity: {ideal_purity:.6f}")
print(f"Noisy purity: {noisy_purity:.6f}")
print(f"Purity drop: {ideal_purity - noisy_purity:.6f}")
# Compute fidelity between ideal and noisy states.
# For a pure ideal state |psi>, F(|psi>, rho) = <psi|rho|psi>.
fidelity = np.real(ideal_dm[0, 0] * noisy_dm[0, 0]
+ ideal_dm[0, 3] * noisy_dm[3, 0]
+ ideal_dm[3, 0] * noisy_dm[0, 3]
+ ideal_dm[3, 3] * noisy_dm[3, 3])
print(f"Bell fidelity: {fidelity:.6f}")预期输出:
Basis | Ideal | Noisy
--------|-----------|----------
|00> | 0.500000 | 0.486667
|01> | 0.000000 | 0.013333
|10> | 0.000000 | 0.013333
|11> | 0.500000 | 0.486667
Ideal purity: 1.000000
Noisy purity: 0.973333
Purity drop: 0.026667
Bell fidelity: 0.973333解析
为什么 H 后跟 CNOT 能创建纠缠
让我们从
步骤 1:初始态。
步骤 2:对量子比特 0 施加 Hadamard。
Hadamard 矩阵为:
作用于
因此联合态变为:
此时量子比特未纠缠。该态是直积态:每个量子比特有各自独立的描述。
步骤 3:施加控制=0、目标=1 的 CNOT。
CNOT 门在控制比特为
因此:
该态不能写为两个单量子比特态的直积。量子比特已纠缠。
每个Bell态的数学推导
全部四个Bell态通过将 Pauli 门作用于
因为
因为
由于全局相位在物理上不可观测,
测量统计的解释
当你在计算基中测量
结果是完全关联的:测量量子比特 0 立即告诉你量子比特 1 的结果。这由条件概率量化:
这种完美关联性无法被任何尊重局域性(没有超光速通信)的经典理论重现。这就是 Bell 定理的内容,由 Aspect、Clauser、Zeilinger 等人实验证实(2022 年诺贝尔物理学奖)。
Bell态作为最大纠缠态
一个双量子比特态
对于
对量子比特 B 求偏迹:
这意味着如果你只看任一量子比特,它看起来完全随机:50% 的概率为
共生度和纠缠熵在Bell态上均达到最大值:
| 度量 | 公式 | Bell态值 |
|---|---|---|
| 共生度 | 1 | |
| 纠缠熵 | 1 比特 | |
| 子系统纯度 | 0.5 |
与量子隐形传态的联系
Bell态是使传态成为可能的量子资源。在标准传态协议中:
- Alice 和 Bob 共享一个Bell对
。Alice 持有量子比特 A;Bob 持有量子比特 B。 - Alice 纠缠她的未知态
与她的Bell对份额,使用 CNOT 和 Hadamard。 - Alice 测量她的两个量子比特(C 和 A),并将 2 比特经典结果发送给 Bob。
- Bob 施加 Pauli 校正(I、X、Z 或 Y)到他的量子比特 B,基于他收到的 2 个比特。校正后,Bob 的量子比特处于态
。
没有初始Bell对,传态是不可能的。Bell对提供了量子信道(纠缠),补偿了 Alice 仅发送经典信息的事实。
与超密编码的联系
超密编码是传态的逆过程:不是发送一个量子比特来传输两个经典比特,而是操控共享Bell对中的一个量子比特来编码两个经典比特,然后发送那一个量子比特。
协议如下:
- Alice 和 Bob 共享
。 - Alice 施加四种 Pauli 操作之一到她的量子比特 A:
:态保持 -- 编码 00:态变为 -- 编码 01:态变为 -- 编码 10:态变为 -- 编码 11
- Alice 发送她的量子比特 A 给 Bob。
- Bob 现在持有两个量子比特。他施加Bell测量(Bell态制备电路的逆操作:先 CNOT 再 Hadamard,然后测量)来区分他拥有四种Bell态中的哪一种,恢复两个经典比特。
四种 Pauli 操作恰好映射到四种Bell态,这就是为什么制备和区分所有四种Bell态的能力对超密编码至关重要。
实用技巧
1. 始终通过统计验证。 单次采样不能说明问题。运行至少 1,000 次采样来确认预期分布。对于定量保真度估计,使用 10,000 次或更多。
2. 使用 DensityMatrixSimulator 进行分析。 当你需要精确数值(纯度、约化密度矩阵、von Neumann 熵)时,使用 DensityMatrixSimulator 而非采样计数。
3. 使用 Stabilizer 进行大规模 Clifford 电路模拟。 如果你的Bell态是更大 Clifford 电路的一部分(例如,包含数百个量子比特的纠错码),Stabilizer 后端可以高效处理。
4. 真实地建模噪声。 当为硬件预测进行模拟时,使用逐门、逐量子比特的噪声模型,其误差率从目标设备校准。超导硬件的典型值为单量子比特门 0.1%,双量子比特门 1-2%。
5. Bell态电路是最简单的纠缠测试。 如果你的硬件或模拟器能正确产生 00 和 11 的 50/50 分布,且没有 01 或 10,你就验证了 Hadamard 和 CNOT 门工作正常。