Skip to content

GHZ态制备

使用 pyqpanda3 创建 Greenberger-Horne-Zeilinger(GHZ)多量子比特纠缠态,并验证其独特的关联性。


问题

什么是GHZ态?

GHZ态(以 Greenberger、Horne 和 Zeilinger 命名)是一种特殊类型的多方量子纠缠,将双量子比特 Bell 态推广到三个或更多量子比特。对于 n 个量子比特的系统,GHZ态定义为:

|GHZn=12(|0n+|1n)|GHZ3=12(|000+|111)

与成对纠缠(Bell对)不同,GHZ态展现的是真正的多方纠缠——没有双分分解能完全描述其关联性。

所有量子比特同时处于全零态和全一态。

为什么GHZ态很重要?

GHZ态是量子信息科学的核心:

  1. 无需统计的 Bell 不等式违背:GHZ论证使用确定性预测展示了量子力学与局域隐变量理论之间的矛盾,无需统计不等式。
  2. 量子网络:GHZ态是量子秘密共享、会议密钥协商和分布式量子共识的资源。
  3. 量子计量学:多方纠缠使得海森堡极限相位估计成为可能(1/n 标度而非 1/n)。
  4. 容错量子计算:GHZ态是纠错码和魔术态蒸馏的基本构件。
  5. 基础测试:GHZ态以最鲜明的形式揭示了量子力学的非局域特征。

Mermin 不等式

对于 3 量子比特 GHZ态,Mermin算子提供了一种 Bell 型测试:

M=XXXXYYYXYYYX

局域隐变量理论满足 |M|2,量子力学预测 M=4 -- 最大违背。

这是已知最强的不依赖统计界限的反驳局域实在论的论证。


方案

逐步方法

步骤 1 -- 将所有量子比特初始化为 |0

|ψ0=|0n

步骤 2 -- 对第一个量子比特施加 Hadamard

H|0=12(|0+|1)|ψ1=12(|0n+|1|0(n1))

步骤 3 -- 施加级联 CNOT 门

对每个量子比特 k=1,2,,n1 施加 CNOT(0,k),其中量子比特 0 始终为控制:

每个 CNOT 将控制值复制到目标:

|ψ3=12(|0n+|1n)=|GHZn

步骤 4 -- 测量所有量子比特

所有量子比特产生相同的结果:全 0 或全 1,各以概率 1/2 出现。

电路图(3 量子比特 GHZ)

门数量:电路需要 1 个 Hadamard 门和 n1 个 CNOT 门,门深度为 n


代码

3 量子比特 GHZ态

python
from pyqpanda3 import core

# Build a 3-qubit GHZ circuit
prog = core.QProg()
prog << core.H(0)            # Hadamard on qubit 0
prog << core.CNOT(0, 1)      # Entangle qubit 0 with qubit 1
prog << core.CNOT(0, 2)      # Entangle qubit 0 with qubit 2
prog << core.measure([0, 1, 2], [0, 1, 2])

# Run on the CPU simulator
machine = core.CPUQVM()
machine.run(prog, shots=10000)
counts = machine.result().get_counts()

print("3-qubit GHZ measurement counts:")
for outcome, count in sorted(counts.items()):
    print(f"  |{outcome}> : {count}")
# Expected: |000> ~5000, |111> ~5000, no other outcomes

通用 n 量子比特 GHZ态函数

python
from pyqpanda3 import core
from typing import Dict


def build_ghz_circuit(n: int) -> core.QProg:
    """Build an n-qubit GHZ state preparation circuit."""
    if n < 2:
        raise ValueError(f"GHZ state requires n >= 2 qubits, got {n}")

    prog = core.QProg()
    prog << core.H(0)
    for k in range(1, n):
        prog << core.CNOT(0, k)
    prog << core.measure(list(range(n)), list(range(n)))
    return prog


def run_ghz(n: int, shots: int = 10000) -> Dict[str, int]:
    """Prepare and measure an n-qubit GHZ state."""
    prog = build_ghz_circuit(n)
    machine = core.CPUQVM()
    machine.run(prog, shots)
    return machine.result().get_counts()


# --- Example usage ---
for n in [3, 5, 8]:
    counts = run_ghz(n, shots=10000)
    ideal_keys = {"0" * n, "1" * n}
    ghz_counts = sum(v for k, v in counts.items() if k in ideal_keys)
    fidelity_est = ghz_counts / sum(counts.values())
    print(f"n={n}: GHZ fidelity estimate = {fidelity_est:.4f}")

