跳转至

组合子线路,再用逆线路还原

构建一个可复用的旋转子线路,接上它的逆线路,再重复这对操作。先检查顺序,再验证量子比特是否回到初态。先完成参数绑定;这个单量子比特本地实验直接查看概率,不做有限次采样。

假设子线路先执行 RX,再执行 RZ。它的矩阵为 U = RZ(θ/2) RX(θ),因为矩阵从右向左作用于态。逆矩阵为 U† = RX(−θ) RZ(−θ/2),执行顺序是先撤销 RZ,再撤销 RX。对不对易的门序列,只改角度符号、不倒转顺序,通常得不到逆操作。

构建并核对往返操作

"""组合可复用子线路,并验证线路与其 inverse 的往返结果。

``compose`` 把子线路映射到目标 qubit,``inverse`` 和 ``repeat`` 都返回门顺序明确的
新线路。运行前可以先检查变换结构,再用数值结果验证预期。
"""

from __future__ import annotations

import json

from cascaqit import Circuit


def main() -> None:
    """构建一个可复用 rotation,并使用 inverse 抵消它。"""
    rotation = Circuit(("data",), program_id="lesson.digital.subcircuit")
    theta = rotation.parameter("theta", lower_bound=-1.0, upper_bound=1.0)
    rotation.rx(theta, "data").rz(theta / 2, "data")

    declaration = Circuit(("data",), program_id="lesson.digital.compose")
    declaration.compose(rotation).compose(rotation.inverse())
    bound = declaration.repeat(2).bind({"theta": 0.4})
    result = bound.run(shots=0, return_probabilities=True)

    payload = {
        "track": "digital_developer",
        "level": "applied",
        "lesson": "circuit_composition",
        "facts": {
            "gate_count": len(bound.operations),
            "gate_names": [
                operation.definition.name for operation in bound.operations
            ],
            "parameter_names": [item.name for item in bound.parameters],
            "round_trip_probability_0": round((result.probabilities or {})["0"], 12),
            "source_unchanged": not rotation.is_bound,
        },
        "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/03_applied_circuit_composition_zh.py

每次调用 compose() 都向接收者 declaration 中加入操作。inverse()、repeat() 和 bind() 返回另外的线路对象。两份子线路引用兼容的 theta 声明,因此一次绑定能为它们提供同一个角度。名称相同但声明不兼容时,会报错。

{
  "boundaries": {
    "cloud_execution": false,
    "credentials_loaded": false,
    "hardware_execution": false,
    "network_accessed": false
  },
  "facts": {
    "gate_count": 8,
    "gate_names": [
      "rx",
      "rz",
      "rz",
      "rx",
      "rx",
      "rz",
      "rz",
      "rx"
    ],
    "parameter_names": [
      "theta"
    ],
    "round_trip_probability_0": 1.0,
    "source_unchanged": true
  },
  "lesson": "circuit_composition",
  "level": "applied",
  "track": "digital_developer"
}

每次往返有四个操作,重复两次得到八个。gate_names 只列出保存的基础门名,不能代替完整操作语义:是否求逆还记录在操作修饰信息中。仅看名称序列,无法判断哪些操作带有逆操作标记。

由于 U†U 为恒等操作,理想结果为 P(0) = 1。source_unchanged 表示可复用源线路仍含未绑定参数。这能检查复用行为;修改示例时,还应查看源线路的操作是否保持预期。

选择合适的构建方法

方法 用途
append() 加入一个目录中的操作,指定操作对象和参数
compose() 加入整个子线路,可提供完整量子比特映射
inverse() 在测量前,对支持的酉线路倒序求逆
repeat(count) 创建重复副本,支持 1 至 1,024 次

如果要把源线路的命名量子比特放到新的双量子比特线路中,可以写 Circuit(2).compose(rotation, qubit_map={"data": "q1"}),绑定后再执行。映射要覆盖源线路的量子比特,名称不会自动解释为物理位置。

检查推理

  1. 将 .repeat(2) 改为 .repeat(3),预测操作数和 P(0)。
  2. 直接运行 rotation.bind({"theta": 0.4}),不接逆线路,也不重复,计算 P(1)。为什么后面的 RZ 改变相对相位,却不改变 Z 基概率?
  3. 在调用 inverse() 前给 rotation 加上测量,阅读错误,再把测量移到完整线路末尾。
核对思路

三次恒等操作对共有 12 个操作,P(0) 仍为 1。单次 RX(0.4) 给出 P(1) = sin²(0.2) ≈ 0.039470;后续 RZ 只给振幅乘上相位,不改变模长。含测量的线路不能求逆,应先组合酉操作,再在末尾测量。这个例子回到 |0⟩,只验证了一个输入;判断任意两条线路是否等价,不能只看某个输入态的计数。

下一课从同一个末态计算多个可观测量,将检查单一测量基可能看不到的相位信息。

English

SDK 1.0.8a · `6eff6362`