Saltar al contenido principal
Este proyecto está en fase beta. ¿Encontraste un error? Abre un issue en GitHub. ¿Tienes una pregunta o una idea? Pregunta en Discussions — ¡nos encantaría tu opinión!
¿Cómo es la calidad de la traducción en esta página?

Aprende el modelo de ruido de una puerta

Este tutorial muestra cómo aprender un modelo de ruido para una puerta unitaria con un protocolo de aprendizaje estándar accesible mediante las funciones de protocolo de alto nivel prepare_vanilla_program() y process_vanilla_result().

  1. Definir la puerta

  2. Configurar la simulación local

  3. Preparar el programa cuántico

  4. Ejecutar el programa cuántico

  5. Leer los resultados

Ejecución en hardware real

Los circuitos siguientes se simulan localmente, por lo que este recorrido no necesita credenciales de IBM Quantum®. Para ejecutarlo en un dispositivo real:

  • Paso 1: reemplaza FakeMarrakesh por un backend real.

  • Paso 2: pasa ese backend como modo del executor y elimina las opciones del simulador.

1. Definir la puerta​

La puerta es un BoxOp que contiene una capa con twirling de seis puertas CZ disjuntas.

from qiskit.circuit import QuantumCircuit
from qiskit_ibm_runtime.fake_provider import FakeMarrakesh
from samplomatic import InjectNoise, Tag, Twirl

backend = FakeMarrakesh()

cz_pairs = [(91, 92), (93, 94), (95, 99), (98, 111), (112, 113), (114, 115)]

circuit = QuantumCircuit(backend.num_qubits)
with circuit.box([Twirl(), Tag("cz_gate"), InjectNoise("cz_gate")]):
for pair in cz_pairs:
circuit.cz(*pair)
Ejecución en hardware real
from qiskit_ibm_runtime import QiskitRuntimeService

backend = QiskitRuntimeService().backend("ibm_marrakesh")

2. Configurar la simulación local​

Los índices de Pauli dentro de cada mapa son locales a la puerta, en orden ascendente de qubit físico:

cz_qubits = sorted({qubit for pair in cz_pairs for qubit in pair})
local = {qubit: index for index, qubit in enumerate(cz_qubits)}
local
{91: 0,
92: 1,
93: 2,
94: 3,
95: 4,
98: 5,
99: 6,
111: 7,
112: 8,
113: 9,
114: 10,
115: 11}

Define el ruido con un término ZZ correlacionado y un término XX más débil en cada par CZ, además de un término Z de un solo qubit en todas partes; la medición recibe un término de inversión de bit por qubit.

from qiskit.quantum_info import PauliLindbladMap

num_qubits = len(cz_qubits)

cz_noise = PauliLindbladMap.from_sparse_list(
[("ZZ", [local[a], local[b]], 8e-4) for a, b in cz_pairs]
+ [("XX", [local[a], local[b]], 4e-4) for a, b in cz_pairs]
+ [("Z", [index], 3e-4) for index in range(num_qubits)],
num_qubits=num_qubits,
)

readout_noise = PauliLindbladMap.from_sparse_list(
[("X", [index], 5e-3) for index in range(num_qubits)], num_qubits=num_qubits
)

Construye una caja para que la medición aprenda.

measurement = QuantumCircuit(backend.num_qubits, num_qubits)
with measurement.box([Twirl(), Tag("readout"), InjectNoise("readout")]):
for clbit, qubit in enumerate(cz_qubits):
measurement.measure(qubit, clbit)

Cada entrada de layer_noise_model empareja una de esas cajas con el mapa que se le aplica. Usa el método de simulación de estabilizadores y establece seed_simulator para que los datos simulados sean reproducibles.

from qiskit_aer import AerSimulator
from qiskit_ibm_runtime import Executor

executor = Executor(
mode=AerSimulator(method="stabilizer"),
options={
"simulator": {
"layer_noise_model": [
(circuit[0], cz_noise),
(measurement[0], readout_noise),
],
"seed_simulator": 1234,
}
},
)
Ejecución en hardware real
executor = Executor(mode=backend)

3. Prepara el programa cuántico​

Usa prepare_vanilla_program() para construir el programa cuántico que contiene los experimentos de aprendizaje.

from qiskit_noise_learning.protocols import prepare_vanilla_program

program = prepare_vanilla_program(
backend,
[circuit[0], measurement[0]],
fragment_depths=[2, 16, 64, 128],
num_randomizations=50,
shots_per_randomization=20,
)

print(f"Number of template circuits: {len(program.items)}")
Number of template circuits: 5

4. Ejecuta el programa cuántico​

Envía el programa cuántico. Este paso es el mismo tanto si el ejecutor apunta a un simulador como a un dispositivo real.

result = executor.run(program).result()

5. Lee los resultados​

Procesa el resultado con process_vanilla_result().

from qiskit_noise_learning.protocols import process_vanilla_result

noise_maps, gate_names, fit = process_vanilla_result(result)

Grafica los decaimientos de fidelidad por par de qubits: tanto los datos como el ajuste exponencial.

fit.plot_qubit_pair_decays(
pairs=cz_pairs,
observable_type="means",
exponential_fit=True,
)