通过测量统计进行验证

真正的 GHZ态有两个标志属性:只出现 |0n|1n,各接近 50%。

python
from pyqpanda3 import core


def verify_ghz_statistics(n: int, shots: int = 20000) -> None:
    """Verify GHZ state: only |000...0> and |111...1> with ~50% each."""
    prog = core.QProg()
    prog << core.H(0)
    for k in range(1, n):
        prog << core.CNOT(0, k)
    prog << core.measure(list(range(n)), list(range(n)))

    machine = core.CPUQVM()
    machine.run(prog, shots)
    counts = machine.result().get_counts()

    all_zeros = "0" * n
    all_ones = "1" * n
    total = sum(counts.values())
    count_0 = counts.get(all_zeros, 0)
    count_1 = counts.get(all_ones, 0)
    count_other = total - count_0 - count_1

    print(f"--- GHZ({n}) Verification ({shots} shots) ---")
    print(f"  |{all_zeros}> : {count_0} ({100*count_0/total:.1f}%)")
    print(f"  |{all_ones}> : {count_1} ({100*count_1/total:.1f}%)")
    print(f"  Other outcomes : {count_other} ({100*count_other/total:.2f}%)")

    assert count_other / total < 0.01, "Too many non-GHZ outcomes"
    print("  PASS: State is consistent with GHZ.")


for n in [3, 4, 5, 6]:
    verify_ghz_statistics(n)

使用 DensityMatrixSimulator 分析 GHZ态

DensityMatrixSimulator 可给出无采样噪声的精确概率,非常适合分析纯度、约化密度矩阵和保真度:

python
from pyqpanda3 import core
import numpy as np

# Build the 3-qubit GHZ circuit without measurement
prog = core.QProg()
prog << core.H(0)
prog << core.CNOT(0, 1)
prog << core.CNOT(0, 2)

# Run on the density matrix simulator
dm_sim = core.DensityMatrixSimulator()
dm_sim.run(prog)

# Get exact probabilities
probs = dm_sim.state_probs()
print("Exact probabilities (3-qubit GHZ):")
for idx, p in enumerate(probs):
    label = format(idx, '03b')
    if p > 1e-10:
        print(f"  |{label}>: {p:.6f}")

# Get the full density matrix (8x8 for 3 qubits)
dm = dm_sim.density_matrix()
print(f"Density matrix shape: {dm.shape}")

# Verify purity. For a pure state, Tr(rho^2) = 1.0.
purity = np.trace(dm @ dm).real
print(f"Purity Tr(rho^2): {purity:.6f}")
assert abs(purity - 1.0) < 1e-10, "State is not pure!"

# Compute the reduced density matrix for qubit 0.
# For the GHZ state, each subsystem is maximally mixed: I/2.
reduced_q0 = dm_sim.reduced_density_matrix([0])
print(f"Reduced 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)")

带噪声模拟的 GHZ态

真实量子器件存在噪声。本示例展示去极化噪声如何使 GHZ态退化,导致之前被禁止的结果出现:

python
from pyqpanda3 import core


def noisy_ghz(n: int, shots: int = 10000) -> None:
    """Simulate a GHZ state under depolarizing noise."""
    prog = core.QProg()
    prog << core.H(0)
    for k in range(1, n):
        prog << core.CNOT(0, k)
    prog << core.measure(list(range(n)), list(range(n)))

    # Define noise model
    noise = core.NoiseModel()
    for q in range(n):
        noise.add_quantum_error(
            core.depolarizing_error(0.01), core.GateType.H, [q]
        )
    for k in range(1, n):
        noise.add_quantum_error(
            core.depolarizing_error(0.02), core.GateType.CNOT, [0, k]
        )

    # Noisy simulation
    machine = core.CPUQVM()
    machine.run(prog, shots, model=noise)
    counts = machine.result().get_counts()

    # Ideal for comparison
    machine.run(prog, shots)
    ideal_counts = machine.result().get_counts()

    all_zeros = "0" * n
    all_ones = "1" * n
    total = sum(counts.values())
    ghz_count = counts.get(all_zeros, 0) + counts.get(all_ones, 0)

    print(f"--- GHZ({n}) Noise Comparison ({shots} shots) ---")
    print(f"  Ideal: {dict(sorted(ideal_counts.items()))}")
    print(f"  Noisy: {dict(sorted(counts.items()))}")
    print(f"  GHZ outcomes: {ghz_count}/{total} ({100*ghz_count/total:.1f}%)")


