反復符号
使用時間の推定: Heronプロセッサで1分未満(注意: これは推定値です。実際の実行時間は異なる場合があります。)
背景
リアルタイム量子誤り訂正(QEC)を可能にするには、実行中に量子プログラムフローを動的に制御できる必要があります。これにより、量子ゲートを測定結果に基づいて条件付けできます。このチュートリアルでは、非常に単純な形式のQECであるビット反転符号を実行します。これは、符号化された量子ビットを単一のビット反転エラーから保護できる動的量子回路を示し、ビット反転符号のパフォーマンス を評価します。
追加のアンシラ量子ビットとエンタングルメントを活用して、符号化された量子情報を変換しないスタビライザーを測定でき、発生した可能性のあるエラーのいくつかのクラスについて通知できます。量子スタビライザー符号は、個の論理量子ビットを個の物理量子ビットに符号化します。スタビライザー符号は、パウリ群からのサポートを受けて離散エラーセットを訂正することに重点を置いています。
QECの詳細については、Quantum Error Correction for Beginners.を参照してください。
要件
このチュートリアルを始める前に、以下がインストールされていることを確認してください:
- Qiskit SDK v2.0以降、visualizationサポート付き
- Qiskit Runtime v0.40以降 (
pip install 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. 古典的な入力を量子問題にマッピング
ビット反転スタビライザー回路を構築
ビット反転符号は、スタビライザー符号の最も単純な例の1つです。符号化量子ビットのいずれかでの単一のビット反転(X)エラーに対して状態を保護します。ビット反転エラーの作用を考えると、これは任意の量子ビットでおよびをマップするため、となります。この符号には5つの量子ビットが必要です。3つは保護された状態を符号化するために使用され、残りの2つはスタビライザー測定アンシラとして使用されます。
# 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)
ステップ2. 量子実行用に問題を最適化
総ジョブ実行時間を短縮するため、Qiskitプリミティブは、ターゲットシステムがサポートする命令と接続性に準拠する回路と観測可能量(命令セットアーキテクチャ(ISA)回路と観測可能量と呼ばれる)のみを受け入れます。トランスパイルの詳細をご覧ください。
ISA回路を生成
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)


no_correction_circuit = build_error_correction_sequence(
apply_correction=False
)
isa_no_correction_circuit = pm.run(no_correction_circuit)