ข้ามไปยังเนื้อหาหลัก

Repetition codes

ประมาณการการใช้งาน: ไม่ถึง 1 นาทีบนโปรเซสเซอร์ Heron (หมายเหตุ: นี่เป็นเพียงการประมาณเท่านั้น เวลาจริงอาจแตกต่างออกไป)

พื้นหลัง

เพื่อให้สามารถแก้ไขข้อผิดพลาดควอนตัม (QEC) แบบเรียลไทม์ได้ คุณจำเป็นต้องควบคุมการไหลของโปรแกรมควอนตัมแบบไดนามิกระหว่างการรัน เพื่อให้ quantum gates สามารถทำงานตามเงื่อนไขของผลการวัดได้ บทแนะนำนี้รัน bit-flip code ซึ่งเป็นรูปแบบ QEC ที่เรียบง่ายมาก โดยแสดงให้เห็น dynamic quantum circuit ที่สามารถป้องกัน qubit ที่เข้ารหัสไว้จากข้อผิดพลาด bit-flip เดี่ยว และประเมินประสิทธิภาพของ bit-flip code

คุณสามารถใช้ประโยชน์จาก ancilla qubits เพิ่มเติมและ entanglement เพื่อวัด stabilizers ที่ไม่เปลี่ยนแปลงข้อมูลควอนตัมที่เข้ารหัสไว้ ขณะที่ยังคงบอกให้คุณทราบถึงข้อผิดพลาดบางประเภทที่อาจเกิดขึ้น quantum stabilizer code เข้ารหัส kk logical qubits ลงใน nn physical qubits Stabilizer codes มุ่งเน้นการแก้ไขชุดข้อผิดพลาดแบบไม่ต่อเนื่องโดยอาศัย Pauli group Πn\Pi^n

สำหรับข้อมูลเพิ่มเติมเกี่ยวกับ QEC ดูได้ที่ Quantum Error Correction for Beginners

ข้อกำหนดเบื้องต้น

ก่อนเริ่มบทแนะนำนี้ ตรวจสอบให้แน่ใจว่าได้ติดตั้งสิ่งต่อไปนี้:

  • Qiskit SDK v2.0 หรือใหม่กว่า พร้อมการรองรับ visualization
  • Qiskit Runtime v0.40 หรือใหม่กว่า (pip install qiskit-ibm-runtime)

การตั้งค่า

# Added by doQumentation — required packages for this notebook
!pip install -q qiskit qiskit-ibm-runtime
# Qiskit imports
from qiskit import (
QuantumCircuit,
QuantumRegister,
ClassicalRegister,
)

# Qiskit Runtime
from qiskit_ibm_runtime import QiskitRuntimeService, SamplerV2 as Sampler

from qiskit_ibm_runtime.circuit import MidCircuitMeasure

service = QiskitRuntimeService()

ขั้นตอนที่ 1 แปลง input แบบ classical เป็นปัญหาควอนตัม

สร้าง bit-flip stabilizer circuit

bit-flip code เป็นหนึ่งในตัวอย่างที่เรียบง่ายที่สุดของ stabilizer code โดยป้องกัน state จากข้อผิดพลาด bit-flip (X) เพียงครั้งเดียวบน qubit ใด ๆ ในการเข้ารหัส พิจารณาการทำงานของ bit-flip error XX ซึ่งแมป 01|0\rangle \rightarrow |1\rangle และ 10|1\rangle \rightarrow |0\rangle บน qubit ใด ๆ ของเรา จะได้ ϵ={E0,E1,E2}={IIX,IXI,XII}\epsilon = \{E_0, E_1, E_2 \} = \{IIX, IXI, XII\} โค้ดนี้ต้องใช้ห้า qubit: สามตัวใช้เข้ารหัส state ที่ถูกป้องกัน และอีกสองตัวที่เหลือใช้เป็น ancilla สำหรับวัด stabilizer

# Choose the least busy backend that supports `measure_2`.

backend = service.least_busy(
filters=lambda b: "measure_2" in b.supported_instructions,
operational=True,
simulator=False,
dynamic_circuits=True,
)
qreg_data = QuantumRegister(3)
qreg_measure = QuantumRegister(2)
creg_data = ClassicalRegister(3, name="data")
creg_syndrome = ClassicalRegister(2, name="syndrome")
state_data = qreg_data[0]
ancillas_data = qreg_data[1:]

