电路逆变换
许多量子算法需要在同一个电路中使用特定的子例程及其逆过程。Qibo通过qibo.models.circuit.Circuit.invert()方法简化了这一实现。该方法通过对所有门按相反顺序取厄米共轭来生成电路的逆电路。它可以与电路加法结合使用,以简化算法的构建,例如:
In [1]:
Copied!
from qibo import Circuit, gates
# 创建一个子程序
subroutine = Circuit(6)
# 为每个量子比特添加 RX 门,旋转角度为 0.1
subroutine.add([gates.RX(i, theta=0.1) for i in range(5)])
# 为偶数索引的量子比特对添加 CZ 门
subroutine.add([gates.CZ(i, i + 1) for i in range(0, 5, 2)])
# 创建电路的中间部分
middle = Circuit(6)
# 为偶数索引的量子比特对添加 CU2 门,phi 和 lam 参数分别为 0.1 和 0.2
middle.add([gates.CU2(i, i + 1, phi=0.1, lam=0.2) for i in range(0, 5, 2)])
# 创建总电路,由子程序 + 中间部分 + 子程序的逆组成
circuit = subroutine + middle + subroutine.invert()
from qibo import Circuit, gates
# 创建一个子程序
subroutine = Circuit(6)
# 为每个量子比特添加 RX 门,旋转角度为 0.1
subroutine.add([gates.RX(i, theta=0.1) for i in range(5)])
# 为偶数索引的量子比特对添加 CZ 门
subroutine.add([gates.CZ(i, i + 1) for i in range(0, 5, 2)])
# 创建电路的中间部分
middle = Circuit(6)
# 为偶数索引的量子比特对添加 CU2 门,phi 和 lam 参数分别为 0.1 和 0.2
middle.add([gates.CU2(i, i + 1, phi=0.1, lam=0.2) for i in range(0, 5, 2)])
# 创建总电路,由子程序 + 中间部分 + 子程序的逆组成
circuit = subroutine + middle + subroutine.invert()
In [2]:
Copied!
circuit.draw()
circuit.draw()
0: ─RX─o─────o────────────o─RX─ 1: ─RX─Z─────U2───────────Z─RX─ 2: ─RX───o──────o───────o───RX─ 3: ─RX───Z──────U2──────Z───RX─ 4: ─RX─────o───────o──o─────RX─ 5: ────────Z───────U2─Z────────
In [3]:
Copied!
circuit.get_parameters()
circuit.get_parameters()
Out[3]:
[(0.1,), (0.1,), (0.1,), (0.1,), (0.1,), (0.1, 0.2), (0.1, 0.2), (0.1, 0.2), (-0.1,), (-0.1,), (-0.1,), (-0.1,), (-0.1,)]
In [4]:
Copied!
print(circuit().state())
print(circuit().state())
[Qibo 0.2.21|INFO|2025-10-11 17:13:54]: Using qibojit (numba) backend on /CPU:0
[ 9.97746900e-01-1.13973259e-03j -1.76135888e-03+8.96920964e-05j -5.25354206e-03+1.49986683e-02j 1.79234681e-03+3.51978167e-02j -1.72626298e-03+8.93592879e-05j 3.03975537e-06-3.09458653e-07j 7.77634805e-06-2.64117439e-05j -6.18401457e-06-6.07444364e-05j -8.74392672e-03+1.50002009e-02j 1.41186623e-05-2.72503042e-05j -1.79210167e-04-2.10630265e-04j -5.44551837e-04-2.82137896e-04j 1.78569619e-03+3.44964837e-02j -6.18401457e-06-6.07444364e-05j -5.27794609e-04-1.55397334e-04j -1.21387615e-03+1.23577207e-04j -1.72626298e-03+8.93592879e-05j 3.03975537e-06-3.09458653e-07j 7.77634805e-06-2.64117439e-05j -6.18401457e-06-6.07444364e-05j 2.97905944e-06-3.05808948e-07j -5.23246713e-09+8.01680044e-10j -1.11418520e-08+4.63803054e-08j 1.60202373e-08+1.04562120e-07j 1.38154911e-05-2.67200995e-05j -2.20422676e-08+4.83867228e-08j 3.28528373e-07+3.48749338e-07j 9.66927875e-07+4.40477920e-07j -6.11108129e-06-5.95315296e-05j 1.60202373e-08+1.04562120e-07j 9.26832973e-07+2.22651311e-07j 2.08949941e-06-3.20137698e-07j -8.74392672e-03+1.50002009e-02j 1.41186623e-05-2.72503042e-05j -1.79210167e-04-2.10630265e-04j -5.44551837e-04-2.82137896e-04j 1.38154911e-05-2.67200995e-05j -2.20422676e-08+4.83867228e-08j 3.28528373e-07+3.48749338e-07j 9.66927875e-07+4.40477920e-07j -1.48584703e-04-2.63083414e-04j 2.85436129e-07+4.51399803e-07j 4.73813308e-06-8.42951942e-07j 9.02047148e-06-5.70396453e-06j -5.33956582e-04-2.76079526e-04j 9.66927875e-07+4.40477920e-07j 6.96917329e-06-6.56509107e-06j 8.80221588e-06-1.93224394e-05j 1.78569619e-03+3.44964837e-02j -6.18401457e-06-6.07444364e-05j -5.27794609e-04-1.55397334e-04j -1.21387615e-03+1.23577207e-04j -6.11108129e-06-5.95315296e-05j 1.60202373e-08+1.04562120e-07j 9.26832973e-07+2.22651311e-07j 2.08949941e-06-3.20137698e-07j -5.33956582e-04-2.76079526e-04j 9.66927875e-07+4.40477920e-07j 6.96917329e-06-6.56509107e-06j 8.80221588e-06-1.93224394e-05j -1.18963823e-03+1.22119757e-04j 2.08949941e-06-3.20137698e-07j 4.44931474e-06-1.85212097e-05j -6.39741744e-06-4.17551574e-05j]
请注意,电路加法仅在作用于相同数量量子比特的电路之间有效。通常,仅在大型电路的一部分量子比特上添加子程序是很有用的。这可以通过qibo.models.circuit.Circuit.on_qubits()方法实现。例如:
In [ ]:
Copied!
from qibo import Circuit, gates
from qibo.models import QFT
# 创建一个包含4个量子比特的小电路
nqubits = 4
small_circuit = Circuit(nqubits)
# 在每个量子比特上添加RX门,并在第0和第2个量子比特之间添加CNOT门
small_circuit.add((gates.RX(i, theta=0.1) for i in range(4)))
small_circuit.add((gates.CNOT(0, 1), gates.CNOT(2, 3)))
# 创建一个包含8个量子比特的大电路
nqubits = 8
large_circuit = Circuit(nqubits)
# 在偶数量子比特上添加小电路
large_circuit.add(small_circuit.on_qubits(*range(0, nqubits, 2)))
# 在奇数量子比特上添加量子傅里叶变换(QFT)
large_circuit.add(QFT(4).on_qubits(*range(1, nqubits, 2)))
# 在前6个量子比特上添加逆量子傅里叶变换
large_circuit.add(QFT(6).invert().on_qubits(*range(6)))
from qibo import Circuit, gates
from qibo.models import QFT
# 创建一个包含4个量子比特的小电路
nqubits = 4
small_circuit = Circuit(nqubits)
# 在每个量子比特上添加RX门,并在第0和第2个量子比特之间添加CNOT门
small_circuit.add((gates.RX(i, theta=0.1) for i in range(4)))
small_circuit.add((gates.CNOT(0, 1), gates.CNOT(2, 3)))
# 创建一个包含8个量子比特的大电路
nqubits = 8
large_circuit = Circuit(nqubits)
# 在偶数量子比特上添加小电路
large_circuit.add(small_circuit.on_qubits(*range(0, nqubits, 2)))
# 在奇数量子比特上添加量子傅里叶变换(QFT)
large_circuit.add(QFT(4).on_qubits(*range(1, nqubits, 2)))
# 在前6个量子比特上添加逆量子傅里叶变换
large_circuit.add(QFT(6).invert().on_qubits(*range(6)))
In [6]:
Copied!
small_circuit.draw()
small_circuit.draw()
0: ─RX─o─── 1: ─RX─X─── 2: ─RX───o─ 3: ─RX───X─
In [7]:
Copied!
large_circuit.draw()
large_circuit.draw()
0: ─RX─o─────────────────────────────────────x─────────────────────────── ... 1: ────|───H─U1─U1─U1────────────────x─────x─|─────────────────────────── ... 2: ─RX─X─────|──|──|─────────────────|───x─|─|────────────────U1─U1─U1─H─ ... 3: ──────────o──|──|──H─U1─U1────────|─x─x─|─|────────U1─U1─H─|──|──o──── ... 4: ─RX───o──────|──|────|──|─────────|─|───x─|───U1─H─|──o────|──o─────── ... 5: ──────|──────o──|────o──|──H─U1───|─x─────x─H─o────o───────o────────── ... 6: ─RX───X─────────|───────|────|────|─────────────────────────────────── ... 7: ────────────────o───────o────o──H─x─────────────────────────────────── ... 0: ... ──────────────U1─U1─U1─U1─U1─H─ 1: ... U1─U1─U1─U1─H─|──|──|──|──o──── 2: ... |──|──|──o────|──|──|──o─────── 3: ... |──|──o───────|──|──o────────── 4: ... |──o──────────|──o───────────── 5: ... o─────────────o──────────────── 6: ... ─────────────────────────────── 7: ... ───────────────────────────────
In [ ]:
Copied!