주 콘텐츠로 건너뛰기

반복 코드

사용 예상 시간: Heron 프로세서에서 1분 미만 (참고: 이는 추정치일 뿐이며, 실제 실행 시간은 다를 수 있습니다.)

배경

실시간 양자 오류 정정(QEC)을 구현하려면, 측정 결과에 따라 양자 게이트를 조건부로 실행할 수 있도록 실행 중에 양자 프로그램의 흐름을 동적으로 제어할 수 있어야 합니다. 이 튜토리얼은 비트 반전 코드(bit-flip code)를 실행하며, 이는 매우 간단한 형태의 QEC입니다. 인코딩된 Qubit을 단일 비트 반전 오류로부터 보호할 수 있는 동적 양자 Circuit을 시연하고, 비트 반전 코드의 성능을 평가합니다.

추가 앤실라(ancilla) Qubit과 얽힘을 활용하여 인코딩된 양자 정보를 변환하지 않으면서도 발생했을 수 있는 특정 종류의 오류를 알려주는 *스태빌라이저(stabilizer)*를 측정할 수 있습니다. 양자 스태빌라이저 코드는 kk개의 논리 Qubit을 nn개의 물리 Qubit으로 인코딩합니다. 스태빌라이저 코드는 파울리 그룹 Πn\Pi^n을 지원하는 이산 오류 집합의 수정에 핵심적으로 집중합니다.

QEC에 대한 자세한 내용은 Quantum Error Correction for Beginners를 참고하세요.

요구 사항

이 튜토리얼을 시작하기 전에 다음이 설치되어 있는지 확인하세요:

  • Qiskit SDK v2.0 이상, 시각화 지원 포함
  • 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단계. 고전적 입력을 양자 문제로 변환

비트 반전 스태빌라이저 Circuit 구축

비트 반전 코드는 스태빌라이저 코드의 가장 간단한 예 중 하나입니다. 이 코드는 인코딩 Qubit 중 어느 하나에 대한 단일 비트 반전(X) 오류로부터 상태를 보호합니다. 01|0\rangle \rightarrow |1\rangle10|1\rangle \rightarrow |0\rangle으로 매핑하는 비트 반전 오류 XX의 작용을 고려하면, ϵ={E0,E1,E2}={IIX,IXI,XII}\epsilon = \{E_0, E_1, E_2 \} = \{IIX, IXI, XII\}가 됩니다. 이 코드는 다섯 개의 Qubit이 필요합니다: 세 개는 보호할 상태를 인코딩하는 데 사용되고, 나머지 두 개는 스태빌라이저 측정 앤실라로 사용됩니다.

# 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단계. 양자 실행을 위한 문제 최적화

총 작업 실행 시간을 줄이기 위해, Qiskit 프리미티브는 대상 시스템이 지원하는 명령어 및 연결성에 맞는 Circuit과 옵저버블만 허용합니다(명령어 집합 아키텍처(ISA) Circuit 및 옵저버블이라고 합니다). 트랜스파일에 대해 더 알아보기.

ISA Circuit 생성

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 프리미티브를 사용하여 실행

정정이 적용된 버전과 정정이 없는 버전을 실행합니다.

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단계. 후처리, 고전적 형식으로 결과 반환

비트 반전 코드가 많은 오류를 감지하고 정정하여 전체적으로 오류가 줄어든 것을 확인할 수 있습니다.

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.