Skip to main content
IBM Quantum Platform


title: "Iniciação rápida" description: "Um guia de início rápido para o complemento Shaded Lightcones do Qiskit (qiskit-addon-slc)"

Iniciação rápida

Este guia apresenta um exemplo mínimo funcional do qiskit-addon-slc pacote. Calculamos um cone de luz sombreado para reduzir o custo de amostragem do cancelamento probabilístico de erros (PEC).

O PEC atenua o ruído de porta por meio da amostragem a partir de uma decomposição em quase-probabilidades do canal de ruído inverso. Seu custo de amostragem aumenta a cada termo de erro que precisa ser mitigado; no entanto, nem todo erro afeta o observável da mesma forma. Um erro fora do cone de luz causal do observável não pode influenciar de forma alguma o valor esperado medido; e, mesmo dentro do cone de luz, alguns erros são mais prejudiciais do que outros. Um cone de luz sombreado quantifica isso ao delimitar o efeito que cada termo de erro de Pauli exerce sobre o observável. O truncamento dos termos de erro com menor efeito reduz o modelo de ruído que o PEC precisa mitigar, diminuindo o custo de amostragem em troca de um viés pequeno e limitado.

Para saber como criar um fluxo de trabalho realista e executá-lo em hardware quântico, confira o tutorial “Cancelamento probabilístico de erros com cones de luz sombreados” no site IBM Quantum Platform.


1. Preparar os dados de entrada para o SLC

Aqui, construímos um circuito de Ising de campo transversal com 6 qubits, submetido ao processo de Trotter, e escolhemos um observável de tipo “ ZZ ” de um único qubit para o qubit do meio.

import numpy as np
from qiskit import QuantumCircuit
from qiskit.quantum_info import Pauli


def trotter_ising_circuit(num_qubits, num_steps, rx_angle, rzz_angle):
    """Trotterized transverse-field Ising evolution on a 1D chain."""
    circuit = QuantumCircuit(num_qubits)
    for _ in range(num_steps):
        circuit.rx(rx_angle, range(num_qubits))
        circuit.barrier()
        for start in (0, 1):  # even then odd bonds
            for i in range(start, num_qubits - 1, 2):
                circuit.rzz(rzz_angle, i, i + 1)
        circuit.barrier()
    return circuit


num_qubits = 6
circuit = trotter_ising_circuit(
    num_qubits, num_steps=2, rx_angle=np.pi / 16, rzz_angle=-np.pi / 2
)