def build_qc():
"""Build a typical error correction circuit"""
return QuantumCircuit(qreg_data, qreg_measure, creg_data, creg_syndrome)

def initialize_qubits(circuit: QuantumCircuit):
"""Initialize qubit to |1>"""
circuit.x(qreg_data[0])
circuit.barrier(qreg_data)
return circuit

def encode_bit_flip(circuit, state, ancillas) -> QuantumCircuit:
"""Encode bit-flip. This is done by simply adding a cx"""
for ancilla in ancillas:
circuit.cx(state, ancilla)
circuit.barrier(state, *ancillas)
return circuit

def measure_syndrome_bit(circuit, qreg_data, qreg_measure, creg_measure):
"""
Measure the syndrome by measuring the parity.
We reset our ancilla qubits after measuring the stabilizer
so we can reuse them for repeated stabilizer measurements.
Because we have already observed the state of the qubit,
we can write the conditional reset protocol directly to
avoid another round of qubit measurement if we used
the `reset` instruction.
"""
circuit.cx(qreg_data[0], qreg_measure[0])
circuit.cx(qreg_data[1], qreg_measure[0])
circuit.cx(qreg_data[0], qreg_measure[1])
circuit.cx(qreg_data[2], qreg_measure[1])
circuit.barrier(*qreg_data, *qreg_measure)
circuit.append(MidCircuitMeasure(), [qreg_measure[0]], [creg_measure[0]])
circuit.append(MidCircuitMeasure(), [qreg_measure[1]], [creg_measure[1]])

with circuit.if_test((creg_measure[0], 1)):
circuit.x(qreg_measure[0])
with circuit.if_test((creg_measure[1], 1)):
circuit.x(qreg_measure[1])
circuit.barrier(*qreg_data, *qreg_measure)
return circuit

def apply_correction_bit(circuit, qreg_data, creg_syndrome):
"""We can detect where an error occurred and correct our state"""
with circuit.if_test((creg_syndrome, 3)):
circuit.x(qreg_data[0])
with circuit.if_test((creg_syndrome, 1)):
circuit.x(qreg_data[1])
with circuit.if_test((creg_syndrome, 2)):
circuit.x(qreg_data[2])
circuit.barrier(qreg_data)
return circuit

def apply_final_readout(circuit, qreg_data, creg_data):
"""Read out the final measurements"""
circuit.barrier(qreg_data)
circuit.measure(qreg_data, creg_data)
return circuit
def build_error_correction_sequence(apply_correction: bool) -> QuantumCircuit:
circuit = build_qc()
circuit = initialize_qubits(circuit)
circuit = encode_bit_flip(circuit, state_data, ancillas_data)
circuit = measure_syndrome_bit(
circuit, qreg_data, qreg_measure, creg_syndrome
)

if apply_correction:
circuit = apply_correction_bit(circuit, qreg_data, creg_syndrome)

circuit = apply_final_readout(circuit, qreg_data, creg_data)
return circuit

circuit = build_error_correction_sequence(apply_correction=True)
circuit.draw(output="mpl", style="iqp", cregbundle=False)

Output of the previous code cell

Output of the previous code cell

ขั้นตอนที่ 2 ปรับแต่งปัญหาสำหรับการรันบนควอนตัม

เพื่อลดเวลาการรัน job โดยรวม Qiskit primitives รับเฉพาะ circuit และ observable ที่เป็นไปตามคำสั่งและการเชื่อมต่อที่ระบบเป้าหมายรองรับ (เรียกว่า ISA circuits และ observables) เรียนรู้เพิ่มเติมเกี่ยวกับการ transpile

สร้าง ISA circuits

from qiskit.transpiler.preset_passmanagers import generate_preset_pass_manager

pm = generate_preset_pass_manager(backend=backend, optimization_level=1)
isa_circuit = pm.run(circuit)

isa_circuit.draw("mpl", style="iqp", idle_wires=False)

Output of the previous code cell

Output of the previous code cell

no_correction_circuit = build_error_correction_sequence(
apply_correction=False
)

isa_no_correction_circuit = pm.run(no_correction_circuit)

ขั้นตอนที่ 3 รันด้วย Qiskit primitives

รันเวอร์ชันที่มีการแก้ไขและเวอร์ชันที่ไม่มีการแก้ไข