noisy_ghz(3, shots=10000)
noisy_ghz(5, shots=10000)

比较理想与噪声 GHZ态的关联性

DensityMatrixSimulator 可给出噪声下的精确概率(无采样噪声),非常适合精确比较:

python
from pyqpanda3 import core
import numpy as np


def compare_ideal_noisy_ghz(n: int) -> None:
    """Compare ideal and noisy GHZ probability distributions exactly."""
    prog = core.QProg()
    prog << core.H(0)
    for k in range(1, n):
        prog << core.CNOT(0, k)

    # Ideal
    dm_ideal = core.DensityMatrixSimulator()
    dm_ideal.run(prog)
    probs_ideal = np.array(dm_ideal.state_probs())
    dm_ideal_mat = dm_ideal.density_matrix()
    purity_ideal = np.trace(dm_ideal_mat @ dm_ideal_mat).real

    # Noisy
    noise = core.NoiseModel()
    for q in range(n):
        noise.add_quantum_error(
            core.depolarizing_error(0.02), core.GateType.H, [q]
        )
    for k in range(1, n):
        noise.add_quantum_error(
            core.depolarizing_error(0.02), core.GateType.CNOT, [0, k]
        )

    dm_noisy = core.DensityMatrixSimulator()
    dm_noisy.run(prog, model=noise)
    probs_noisy = np.array(dm_noisy.state_probs())
    dm_noisy_mat = dm_noisy.density_matrix()
    purity_noisy = np.trace(dm_noisy_mat @ dm_noisy_mat).real

    # Print comparison
    dim = 2 ** n
    print(f"\n--- GHZ({n}) Exact Probability Comparison ---")
    print(f"{'Basis':<{n+2}} {'Ideal':>10} {'Noisy':>10} {'Delta':>10}")
    print("-" * (n + 35))
    for i in range(dim):
        bs = format(i, f'0{n}b')
        d = abs(probs_ideal[i] - probs_noisy[i])
        if probs_ideal[i] > 1e-6 or probs_noisy[i] > 1e-6:
            print(f"|{bs}> {probs_ideal[i]:10.6f} {probs_noisy[i]:10.6f} {d:10.6f}")

    print(f"\nIdeal purity:  {purity_ideal:.6f}")
    print(f"Noisy purity:  {purity_noisy:.6f}")
    print(f"Purity loss:   {purity_ideal - purity_noisy:.6f}")


compare_ideal_noisy_ghz(3)
compare_ideal_noisy_ghz(4)

GHZ态保真度扫描

保真度 F=ψ|ρ|ψ 量化噪声态与理想 GHZ态的接近程度。本示例扫描噪声强度以观察退化:

python
from pyqpanda3 import core
import numpy as np


def ghz_fidelity_dm(n: int, noise: core.NoiseModel) -> float:
    """Compute exact fidelity F = <GHZ_n|rho|GHZ_n> using density matrices."""
    prog = core.QProg()
    prog << core.H(0)
    for k in range(1, n):
        prog << core.CNOT(0, k)

    dm_sim = core.DensityMatrixSimulator()
    dm_sim.run(prog, model=noise)
    rho = dm_sim.density_matrix()

    dim = 2 ** n
    ghz_vec = np.zeros(dim, dtype=complex)
    ghz_vec[0] = 1.0 / np.sqrt(2)
    ghz_vec[dim - 1] = 1.0 / np.sqrt(2)

    fidelity = float(np.real(ghz_vec.conj() @ rho @ ghz_vec))
    return fidelity


n = 4
print(f"GHZ({n}) fidelity vs. depolarizing error strength:")
print(f"{'Error rate':>12s}  {'Fidelity':>10s}")
print("-" * 25)
for p in [0.0, 0.005, 0.01, 0.02, 0.05, 0.1]:
    noise = core.NoiseModel()
    if p > 0:
        for q in range(n):
            noise.add_quantum_error(
                core.depolarizing_error(p), core.GateType.H, [q]
            )
        for k in range(1, n):
            noise.add_quantum_error(
                core.depolarizing_error(p), core.GateType.CNOT, [0, k]
            )
    fid = ghz_fidelity_dm(n, noise)
    print(f"{p:>12.3f}  {fid:>10.6f}")

GHZ态上的 Mermin 不等式测试

本示例估计 Mermin算子 M 以展示 GHZ态的非局域关联性:

python
from pyqpanda3 import core
from pyqpanda3.hamiltonian import PauliOperator


