Aller au contenu principal

Démarrage rapide avec Estimator

La primitive Estimator calcule les valeurs d'espérance pour un ou plusieurs observables par rapport aux états préparés par des circuits quantiques. Les circuits peuvent être paramétrés, à condition que les valeurs des paramètres soient également fournies en entrée à la primitive.

Cette primitive dispose de plusieurs techniques intégrées d'atténuation et de suppression d'erreurs incluant le découplage dynamique, le twirling de Pauli, le ZNE par repliement de gate, le PEA et le PEC. Elle prend également en charge une option resilience_level qui te permet de configurer facilement le compromis coût-précision. Les étapes de ce sujet décrivent comment configurer Estimator, explorer les options que tu peux utiliser pour le configurer et l'invoquer dans un programme.

Versions des packages

Le code sur cette page a été développé en utilisant les exigences suivantes. Nous recommandons d'utiliser ces versions ou des versions plus récentes.

qiskit[all]~=2.5.2
qiskit-ibm-runtime~=0.47.0
# Added by doQumentation — required packages for this notebook
!pip install -q qiskit qiskit-ibm-runtime

Étapes pour utiliser la primitive Estimator​

1. Initialiser le compte​

Tu dois d'abord initialiser ton compte. Tu peux ensuite sélectionner la QPU que tu veux utiliser pour calculer la valeur d'espérance.

Suis les étapes dans Configurer ton compte IBM Cloud si tu n'as pas encore de compte.

Gates fractionnaires

Pour utiliser les gates fractionnaires récemment pris en charge, définis use_fractional_gates=True lors de la demande d'un Backend à partir d'une instance QiskitRuntimeService. Par exemple :

service = QiskitRuntimeService()
fractional_gate_backend = service.least_busy(use_fractional_gates=True)

Il s'agit d'une fonctionnalité expérimentale qui pourrait changer à l'avenir.

from qiskit_ibm_runtime import QiskitRuntimeService

service = QiskitRuntimeService()
backend = service.least_busy(
operational=True, simulator=False, min_num_qubits=127
)

print(backend.name)
ibm_fez

2. Créer un circuit et un observable​

Tu as besoin d'au moins un circuit et un observable comme entrées pour la primitive Estimator.

from qiskit.circuit.library import qaoa_ansatz
from qiskit.quantum_info import SparsePauliOp

entanglement = [tuple(edge) for edge in backend.coupling_map.get_edges()]
observable = SparsePauliOp.from_sparse_list(
[("ZZ", [i, j], 0.5) for i, j in entanglement],
num_qubits=backend.num_qubits,
)
circuit = qaoa_ansatz(observable, reps=2)
# The circuit is parametrized, so we will define the parameter values for execution
param_values = [0.1, 0.2, 0.3, 0.4]

Le circuit et l'observable doivent être transformés pour n'utiliser que des instructions prises en charge par la QPU (appelées circuits d'architecture d'ensemble d'instructions (ISA)). Utilise le Transpiler pour ce faire.

from qiskit.transpiler import generate_preset_pass_manager

pm = generate_preset_pass_manager(optimization_level=1, backend=backend)
isa_circuit = pm.run(circuit)
isa_observable = observable.apply_layout(isa_circuit.layout)
print(f">>> Circuit ops (ISA): {isa_circuit.count_ops()}")
>>> Circuit ops (ISA): OrderedDict([('rz', 4472), ('sx', 1884), ('cz', 1120)])

3. Initialiser IBM Quantum Estimator​

Lorsque tu initialises Estimator, utilise le paramètre mode pour spécifier le mode dans lequel tu veux l'exécuter. Les valeurs possibles sont batch, session ou des objets backend pour le mode d'exécution batch, session et job respectivement. Pour plus d'informations, voir Introduction aux modes d'exécution d'IBM Quantum Compute Service. Remarque que les utilisateurs du plan Open ne peuvent pas soumettre de jobs de Session.

from qiskit_ibm_runtime import EstimatorV2 as Estimator

estimator = Estimator(mode=backend)

4. Invoquer Estimator et obtenir les résultats​

Ensuite, invoque la méthode run() pour calculer les valeurs d'espérance pour les circuits d'entrée et les observables. Le circuit, l'observable et les ensembles de valeurs de paramètres optionnels sont entrés sous forme de tuples bloc unifié de primitive (PUB).

job = estimator.run([(isa_circuit, isa_observable, param_values)])
print(f">>> Job ID: {job.job_id()}")
print(f">>> Job Status: {job.status()}")
>>> Job ID: dab7lfurrl7c7386gjn0
>>> Job Status: QUEUED
result = job.result()
print(f">>> {result}")
print(f" > Expectation value: {result[0].data.evs}")
print(f" > Metadata: {result[0].metadata}")
>>> PrimitiveResult([PubResult(data=DataBin(evs=np.ndarray(<shape=(), dtype=float64>), stds=np.ndarray(<shape=(), dtype=float64>), ensemble_standard_error=np.ndarray(<shape=(), dtype=float64>)), metadata={'shots': 4096, 'target_precision': 0.015625, 'circuit_metadata': {}, 'resilience': {}, 'num_randomizations': 32})], metadata={'dynamical_decoupling': {'enable': False, 'sequence_type': 'XX', 'extra_slack_distribution': 'middle', 'scheduling_method': 'alap'}, 'twirling': {'enable_gates': False, 'enable_measure': True, 'num_randomizations': 'auto', 'shots_per_randomization': 'auto', 'interleave_randomizations': True, 'strategy': 'active-accum'}, 'resilience': {'measure_mitigation': True, 'zne_mitigation': False, 'pec_mitigation': False}, 'version': 2})
> Expectation value: 28.60306448415693
> Metadata: {'shots': 4096, 'target_precision': 0.015625, 'circuit_metadata': {}, 'resilience': {}, 'num_randomizations': 32}

Étapes suivantes​

Recommandations