Skip to main content
IBM Quantum Platform

Códigos de repetição

Estimativa de uso: menos de 1 minuto em um processador Heron (OBSERVAÇÃO: essa é apenas uma estimativa. Seu tempo de execução pode variar)


Segundo plano

Para permitir a correção de erros quânticos (QEC) em tempo real, você precisa ser capaz de controlar dinamicamente o fluxo do programa quântico durante a execução, de modo que as portas quânticas possam ser condicionadas aos resultados da medição. Este tutorial executa o código bit-flip, que é uma forma muito simples de QEC. Ele demonstra um circuito quântico dinâmico que pode proteger um qubit codificado de um único erro de inversão de bit e, em seguida, avalia o desempenho do código de inversão de bit.

Você pode explorar qubits ancilla adicionais e emaranhamento para medir estabilizadores que não transformam as informações quânticas codificadas e, ao mesmo tempo, informá-lo sobre algumas classes de erros que podem ter ocorrido. Um código estabilizador quântico codifica kk qubits lógicos em nn qubits físicos. Os códigos estabilizadores se concentram criticamente na correção de um conjunto de erros discretos com o apoio do grupo Pauli Πn\Pi^n.

Para obter mais informações sobre a QEC, consulte “Correção de erros quânticos para iniciantes”.


Requisitos

Antes de iniciar este tutorial, verifique se você tem os seguintes itens instalados:

  • Qiskit SDK v2.0 ou posterior, com suporte para visualização
  • Qiskit Runtime v0.40 ou posterior (pip install qiskit-ibm-runtime)

Instalação

# 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()

Etapa 1. Mapeie entradas clássicas para um problema quântico

Construa um circuito estabilizador de inversão de bits

O código bit-flip está entre os exemplos mais simples de um código estabilizador. Ele protege o estado contra um único erro de inversão de bit (X) em qualquer um dos qubits de codificação. Considere a ação do erro de inversão de bit XX, que mapeia 01|0\rangle \rightarrow |1\rangle e 10|1\rangle \rightarrow |0\rangle em qualquer um de nossos qubits, então temos ϵ={E0,E1,E2}={IIX,IXI,XII}\epsilon = \{E_0, E_1, E_2 \} = \{IIX, IXI, XII\}. O código requer cinco qubits: três são usados para codificar o estado protegido e os dois restantes são usados como auxiliares de medição do estabilizador.

# 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:

Output of the previous code cell Output of the previous code cell

Etapa 2. Otimize o problema para execução quântica

Para reduzir o tempo total de execução da tarefa, o Qiskit primitives aceita apenas circuitos e observáveis que estejam em conformidade com as instruções e a conectividade suportadas pelo sistema de destino (conhecidos como circuitos e observáveis da arquitetura de conjunto de instruções (ISA)). Saiba mais sobre transpilação.

Gerar circuitos 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)

Output:

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)

Etapa 3. Execute usando Qiskit primitives

Execute a versão com correção aplicada e uma sem correção.

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()}"
)

Output:

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()}"
)

Output:

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}

Etapa 4. Pós-processamento, retornar resultado no formato clássico

Você pode ver que o código de inversão de bits detectou e corrigiu muitos erros, resultando em menos erros em geral.

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 "
        f"{error_correction_events}/{shots} trials."
    )
    print(
        f"A final parity error was detected on "
        f"{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): "
    f"{data_result}"
)
print(
    f"Completed bit code experiment syndrome measurement counts (no correction): "
    f"{marginalized_syndrome_result}"
)
decode_result(data_result, marginalized_syndrome_result)

Output:

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): "
    f"{corrected_data_result}"
)
print(
    f"Completed bit code experiment syndrome measurement counts (corrected): "
    f"{corrected_syndrome_result}"
)
decode_result(corrected_data_result, corrected_syndrome_result)

Output:

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.

Pesquisa tutorial

Responda a esta breve pesquisa para fornecer feedback sobre este tutorial. Suas percepções nos ajudarão a melhorar nossas ofertas de conteúdo e a experiência do usuário.

Link para a pesquisa

Esta página foi útil?
Relate um bug, erro de digitação ou solicite conteúdo no GitHub.