Aller au contenu principal
Ce projet est en phase bêta. Tu as trouvé un bug ? Ouvrir un ticket GitHub. Une question ou une idée ? Pose ta question dans Discussions — tes retours sont les bienvenus !
Quelle est la qualité de la traduction sur cette page ?

Apprendre le modèle de bruit d'une porte

Ce tutoriel montre comment apprendre un modèle de bruit pour une porte unitaire avec un protocole d'apprentissage standard accessible via les fonctions de protocole de haut niveau prepare_vanilla_program() et process_vanilla_result().

  1. Définir la porte

  2. Configurer la simulation locale

  3. Préparer le programme quantique

  4. Exécuter le programme quantique

  5. Lire les résultats

Exécution sur du matériel réel

Les circuits ci-dessous sont simulés localement, donc ce pas à pas ne nécessite aucun identifiant IBM Quantum®. Pour l'exécuter plutôt sur un appareil réel :

  • Étape 1 : remplace FakeMarrakesh par un vrai backend.

  • Étape 2 : passe ce backend comme mode de l'executor, et supprime les options du simulateur.

1. Définir la porte​

La porte est un BoxOp contenant une couche twirlée de six portes CZ disjointes.

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)
Exécution sur du matériel réel
from qiskit_ibm_runtime import QiskitRuntimeService

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

2. Configurer la simulation locale​

Les indices de Pauli à l'intérieur de chaque map sont locaux à la porte, dans l'ordre croissant des qubits physiques :

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}

Définis le bruit avec un terme ZZ corrélé et un terme XX plus faible sur chaque paire CZ, plus un terme Z à un seul qubit partout ; la mesure reçoit un terme de bit-flip par 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
)

Construis une boîte que la mesure doit apprendre.

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)

Chaque entrée de layer_noise_model associe une de ces boîtes à la map à lui appliquer. Utilise la méthode de simulation stabilizer et définis seed_simulator pour rendre les données simulées reproductibles.

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,
}
},
)
Exécution sur du matériel réel
executor = Executor(mode=backend)

3. Préparer le programme quantique​

Utilise prepare_vanilla_program() pour construire le programme quantique contenant les expériences d'apprentissage.

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. Exécuter le programme quantique​

Soumets le programme quantique. Cette étape est la même que l'executor pointe vers un simulateur ou vers un appareil réel.

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

5. Lire les résultats​

Traite le résultat avec process_vanilla_result().

from qiskit_noise_learning.protocols import process_vanilla_result

noise_maps, gate_names, fit = process_vanilla_result(result)

Trace les décroissances de fidélité par paire de qubits : à la fois les données et l'ajustement exponentiel.

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