# Measure <Z> on the middle qubit
observable = Pauli("I" * num_qubits).compose("Z", [num_qubits // 2])

print(f"Observable: {observable}")
circuit.draw("mpl", fold=-1, scale=0.7)

Output:

Observable: IIZIII
Output of the previous code cell

O SLC opera nas camadas ruidosas de portas de dois qubits do circuito. Aqui, usamos samplomatic para agrupar as portas em caixas anotadas e atribuímos uma anotação de injeção de ruído a cada camada de dois qubits. generate_noise_model_paulis em seguida, enumera os termos de erro de Pauli de cada camada ruidosa específica.

from qiskit_addon_slc.utils import generate_noise_model_paulis
from samplomatic.transpiler import generate_boxing_pass_manager
from samplomatic.utils import find_unique_box_instructions

# Group gates into boxes and annotate each two-qubit layer with a noise-injection point
boxing_pass = generate_boxing_pass_manager(
    inject_noise_targets="all",
    inject_noise_strategy="individual_modification",
    inject_noise_site="after",
    twirling_strategy="active",
    remove_barriers="never",
)
boxed_circuit = boxing_pass.run(circuit)

# Enumerate the 1- and 2-weight Pauli error terms of each unique noisy layer
noise_model_paulis = generate_noise_model_paulis(
    find_unique_box_instructions(boxed_circuit)
)

num_terms = sum(len(paulis) for paulis in noise_model_paulis.values())
print(f"Noisy layers: {len(noise_model_paulis)}")
print(f"Pauli error terms across all layers: {num_terms}")

Output:

Noisy layers: 2
Pauli error terms across all layers: 102

2. Calcular o cone de luz sombreado

O cone de luz sombreado é construído atribuindo-se uma escala a cada termo de erro de Pauli no modelo de ruído, com base no grau de influência que ele exerce sobre o valor esperado da observável. Essas escalas são derivadas dos limites de erro para a direção direta e para a direção reversa de cada termo de erro (descritos abaixo), bem como de sua taxa de erro:

  • compute_forward_bounds avança cada termo de erro até o final do circuito para limitar seu efeito sobre a grandeza observável medida nesse ponto.
  • compute_backward_bounds evolui cada termo de erro retroativamente até o início do circuito para limitar seu efeito sobre o estado inicial.

merge_bounds combina os dois em um único termo de erro. A fusão das escalas é limitada pela taxa de erro de cada termo. Essas taxas geralmente são obtidas a partir de um experimento de aprendizado com ruído (por exemplo, NoiseLearnerV3); Aqui, utilizamos taxas aleatórias para simplificar.

from qiskit.quantum_info import PauliLindbladMap, QubitSparsePauliList
from qiskit_addon_slc.bounds import (
    compute_backward_bounds,
    compute_forward_bounds,
    merge_bounds,
)

forward_bounds = compute_forward_bounds(
    boxed_circuit, noise_model_paulis, observable
)
backward_bounds = compute_backward_bounds(boxed_circuit, noise_model_paulis)

# Stand-in for rates that would be measured by a noise-learning experiment on hardware
rng = np.random.default_rng(42)
noise_rates = {
    layer_id: PauliLindbladMap.from_components(
        rng.random(len(paulis)) * 5e-3,
        QubitSparsePauliList.from_sparse_list(
            paulis.to_sparse_list(), paulis.num_qubits
        ),
    )
    for layer_id, paulis in noise_model_paulis.items()
}

merged_bounds = merge_bounds(
    boxed_circuit, forward_bounds, backward_bounds, noise_rates
)

Na visualização do cone de luz sombreado abaixo, cada caixa é sombreada de acordo com a intensidade com que os erros naquele ponto podem afetar a grandeza observável: as caixas mais claras representam os limites mais amplos, enquanto as caixas que se desvanecem no fundo contêm termos de erro que têm pouco efeito no cálculo — esses erros são candidatos naturais a serem excluídos do modelo de ruído. Os valores na visualização abaixo representam as somas dos limites de erro de todos os erros de Pauli naquele local; é por isso que alguns dos valores se tornam maiores do que 2.0 — o limite para qualquer erro de Pauli isolado.

from qiskit_addon_slc.visualization import draw_shaded_lightcone

draw_shaded_lightcone(boxed_circuit, merged_bounds, noise_model_paulis)

Output:

Output of the previous code cell

3. Reduzir o custo da amostragem

compute_local_scales transforma o cone de luz sombreado em uma configuração PEC concreta. Ele prioriza os termos de erro de acordo com seu efeito limitado sobre a variável observável e elimina os de menor impacto até que o valor solicitado bias_tolerance seja alcançado. Ele retorna escalas para cada termo de erro — 0.0 para os termos a serem ignorados durante a mitigação e -1.0 para os termos que devem ser mitigados. A função também retorna a sobrecarga de custo de amostragem resultante ( γ2\gamma^2 ) e um limite para o viés residual causado pelo truncamento.

Essa configuração bias_tolerance=0.0 atenua todos os termos de erro dentro do cone de luz causal do observável e fornece um custo de amostragem de referência. Permitir um pequeno viés permite que o SLC descarte os termos de baixo impacto e reduza ainda mais esse custo.

from qiskit_addon_slc.bounds import compute_local_scales

_, full_cost, full_bias = compute_local_scales(
    boxed_circuit, merged_bounds, noise_rates, bias_tolerance=0.0
)
local_scales, reduced_cost, reduced_bias = compute_local_scales(
    boxed_circuit, merged_bounds, noise_rates, bias_tolerance=0.05
)

print(
    f"Full PEC (bias_tolerance=0.0):  sampling cost {full_cost:.3f}, residual bias {full_bias:.3f}"
)
print(
    f"Shaded    (bias_tolerance=0.05): sampling cost {reduced_cost:.3f}, residual bias {reduced_bias:.3f}"
)
print(
    f"\nSampling-cost reduction: {(1 - reduced_cost / full_cost):.0%} for <= 0.05 bias"
)

Output:

Full PEC (bias_tolerance=0.0):  sampling cost 1.923, residual bias 0.000
Shaded    (bias_tolerance=0.05): sampling cost 1.441, residual bias 0.044

Sampling-cost reduction: 25% for <= 0.05 bias
Esta página foi útil?
Relate um bug, erro de digitação ou solicite conteúdo no GitHub.