def mermin_inequality_test() -> None:
    """Test the Mermin inequality on a 3-qubit GHZ state.

    M = +XXX - XYY - YXY - YYX
    Classical bound: |<M>| <= 2, Quantum prediction: <M> = 4
    """
    terms = [
        (+1.0, "X0 X1 X2"),
        (-1.0, "X0 Y1 Y2"),
        (-1.0, "Y0 X1 Y2"),
        (-1.0, "Y0 Y1 X2"),
    ]

    mermin_value = 0.0
    for coeff, pauli_str in terms:
        prog = core.QProg()
        prog << core.H(0)
        prog << core.CNOT(0, 1)
        prog << core.CNOT(0, 2)

        op = PauliOperator(pauli_str)
        exp_val = core.expval_pauli_operator(prog, op)
        contribution = coeff * exp_val
        mermin_value += contribution
        print(f"  <{pauli_str}> = {exp_val:.6f}, contribution = {contribution:.6f}")

    print(f"\nMermin operator <M> = {mermin_value:.6f}")
    print(f"Classical bound: |<M>| <= 2")
    print(f"Quantum prediction: <M> = 4")
    if abs(mermin_value) > 2:
        print("RESULT: Mermin inequality VIOLATED!")
    else:
        print("RESULT: No violation detected.")


mermin_inequality_test()

解析

为什么级联 CNOT 能创建 GHZ态

|000 开始,量子比特 0 上的 Hadamard 创建叠加:

|0|00H012(|000+|100)

每个 CNOT 将控制(量子比特 0)复制到目标:

CNOT0112(|000+|110)CNOT0212(|000+|111)

对于 n 个量子比特,n1 个 CNOT 即可,因为量子比特 0 充当广播控制,同步所有目标。

纠缠结构:GHZ态 vs. Bell态

2 量子比特 GHZ态 |GHZ2=12(|00+|11) 与 Bell态 |Φ+ 完全相同。然而,对于 n3,GHZ态展现根本不同的纠缠:

