跳转至

第一个 Bell 线路

这次实验准备两个量子比特,测量它们,再读取运行结果。你会看到:即使线路不变,每次采样得到的频率也可能不同。

先完成安装,在仓库根目录运行下面的命令。实验使用两个量子比特和 32 次采样,在本地 CPU 上运行。

先预测会测到什么

两个量子比特最初都处于 0 状态。对第 0 个量子比特施加 H 门,使它进入叠加态。随后执行 CX 门:当第 0 个量子比特为 1 时,翻转第 1 个量子比特。两步操作准备出 Bell 态:

(|00⟩ + |11⟩) / √2

在这个基上进行理想测量,00 和 11 的概率各为 1/2。运行前想一想:采样 32 次,是否一定会各得到 16 次?

构建并运行线路

下面的源码也是课程自动检查时运行的文件。measure_all(key="readout") 为测量寄存器命名。一个 shot 表示从输出分布中采样一次,seed 用于控制伪随机采样。

"""构建 Bell 线路并解释本地采样结果。

示例使用链式 ``Circuit`` API 添加量子门和终端测量。读取 counts 时要同时查看
bit order,否则无法判断 bitstring 的每一位对应哪个量子比特。
"""

from __future__ import annotations

import json

from cascaqit import Circuit


def main() -> None:
    """使用固定随机种子执行一个两量子比特纠缠线路。"""
    # H 门创建叠加态,CX 门让 q1 与 q0 产生关联。
    circuit = Circuit(2, program_id="lesson.digital.beginner")
    circuit.h(0).cx(0, 1).measure_all(key="readout")

    # 对第一次 Digital 实验而言,Circuit.run 是最短的本地执行路径。
    result = circuit.run(shots=32, seed=201, return_probabilities=True)
    program = circuit.to_program()

    payload = {
        "track": "digital_developer",
        "level": "beginner",
        "lesson": "bell_circuit",
        "facts": {
            "gate_names": [
                operation.definition.name
                for operation in program.circuit.operations
                if operation.definition.name != "measure"
            ],
            "counts_total": sum(result.counts.values()),
            "probability_states": sorted((result.probabilities or {}).keys()),
            "bit_order": result.metadata["bitstring_ordering"]["qubit_order"],
            "measurement_key": program.circuit.classical_registers[0].register_id,
        },
        "boundaries": {
            "hardware_execution": False,
            "cloud_execution": False,
            "network_accessed": False,
            "credentials_loaded": False,
        },
    }
    print(json.dumps(payload, sort_keys=True))


if __name__ == "__main__":
    main()

下载完整脚本

python3 examples/user/tracks/digital_developer/01_beginner_bell_circuit_zh.py

脚本打印一个 JSON 对象,先阅读 facts:

{
  "boundaries": {
    "cloud_execution": false,
    "credentials_loaded": false,
    "hardware_execution": false,
    "network_accessed": false
  },
  "facts": {
    "bit_order": [
      "q0",
      "q1"
    ],
    "counts_total": 32,
    "gate_names": [
      "h",
      "x"
    ],
    "measurement_key": "readout",
    "probability_states": [
      "00",
      "01",
      "10",
      "11"
    ]
  },
  "lesson": "bell_circuit",
  "level": "beginner",
  "track": "digital_developer"
}
字段 要检查什么
gate_names 应为 ["h", "x"];受控 X 操作保存的门名为 x,控制信息记录在操作对象中
counts_total 是否等于指定的 32 次采样
probability_states 概率结果中记录了哪些状态;判断概率时还要看数值,不能只看键是否存在
bit_order 字符串的每一位对应哪个量子比特
measurement_key 是否为刚才指定的寄存器名 readout

boundaries 说明这次运行使用本地模拟。它不是错误提示,也不表示你还需要配置云账户。

查看实际采样计数

课程脚本默认只打印摘要。若要查看计数,在本地副本的 result = circuit.run(...) 后加入 print(result.counts)。再加入 print(result.probabilities),对比采样频率与理想概率。

计数总和应为 32,但不必恰好各占 16 次。重复测量不会改变理想概率分布,只会从这个分布中重新采样。固定 seed 有助于在相同环境中重复实验;不要把某组采样整数视为跨版本保证。

00 和 11 的计数说明两个量子比特在这个测量基上有关联。但仅凭这些计数,无法区分 Bell 态和经典混合态;研究相干性还需要考虑其他测量基。另外,这个对称例子本身也不能暴露位序是否颠倒,仍要读取位序元数据。

改两个条件试试

  1. 把 shots 从 32 改为 1,000,对比采样频率与 1/2 的差距。差距是否变小?换几个 seed 再判断。
  2. 去掉 .cx(0, 1),保留 H 门和测量。现在只有哪个量子比特可能变化?结合 bit_order 解释输出字符串。
核对思路

增加 shots 通常会减小相对采样波动,但不能保证任意两次运行都恰好如此。去掉 CX 后,只有第 0 个量子比特进入叠加态,第 1 个仍为 0。读取记录的位序,判断它在字符串中的位置。

接下来学习参数绑定。如果想保存可交互的结果图,继续看实验报告。

English

SDK 1.0.8a · `8b227bff`