Lumaktaw sa pangunahing nilalaman

Classical feedforward at control flow (dynamic circuits)

Package versions

Ang code sa pahinang ito ay ginawa gamit ang mga sumusunod na kinakailangan. Inirerekomenda naming gamitin ang mga bersyong ito o mas bago pa.

qiskit[all]~=2.4.0

Ang dynamic circuits ay makapangyarihang mga tool na maaari mong gamitin para sukatin ang mga qubit sa gitna ng pagpapatakbo ng quantum circuit at pagkatapos ay magsagawa ng mga classical logic operation sa loob ng circuit, batay sa resulta ng mga mid-circuit na pagsukat. Ang prosesong ito ay kilala rin bilang classical feedforward. Bagama't maaga pa lamang ang pag-unawa kung paano pinakamabuti na mapagsamantalahan ang dynamic circuits, ang komunidad ng quantum research ay nakakilala na ng ilang mga use case, tulad ng mga sumusunod:

if statement​

Ginagamit ang if statement para magsagawa ng mga operasyon nang kondisyonal batay sa halaga ng isang classical bit o register.

Sa halimbawa sa ibaba, nag-aaplay kami ng Hadamard gate sa isang qubit at sinusukat ito. Kung ang resulta ay 1, nag-aaplay kami ng X gate sa qubit, na may epektong ibabalik ito sa estado na 0. Pagkatapos ay sinusukat namin ang qubit muli. Ang nagreresultang kinalabasan ng pagsukat ay dapat na 0 na may 100% na posibilidad.

# Added by doQumentation β€” required packages for this notebook
!pip install -q qiskit
from qiskit.circuit import QuantumCircuit, QuantumRegister, ClassicalRegister

qubits = QuantumRegister(1)
clbits = ClassicalRegister(1)
circuit = QuantumCircuit(qubits, clbits)
(q0,) = qubits
(c0,) = clbits

circuit.h(q0)
circuit.measure(q0, c0)
with circuit.if_test((c0, 1)):
circuit.x(q0)
circuit.measure(q0, c0)
circuit.draw("mpl")

# example output counts: {'0': 1024}

Output of the previous code cell

Ang with statement ay maaaring bigyan ng assignment target na isa ring context manager na maaaring i-store at pagkatapos ay gamitin para lumikha ng else block, na isinasagawa tuwing ang mga nilalaman ng if block ay hindi isinasagawa.

Sa halimbawa sa ibaba, nagpapasimula kami ng mga register na may dalawang qubit at dalawang classical bit. Nag-aaplay kami ng Hadamard gate sa unang qubit at sinusukat ito. Kung ang resulta ay 1, nag-aaplay kami ng Hadamard gate sa pangalawang qubit; kung hindi, nag-aaplay kami ng X gate sa pangalawang qubit. Sa wakas, sinusukat namin ang pangalawang qubit din.

qubits = QuantumRegister(2)
clbits = ClassicalRegister(2)
circuit = QuantumCircuit(qubits, clbits)
(q0, q1) = qubits
(c0, c1) = clbits

circuit.h(q0)
circuit.measure(q0, c0)
with circuit.if_test((c0, 1)) as else_:
circuit.h(q1)
with else_:
circuit.x(q1)
circuit.measure(q1, c1)

circuit.draw("mpl")

# example output counts: {'01': 260, '11': 272, '10': 492}

Output of the previous code cell

Bukod sa pag-condition sa isang classical bit, posible rin ang pag-condition sa halaga ng isang classical register na binubuo ng maraming bit.

Sa halimbawa sa ibaba, nag-aaplay kami ng Hadamard gate sa dalawang qubit at sinusukat ang mga ito. Kung ang resulta ay 01, iyon ay, ang unang qubit ay 1 at ang pangalawang qubit ay 0, nag-aaplay kami ng X gate sa ikatlong qubit. Sa wakas, sinusukat namin ang ikatlong qubit. Tandaan na para sa kalinawan, pinili naming tukuyin ang estado ng ikatlong classical bit, na 0, sa kondisyon ng if. Sa drawing ng circuit, ang kondisyon ay ipinahiwatig ng mga bilog sa mga classical bit na kina-condition. Ang isang solidong bilog ay nagpapahiwatig ng pag-condition sa 1, habang ang isang bilog na may balangkas ay nagpapahiwatig ng pag-condition sa 0.

