组合子线路,再用逆线路还原¶
构建一个可复用的旋转子线路,接上它的逆线路,再重复这对操作。先检查顺序,再验证量子比特是否回到初态。先完成参数绑定;这个单量子比特本地实验直接查看概率,不做有限次采样。
假设子线路先执行 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"}),绑定后再执行。映射要覆盖源线路的量子比特,名称不会自动解释为物理位置。
检查推理¶
- 将
.repeat(2)改为.repeat(3),预测操作数和P(0)。 - 直接运行
rotation.bind({"theta": 0.4}),不接逆线路,也不重复,计算P(1)。为什么后面的 RZ 改变相对相位,却不改变 Z 基概率? - 在调用
inverse()前给rotation加上测量,阅读错误,再把测量移到完整线路末尾。
核对思路
三次恒等操作对共有 12 个操作,P(0) 仍为 1。单次 RX(0.4) 给出 P(1) = sin²(0.2) ≈ 0.039470;后续 RZ 只给振幅乘上相位,不改变模长。含测量的线路不能求逆,应先组合酉操作,再在末尾测量。这个例子回到 |0⟩,只验证了一个输入;判断任意两条线路是否等价,不能只看某个输入态的计数。
下一课从同一个末态计算多个可观测量,将检查单一测量基可能看不到的相位信息。