Estimation de l'énergie de l'état fondamental de la chaîne de Heisenberg avec VQE
Estimation d'utilisation : 37 minutes sur un processeur Heron (REMARQUE : il s'agit d'une estimation uniquement. Ton temps d'exécution peut varier.)
Contexte
Ce tutoriel montre comment construire, déployer et exécuter un workflow de développement appelé patron Qiskit pour simuler une chaîne de Heisenberg et estimer son énergie de l'état fondamental en utilisant l'optimiseur SPSA.
Prérequis
Avant de commencer ce tutoriel, assure-toi que les éléments suivants sont installés :
- Qiskit SDK v2.0 ou version ultérieure, avec le support de visualisation
- Qiskit Runtime v0.44 ou version ultérieure (
pip install qiskit-ibm-runtime)
Configuration
# Added by doQumentation — required packages for this notebook
!pip install -q matplotlib numpy qiskit qiskit-ibm-runtime
import numpy as np
import matplotlib.pyplot as plt
from typing import Sequence
from qiskit import QuantumCircuit
from qiskit.quantum_info import SparsePauliOp
from qiskit.primitives import BaseEstimatorV2
from qiskit.circuit.library import XGate
from qiskit.circuit.library import efficient_su2
from qiskit.transpiler import PassManager
from qiskit.transpiler.preset_passmanagers import generate_preset_pass_manager
from qiskit.transpiler.passes.scheduling import (
ALAPScheduleAnalysis,
PadDynamicalDecoupling,
)
from qiskit_ibm_runtime import QiskitRuntimeService, Session, EstimatorV2
def visualize_results(results):
plt.plot(results["cost_history"], lw=2)
plt.xlabel("Number of function evaluations")
plt.ylabel("Energy")
plt.show()
Étape 1 : Transposer les entrées classiques en un problème quantique
- Entrée : Nombre de spins
- Sortie : Ansatz et hamiltonien modélisant la chaîne de Heisenberg
Construis un ansatz et un hamiltonien qui modélisent une chaîne de Heisenberg à 10 spins. Tout d'abord, nous importons quelques paquets génériques et créons quelques fonctions utilitaires.
num_spins = 10
ansatz = efficient_su2(num_qubits=num_spins, reps=2)
service = QiskitRuntimeService(
channel="ibm_cloud",
token="<YOUR_API_TOKEN>", # Replace with your actual API token
instance="<YOUR_INSTANCE_NAME>", # Replace with your instance name if needed
)
backend = service.least_busy(
operational=True, min_num_qubits=num_spins, simulator=False
)
coupling = backend.target.build_coupling_map()
reduced_coupling = coupling.reduce(list(range(num_spins)))
edge_list = reduced_coupling.graph.edge_list()
ham_list = []
for edge in edge_list:
ham_list.append(("ZZ", edge, 0.5))
ham_list.append(("YY", edge, 0.5))
ham_list.append(("XX", edge, 0.5))
for qubit in reduced_coupling.physical_qubits:
ham_list.append(("Z", [qubit], np.random.random() * 2 - 1))
hamiltonian = SparsePauliOp.from_sparse_list(ham_list, num_qubits=num_spins)
ansatz.draw("mpl", style="iqp")

Étape 2 : Optimiser le problème pour l'exécution sur du matériel quantique
- Entrée : Circuit abstrait, observable
- Sortie : Circuit et observable cibles, optimisés pour le QPU sélectionné
Utilise la fonction generate_preset_pass_manager de Qiskit pour générer automatiquement une routine d'optimisation pour notre circuit par rapport au QPU sélectionné. Nous choisissons optimization_level=3, qui fournit le niveau d'optimisation le plus élevé des gestionnaires de passes prédéfinis. Nous incluons également les passes de planification ALAPScheduleAnalysis et PadDynamicalDecoupling pour supprimer les erreurs de décohérence.
target = backend.target
pm = generate_preset_pass_manager(optimization_level=3, target=target)
pm.scheduling = PassManager(
[
ALAPScheduleAnalysis(durations=target.durations()),
PadDynamicalDecoupling(
durations=target.durations(),
dd_sequence=[XGate(), XGate()],
pulse_alignment=target.pulse_alignment,
),
]
)
isa_ansatz = pm.run(ansatz)
isa_observable = hamiltonian.apply_layout(isa_ansatz.layout)
isa_ansatz.draw("mpl", scale=0.6, style="iqp", fold=-1, idle_wires=False)