性质Bell态(n=2GHZ态(n3
纠缠双方真正的多方
追踪一个量子比特剩余量子比特为最大混合态剩余量子比特为可分离混合态
鲁棒性中等非常脆弱
Bell 违背CHSH 不等式(S22Mermin 不等式(M=2n1

一个引人注目的性质:如果你追踪掉任何一个量子比特,剩余 n1 个量子比特变成完全可分离的混合态——所有纠缠都被破坏。这与 W态不同,后者在追踪后仍保持双方纠缠。

Mermin 不等式与 GHZ态关联性

推导利用 X 交换 |0|1,而 Y|0=i|1Y|1=i|0

  • X0X1X2|GHZ=+|GHZ(所有比特交换,叠加不变)
  • Y0Y1X2|GHZ=(i2)|111+((i)2)|000=|GHZ

得到 M=(+1)(1)(1)(1)=4。对于一般 n 量子比特情况,MABK 不等式给出:

|Mn|2(n1)/2(经典),Mn=2n1(量子)

量子与经典界限之间的比值指数增长:2(n1)/2

退相干敏感性:为什么 GHZ态很脆弱

GHZ态的相干性存在于单个非对角密度矩阵元素 ρ0,2n1=1/2 中。在每个量子比特独立相位阻尼率为 γ 的情况下,该元素衰减为:

ρ0,2n1(t)=12enγt

有效退相干率随 n 线性增长——更大的 GHZ态退相干速度是单个量子比特的 n 倍。

量子比特(nCNOT 门数深度1% CNOT 误差下的保真度
323~0.96
545~0.92
10910~0.83
201920~0.68
504950~0.40

缓解策略包括错误检测码、快速门(减少相对于 T1T2 的门时间)、基于辅助比特的奇偶校验验证协议,以及将深度从 n 减少到 2 的并行 CNOT 架构。


GHZ态验证

问题

制备 GHZ态后,如何验证电路确实产生了正确的纠缠态?仅靠测量计数不足以确认真正的多方纠缠。你需要结构化验证,同时检查布居数(正确的基态)和相干性(正确的相位关系)。

方案:多层验证

完整的 GHZ态验证协议检查三个独立标准:

  1. 布居数测试:只应出现 |0n|1n,各接近 50%。
  2. 奇偶性测试:相邻量子比特对必须具有偶奇偶性(两者相同)。任何相邻量子比特的 XOR 必须为 0。
  3. 相干性测试(可选):将所有量子比特旋转到 X 基并测量;所有结果应再次关联。

代码:使用 CPUQVM 进行完整 GHZ态验证

python
from pyqpanda3 import core
from typing import Dict, List


def ghz_population_test(counts: Dict[str, int], n: int, tol: float = 0.02) -> bool:
    """Check that only |000...0> and |111...1> appear with ~50% each."""
    total = sum(counts.values())
    all_zeros = "0" * n
    all_ones = "1" * n

    p0 = counts.get(all_zeros, 0) / total
    p1 = counts.get(all_ones, 0) / total
    p_other = 1.0 - p0 - p1

    print(f"  Population test:")
    print(f"    |{all_zeros}>: {p0:.4f}  (expected 0.5000)")
    print(f"    |{all_ones}>: {p1:.4f}  (expected 0.5000)")
    print(f"    Other:        {p_other:.4f}  (expected 0.0000)")

    pop_ok = (abs(p0 - 0.5) < tol) and (abs(p1 - 0.5) < tol) and (p_other < tol)
    print(f"    Result: {'PASS' if pop_ok else 'FAIL'}")
    return pop_ok


def ghz_parity_test(counts: Dict[str, int], n: int) -> bool:
    """Check that adjacent qubits always have even parity (XOR = 0).

    For a genuine GHZ state, every outcome has all qubits equal.
    So for any pair of adjacent qubits (i, i+1), XOR should be 0.
    """
    total = sum(counts.values())
    parity_violations = 0

    print(f"  Parity test (adjacent qubit XOR):")
    for i in range(n - 1):
        xor0_count = 0  # count of outcomes where qubit_i XOR qubit_{i+1} = 0
        for outcome, count in counts.items():
            bit_i = int(outcome[i])
            bit_j = int(outcome[i + 1])
            if bit_i == bit_j:  # XOR = 0
                xor0_count += count
        parity_frac = xor0_count / total
        print(f"    q[{i}] XOR q[{i+1}] = 0: {parity_frac:.4f}  (expected 1.0000)")
        if parity_frac < 0.98:
            parity_violations += 1

    parity_ok = parity_violations == 0
    print(f"    Result: {'PASS' if parity_ok else 'FAIL'} ({parity_violations} violations)")
    return parity_ok


def ghz_coherence_test(n: int, shots: int = 20000) -> bool:
    """Verify coherence by rotating all qubits into the X basis (H on each).

    A GHZ state rotated into the X basis produces correlated outcomes:
    all outcomes have even parity (even number of 1s).
    """
    prog = core.QProg()
    prog << core.H(0)
    for k in range(1, n):
        prog << core.CNOT(0, k)
    # Rotate into X basis: apply H to every qubit before measuring
    for k in range(n):
        prog << core.H(k)
    prog << core.measure(list(range(n)), list(range(n)))

    machine = core.CPUQVM()
    machine.run(prog, shots)
    counts = machine.result().get_counts()

    total = sum(counts.values())
    even_parity_count = 0
    for outcome, count in counts.items():
        num_ones = outcome.count("1")
        if num_ones % 2 == 0:
            even_parity_count += count

    coherence_frac = even_parity_count / total
    print(f"  Coherence test (X-basis even parity):")
    print(f"    Even parity fraction: {coherence_frac:.4f}  (expected 1.0000)")

    coherence_ok = coherence_frac > 0.98
    print(f"    Result: {'PASS' if coherence_ok else 'FAIL'}")
    return coherence_ok


def verify_ghz_full(n: int, shots: int = 20000) -> None:
    """Run all three verification layers on an n-qubit GHZ state."""
    print(f"\n{'='*50}")
    print(f"Full GHZ({n}) Verification ({shots} shots)")
    print(f"{'='*50}")

    # Prepare and measure in computational basis
    prog = core.QProg()
    prog << core.H(0)
    for k in range(1, n):
        prog << core.CNOT(0, k)
    prog << core.measure(list(range(n)), list(range(n)))

    machine = core.CPUQVM()
    machine.run(prog, shots)
    counts = machine.result().get_counts()

    results = []
    results.append(ghz_population_test(counts, n))
    results.append(ghz_parity_test(counts, n))
    results.append(ghz_coherence_test(n, shots))

    print(f"\n  Overall: {'ALL TESTS PASSED' if all(results) else 'SOME TESTS FAILED'}")


# Run verification for several qubit counts
for n in [3, 4, 5]:
    verify_ghz_full(n)

解析

验证协议的工作方式如下:

  • 布居数测试:完美的 GHZ态仅在 |0n|1n 上有支撑。在其他基态中的任何布居都表明存在误差(门误差、退相干或读出误差)。

  • 奇偶性测试:在每个正确的 GHZ态结果中,所有量子比特相同。对于任何相邻对 (i,i+1),测量比特的 XOR 必须为 0。此测试对可能保持布居数不变但破坏纠缠的关联误差敏感。

  • 相干性测试:在测量前施加 Hn 将 GHZ态旋转为所有偶奇偶性计算基态的叠加。对于 3 个量子比特,旋转后的态变为 12(|000+|011+|101+|110)。计算偶奇偶性结果验证 |0n|1n 分量之间的相对相位是否正确。

这三项测试共同捕获不同类型的误差:

  • 比特翻转误差导致布居数和奇偶性测试失败。
  • 相位翻转误差保持布居数和奇偶性不变但无法通过相干性测试。
  • 去极化误差导致所有三项测试失败。

Mermin 不等式测试

问题

Mermin 不等式为真正的多方非局域性提供了 Bell 型测试。对于 3 量子比特系统,局域隐变量理论约束 Mermin算子满足 |M|2,而量子力学预测 GHZ态的 |M|=4 -- 最大违背因子为 2。

如何使用 pyqpanda3 进行实验测量?

Mermin算子

对于 3 个量子比特,Mermin算子为:

M=XXXXYYYXYYYX

每一项需要测量不同组合的 Pauli可观测量。关键洞察是:

  • X 测量需要在计算基测量前施加 H
  • Y 测量需要施加 SH(或等效地 HS)。

GHZ态上的期望值为:

  • XXX=+1
  • XYY=1
  • YXY=1
  • YYX=1

得到 M=1(1)(1)(1)=4

代码:在 X 和 Y 基中测量 Mermin算子

python
from pyqpanda3 import core
import numpy as np


def measure_pauli_term(
    n: int,
    basis: str,
    shots: int = 50000,
    noise: core.NoiseModel = None,
) -> float:
    """Measure the expectation value of a Pauli string on the GHZ state.

    Args:
        n: number of qubits (e.g., 3).
        basis: Pauli basis string, e.g., "XXY" (one char per qubit).
               'X' = measure in X basis, 'Y' = measure in Y basis,
               'Z' = measure in Z (computational) basis.
        shots: number of measurement shots.
        noise: optional noise model for realistic simulation.

    Returns:
        Expectation value <basis> in range [-1, +1].
    """
    assert len(basis) == n, f"Basis length {len(basis)} != n qubits {n}"

    prog = core.QProg()
    # Prepare GHZ state
    prog << core.H(0)
    for k in range(1, n):
        prog << core.CNOT(0, k)

    # Basis rotation: apply gates so that measuring in Z gives X or Y observable
    for i, pauli in enumerate(basis):
        if pauli == "X":
            prog << core.H(i)
        elif pauli == "Y":
            prog << core.S(i)       # S = phase gate (S dagger equivalent via sign)
            prog << core.H(i)
        # 'Z' needs no rotation

    prog << core.measure(list(range(n)), list(range(n)))

    machine = core.CPUQVM()
    if noise is not None:
        machine.run(prog, shots, model=noise)
    else:
        machine.run(prog, shots)
    counts = machine.result().get_counts()

    # Compute expectation: parity-weighted average
    total = sum(counts.values())
    expectation = 0.0
    for outcome, count in counts.items():
        # Count parity of measured bits
        parity = sum(int(b) for b in outcome) % 2
        sign = (-1) ** parity
        expectation += sign * count
    expectation /= total
    return expectation


def mermin_test_3qubit(shots: int = 50000, noise: core.NoiseModel = None) -> None:
    """Run the Mermin inequality test on a 3-qubit GHZ state.

    M = +XXX - XYY - YXY - YYX
    Classical bound: |<M>| <= 2
    Quantum prediction: <M> = 4
    """
    terms = [
        (+1.0, "XXX"),
        (-1.0, "XYY"),
        (-1.0, "YXY"),
        (-1.0, "YYX"),
    ]

    print(f"Mermin Inequality Test (3-qubit GHZ, {shots} shots)")
    print(f"{'Term':>8s}  {'Expectation':>12s}  {'Contribution':>13s}")
    print("-" * 40)

    mermin_value = 0.0
    for coeff, pauli_str in terms:
        exp_val = measure_pauli_term(3, pauli_str, shots=shots, noise=noise)
        contribution = coeff * exp_val
        mermin_value += contribution
        print(f"{pauli_str:>8s}  {exp_val:>12.6f}  {contribution:>13.6f}")

    print(f"\nMermin operator <M> = {mermin_value:.6f}")
    print(f"Classical bound:     |<M>| <= 2")
    print(f"Quantum prediction:  <M> = 4")
    print(f"Violation ratio:     {mermin_value / 2:.4f}")

    if abs(mermin_value) > 2:
        print(f"RESULT: Mermin inequality VIOLATED (|<M>| = {abs(mermin_value):.4f} > 2)")
    else:
        print(f"RESULT: No violation (|<M>| = {abs(mermin_value):.4f} <= 2)")


# Ideal (noiseless) test
print("=" * 50)
print("IDEAL (noiseless) Mermin test")
print("=" * 50)
mermin_test_3qubit(shots=50000)

# Test under depolarizing noise
print("\n" + "=" * 50)
print("NOISY Mermin test (1% depolarizing)")
print("=" * 50)
noise = core.NoiseModel()
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]
)
noise.add_quantum_error(
    core.depolarizing_error(0.01), core.GateType.H, [2]
)
noise.add_quantum_error(
    core.depolarizing_error(0.01), core.GateType.CNOT, [0, 1]
)
noise.add_quantum_error(
    core.depolarizing_error(0.01), core.GateType.CNOT, [0, 2]
)
mermin_test_3qubit(shots=50000, noise=noise)

解析

Mermin 测试通过独立测量每个 Pauli项来工作:

  1. 基旋转:要在量子比特上测量 X,在计算基测量前施加 H。要测量 Y,施加 SH。这将 X(或 Y)的本征态映射到 Z 的本征态。

  2. 奇偶性计算:旋转后,每次采样产生一个比特串。本征值 +1 对应偶奇偶性(偶数个 1),1 对应奇奇偶性。期望值是奇偶性加权平均。

  3. 违背的显著性:经典界限 2 来自任何局域隐变量理论。量子力学达到 4,因为 GHZ态具有任何经典系统都无法复现的关联性。即使是中等噪声(1% 去极化)也会降低违背程度,这说明了为什么在真实硬件上进行 Bell 测试时错误缓解至关重要。


GHZ态在噪声下的保真度退化

问题

去极化噪声如何随着量子比特数量增加而影响 GHZ态质量?由于 GHZ态电路使用级联的 n1 个 CNOT 门,误差会累积。理解这种标度行为对于确定近中期硬件上最大可行 GHZ规模至关重要。

去极化噪声下的保真度

单量子比特上的去极化信道以概率 p 将态替换为最大混合态,以概率 1p 保持不变:

E(ρ)=(1p)ρ+p3(XρX+YρY+ZρZ)

对于 GHZ态,保真度近似衰减为:

F(14p3)n1

其中 n1 是 CNOT 门数。这种指数衰减意味着即使适度的单门误差率,在没有纠错的情况下也会使大规模 GHZ态变得不切实际。

代码:扫描 GHZ态保真度 vs. 量子比特数(噪声下)

python
from pyqpanda3 import core
import numpy as np


def ghz_fidelity(n: int, noise: core.NoiseModel, shots: int = 10000) -> float:
    """Estimate GHZ fidelity via sampling.

    Fidelity is estimated as the fraction of shots in |000...0> or |111...1>.
    This is a lower bound on the true fidelity (does not account for
    coherent errors or phase damping that preserves populations).
    """
    prog = core.QProg()
    prog << core.H(0)
    for k in range(1, n):
        prog << core.CNOT(0, k)
    prog << core.measure(list(range(n)), list(range(n)))

    machine = core.CPUQVM()
    machine.run(prog, shots, model=noise)
    counts = machine.result().get_counts()

    all_zeros = "0" * n
    all_ones = "1" * n
    total = sum(counts.values())
    ghz_count = counts.get(all_zeros, 0) + counts.get(all_ones, 0)
    return ghz_count / total


def ghz_exact_fidelity(n: int, noise: core.NoiseModel) -> float:
    """Compute exact GHZ fidelity F = <GHZ_n|rho|GHZ_n> via density matrix."""
    prog = core.QProg()
    prog << core.H(0)
    for k in range(1, n):
        prog << core.CNOT(0, k)

    dm_sim = core.DensityMatrixSimulator()
    dm_sim.run(prog, model=noise)
    rho = dm_sim.density_matrix()

    dim = 2 ** n
    ghz_vec = np.zeros(dim, dtype=complex)
    ghz_vec[0] = 1.0 / np.sqrt(2)
    ghz_vec[dim - 1] = 1.0 / np.sqrt(2)

    fidelity = float(np.real(ghz_vec.conj() @ rho @ ghz_vec))
    return fidelity


# Sweep: GHZ fidelity vs. qubit count at fixed noise strength
noise_rate = 0.02  # 2% depolarizing error per gate
qubit_range = range(2, 9)  # 2 to 8 qubits

print(f"GHZ Fidelity vs. Qubit Count (depolarizing error = {noise_rate:.0%})")
print(f"{'Qubits':>7s}  {'CNOTs':>6s}  {'Exact F':>10s}  {'Sampled F':>10s}  {'Theoretical':>12s}")
print("-" * 55)

for n in qubit_range:
    noise = core.NoiseModel()
    for q in range(n):
        noise.add_quantum_error(
            core.depolarizing_error(noise_rate), core.GateType.H, [q]
        )
    for k in range(1, n):
        noise.add_quantum_error(
            core.depolarizing_error(noise_rate), core.GateType.CNOT, [0, k]
        )

    exact_fid = ghz_exact_fidelity(n, noise)
    sampled_fid = ghz_fidelity(n, noise, shots=20000)
    # Theoretical approximation: (1 - 4p/3)^(n-1) * (1 - 4p/3) for the Hadamard
    theoretical = ((1 - 4 * noise_rate / 3) ** n)

    num_cnots = n - 1
    print(f"{n:>7d}  {num_cnots:>6d}  {exact_fid:>10.6f}  {sampled_fid:>10.4f}  {theoretical:>12.6f}")

# Sweep: Fidelity vs. noise strength for a fixed qubit count
print(f"\n\nGHZ(4) Fidelity vs. Noise Strength")
print(f"{'Error rate':>12s}  {'Exact F':>10s}  {'Purity':>10s}")
print("-" * 37)

n = 4
for p in [0.0, 0.005, 0.01, 0.02, 0.03, 0.05, 0.08, 0.10, 0.15, 0.20]:
    noise = core.NoiseModel()
    if p > 0:
        for q in range(n):
            noise.add_quantum_error(
                core.depolarizing_error(p), core.GateType.H, [q]
            )
        for k in range(1, n):
            noise.add_quantum_error(
                core.depolarizing_error(p), core.GateType.CNOT, [0, k]
            )

    prog = core.QProg()
    prog << core.H(0)
    for k in range(1, n):
        prog << core.CNOT(0, k)

    dm_sim = core.DensityMatrixSimulator()
    dm_sim.run(prog, model=noise)
    rho = dm_sim.density_matrix()
    fidelity = ghz_exact_fidelity(n, noise)
    purity = float(np.trace(rho @ rho).real)

    print(f"{p:>12.3f}  {fidelity:>10.6f}  {purity:>10.6f}")

解析

扫描揭示了几个重要模式:

量子比特数CNOT 门数2% 误差下的保真度
21~0.97
32~0.95
43~0.92
54~0.89
65~0.86
76~0.83
87~0.80

主要观察:

  1. 线性门数量,指数保真度损失:每增加一个量子比特添加一个 CNOT,保真度损失复合增长。在 2% 误差下,从 2 个量子比特增加到 8 个量子比特将保真度从 97% 降低到约 80%。

  2. 采样 vs. 精确保真度:采样估计(来自测量采样)是真实保真度的下界,因为它只检测布居数误差。破坏相干性但不改变布居数的相位误差对简单计算基测量是不可见的。密度矩阵模拟器给出真实保真度。

  3. 交叉点:在给定误差率下,存在一个最大 GHZ规模,超过该规模态不再有用。对于 2% 去极化噪声,实用极限约为 8 个量子比特(80% 保真度)。超过此规模需要错误缓解或纠错。

  4. 纯度跟踪保真度:纯度 Tr(ρ2) 在去极化噪声下密切跟踪保真度,因为两者都随噪声将纯 GHZ态与最大混合态混合而衰减。


总结

方面详情
态定义|GHZn=12(|0n+|1n)
电路1 个 Hadamard + n1 个 CNOT,深度 n
测量全零或全一,各 50%
关键性质真正的多方纠缠;丢失单个量子比特即失去所有纠缠
验证布居数测试、奇偶性测试、相干性测试(X基)
Mermin 违背3 量子比特的 M=4(经典界限:2)
噪声标度去极化噪声下保真度衰减为 (14p/3)n;2% 误差下实用极限约 8 个量子比特
脆弱性退相干率标度为 nγ;对量子比特数指数敏感
应用量子网络、计量学、秘密共享、纠错

另见

Released under the MIT License.