qubits = QuantumRegister(3)
clbits = ClassicalRegister(3)
circuit = QuantumCircuit(qubits, clbits)
(q0, q1, q2) = qubits
(c0, c1, c2) = clbits

circuit.h([q0, q1])
circuit.measure(q0, c0)
circuit.measure(q1, c1)
with circuit.if_test((clbits, 0b001)):
circuit.x(q2)
circuit.measure(q2, c2)

circuit.draw("mpl")

# example output counts: {'101': 269, '011': 260, '000': 252, '010': 243}

Output of the previous code cell

Mga classical expression​

Ang Qiskit classical expression module na qiskit.circuit.classical ay naglalaman ng eksplorasyon na representasyon ng mga runtime operation sa mga classical value sa panahon ng pagpapatakbo ng circuit. Dahil sa mga limitasyon ng hardware, ang mga kondisyon ng QuantumCircuit.if_test() lamang ang kasalukuyang sinusuportahan.

Ang sumusunod na halimbawa ay nagpapakita na maaari mong gamitin ang pagkalkula ng parity para lumikha ng n-qubit GHZ state gamit ang dynamic circuits. Una, gumawa ng n/2n/2 Bell pairs sa mga katabing qubit. Pagkatapos, idikit ang mga pares na ito gamit ang isang layer ng CNOT gate sa pagitan ng mga pares. Pagkatapos ay susukat ng mga target qubit ng lahat ng naunang CNOT gate at iri-reset ang bawat nasukat na qubit sa estado ∣0⟩\vert 0 \rangle. Mag-aaplay ka ng XX sa bawat hindi nasukat na site kung saan ang parity ng lahat ng naunang bit ay kakaiba. Sa wakas, mga CNOT gate ang ilalapat sa mga nasukat na qubit para muling maitatag ang entanglement na nawala sa pagsukat.

Sa pagkalkula ng parity, ang unang elemento ng nabuong expression ay kinabibilangan ng pag-lift ng Python object na mr[0] sa isang Value node (lift ay ginagamit para gawing mga classical expression ang mga arbitrary na object). Hindi ito kinakailangan para sa mr[1] at sa posibleng susunod na classical register, dahil sila ay mga input sa expr.bit_xor, at ang anumang kinakailangang pag-lift ay awtomatikong ginagawa sa mga kasong ito. Ang mga ganitong expression ay maaaring itayo sa mga loop at iba pang mga construct.

from qiskit import QuantumCircuit, QuantumRegister, ClassicalRegister
from qiskit.circuit.classical import expr

num_qubits = 8
if num_qubits % 2 or num_qubits < 4:
raise ValueError("num_qubits must be an even integer β‰₯ 4")
meas_qubits = list(range(2, num_qubits, 2)) # qubits to measure and reset

qr = QuantumRegister(num_qubits, "qr")
mr = ClassicalRegister(len(meas_qubits), "m")
qc = QuantumCircuit(qr, mr)

# Create local Bell pairs
qc.reset(qr)
qc.h(qr[::2])
for ctrl in range(0, num_qubits, 2):
qc.cx(qr[ctrl], qr[ctrl + 1])

# Glue neighboring pairs
for ctrl in range(1, num_qubits - 1, 2):
qc.cx(qr[ctrl], qr[ctrl + 1])

# Measure boundary qubits between pairs,reset to 0
for k, q in enumerate(meas_qubits):
qc.measure(qr[q], mr[k])
qc.reset(qr[q])

# Parity-conditioned X corrections
# Each non-measured qubit gets flipped iff the parity (XOR) of all
# preceding measurement bits is 1
for tgt in range(num_qubits):
if tgt in meas_qubits: # skip measured qubits
continue
# all measurement registers whose physical qubit index < tgt
left_bits = [k for k, q in enumerate(meas_qubits) if q < tgt]
if not left_bits: # skip if list empty
continue

# build XOR-parity expression
parity = expr.lift(
mr[left_bits[0]]
) # lift the first bit to Value so it will be treated like a boolean.
for k in left_bits[1:]:
parity = expr.bit_xor(
mr[k], parity
) # calculate parity with all other bits
with qc.if_test(parity): # Add X if parity is 1
qc.x(qr[tgt])

# Re-entangle measured qubits
for ctrl in range(1, num_qubits - 1, 2):
qc.cx(qr[ctrl], qr[ctrl + 1])
qc.draw(output="mpl", style="iqp", idle_wires=False, fold=-1)

Output of the previous code cell

Mga susunod na hakbang​

Mga Rekomendasyon