sampler_no_correction = Sampler(backend)
job_no_correction = sampler_no_correction.run(
[isa_no_correction_circuit], shots=1000
)
result_no_correction = job_no_correction.result()[0]
sampler_with_correction = Sampler(backend)

job_with_correction = sampler_with_correction.run([isa_circuit], shots=1000)
result_with_correction = job_with_correction.result()[0]
print(f"Data (no correction):\n{result_no_correction.data.data.get_counts()}")
print(
f"Syndrome (no correction):\n{result_no_correction.data.syndrome.get_counts()}"
)
Data (no correction):
{'111': 878, '011': 42, '110': 35, '101': 40, '100': 1, '001': 2, '000': 2}
Syndrome (no correction):
{'00': 942, '10': 33, '01': 22, '11': 3}
print(f"Data (corrected):\n{result_with_correction.data.data.get_counts()}")
print(
f"Syndrome (corrected):\n{result_with_correction.data.syndrome.get_counts()}"
)
Data (corrected):
{'111': 889, '110': 25, '000': 11, '011': 45, '101': 17, '010': 10, '001': 2, '100': 1}
Syndrome (corrected):
{'00': 929, '01': 39, '10': 20, '11': 12}

ขั้นตอนที่ 4 ประมวลผลต่อและส่งคืนผลลัพธ์ในรูปแบบ classical

จะเห็นได้ว่า bit flip code ตรวจพบและแก้ไขข้อผิดพลาดได้หลายครั้ง ส่งผลให้ข้อผิดพลาดโดยรวมลดลง

def decode_result(data_counts, syndrome_counts):
shots = sum(data_counts.values())
success_trials = data_counts.get("000", 0) + data_counts.get("111", 0)
failed_trials = shots - success_trials
error_correction_events = shots - syndrome_counts.get("00", 0)
print(
f"Bit flip errors were detected/corrected on {error_correction_events}/{shots} trials."
)
print(
f"A final parity error was detected on {failed_trials}/{shots} trials."
)
# non-corrected marginalized results
data_result = result_no_correction.data.data.get_counts()
marginalized_syndrome_result = result_no_correction.data.syndrome.get_counts()

print(
f"Completed bit code experiment data measurement counts (no correction): {data_result}"
)
print(
f"Completed bit code experiment syndrome measurement counts (no correction): {marginalized_syndrome_result}"
)
decode_result(data_result, marginalized_syndrome_result)
Completed bit code experiment data measurement counts (no correction): {'111': 878, '011': 42, '110': 35, '101': 40, '100': 1, '001': 2, '000': 2}
Completed bit code experiment syndrome measurement counts (no correction): {'00': 942, '10': 33, '01': 22, '11': 3}
Bit flip errors were detected/corrected on 58/1000 trials.
A final parity error was detected on 120/1000 trials.
# corrected marginalized results
corrected_data_result = result_with_correction.data.data.get_counts()
corrected_syndrome_result = result_with_correction.data.syndrome.get_counts()

print(
f"Completed bit code experiment data measurement counts (corrected): {corrected_data_result}"
)
print(
f"Completed bit code experiment syndrome measurement counts (corrected): {corrected_syndrome_result}"
)
decode_result(corrected_data_result, corrected_syndrome_result)
Completed bit code experiment data measurement counts (corrected): {'111': 889, '110': 25, '000': 11, '011': 45, '101': 17, '010': 10, '001': 2, '100': 1}
Completed bit code experiment syndrome measurement counts (corrected): {'00': 929, '01': 39, '10': 20, '11': 12}
Bit flip errors were detected/corrected on 71/1000 trials.
A final parity error was detected on 100/1000 trials.

แบบสำรวจบทแนะนำ

กรุณาทำแบบสำรวจสั้น ๆ นี้เพื่อให้ข้อเสนอแนะเกี่ยวกับบทแนะนำนี้ ความคิดเห็นของคุณจะช่วยให้เราปรับปรุงเนื้อหาและประสบการณ์การใช้งานได้ดียิ่งขึ้น

ลิงก์ไปยังแบบสำรวจ

Note: This survey is provided by IBM Quantum and relates to the original English content. To give feedback on doQumentation's website, translations, or code execution, please open a GitHub issue.

Source: IBM Quantum docs — updated 27 เม.ย. 2569
English version on doQumentation — updated 7 พ.ค. 2569
This translation based on the English version of 9 เม.ย. 2569