Données d'entrée et de sortie de l'estimateur
Le code présenté sur cette page a été développé en tenant compte des exigences suivantes. Nous vous recommandons d'utiliser ces versions ou des versions plus récentes.
qiskit[all]~=2.5.1 qiskit-ibm-runtime~=0.47.0
Cette page présente une vue d'ensemble des entrées et des sorties de la primitive « Estimator » d' IBM Quantum, qui exécute des charges de travail sur les ressources de calcul d' IBM Quantum®. Estimator vous permet de définir efficacement des charges de travail vectorisées à l'aide d'une structure de données appelée « PUB » (). Ils servent d'entrées à la méthode run() de la primitive « Estimator », qui exécute la charge de travail définie sous forme de tâche. Ensuite, une fois la tâche terminée, les résultats sont renvoyés dans un format qui dépend à la fois des PUB utilisés et des options d'exécution spécifiées au niveau de la primitive.
Entrées
Chaque ligne « PUB » se présente sous ce format :
(<single circuit>, <one or more observables>, <optional one or more parameter values>, <optional precision>),
Le paramètre facultatif parameter values peut être une liste ou un seul paramètre. Les éléments issus des observables et des valeurs de paramètres sont combinés selon les règles de diffusion d' NumPy s décrites dans la rubrique « Entrées et sorties primitives », et une estimation de la valeur attendue est renvoyée pour chaque élément de la structure diffusée.
Si la saisie contient des mesures, celles-ci sont ignorées.
Pour la primitive Estimator, une instance de type « PUB » peut contenir au maximum quatre valeurs :
- Un élément unique
QuantumCircuit, pouvant contenir un ou plusieursParameterobjets - Une liste d'une ou plusieurs variables observables, qui spécifient les valeurs attendues à estimer, organisées sous forme de tableau (par exemple, une seule variable observable représentée par un tableau de dimension 0, une liste de variables observables par un tableau de dimension 1, et ainsi de suite). Les données peuvent être dans l'un des
ObservablesArrayLikeformats suivantsPauli:SparsePauliOp,PauliList,, oustr.Variables liées aux déplacements domicile-travail- Cette méthode permet de regrouper les observables commutatives d'une même PUB.
- Les grandeurs observables relatives aux trajets domicile-travail dans différents PUB, même si elles concernent le même circuit, ne sont pas estimées à partir de la même mesure. Chaque « PUB » correspond à une base de mesure différente; par conséquent, des mesures distinctes sont nécessaires pour chaque « PUB ».
- Pour garantir que les variables relatives aux trajets domicile-travail soient estimées à partir de la même mesure, regroupez-les au sein d'une même « PUB ».
- Un ensemble de valeurs de paramètres auxquelles le circuit doit être associé. Cela peut être spécifié sous la forme d'un objet de type tableau unique dont le dernier index correspond au nombre d'objets
Parameterdu circuit, ou être omis (ou, de manière équivalente, défini àNone) si le circuit ne comporte aucunParameterobjet. - (Facultatif) Une précision cible pour les valeurs attendues à estimer
Le code suivant présente un exemple d'ensemble d'entrées vectorisées pour la Estimator primitive et les exécute sur un backend IBM® en tant qu'objet RuntimeJobV2 unique.
from qiskit.circuit import (
Parameter,
QuantumCircuit,
)
from qiskit.transpiler import generate_preset_pass_manager
from qiskit.quantum_info import SparsePauliOp
from qiskit_ibm_runtime import (
QiskitRuntimeService,
EstimatorV2 as Estimator,
)
import numpy as np
# Instantiate runtime service and get
# the least busy backend
service = QiskitRuntimeService()
backend = service.least_busy(operational=True, simulator=False)
# Define a circuit with two parameters.
circuit = QuantumCircuit(2)
circuit.h(0)
circuit.cx(0, 1)
circuit.ry(Parameter("a"), 0)
circuit.rz(Parameter("b"), 0)
circuit.cx(0, 1)
circuit.h(0)
# Transpile the circuit
pm = generate_preset_pass_manager(optimization_level=1, backend=backend)
transpiled_circuit = pm.run(circuit)
layout = transpiled_circuit.layout
# Now define a sweep over parameter values, the last axis of dimension 2 is
# for the two parameters "a" and "b"
params = np.vstack(
[
np.linspace(-np.pi, np.pi, 100),
np.linspace(-4 * np.pi, 4 * np.pi, 100),
]
).T
# Define three observables. The inner length-1 lists cause this array of
# observables to have shape (3, 1), rather than shape (3,) if they were
# omitted.
observables = [
[SparsePauliOp(["XX", "IY"], [0.5, 0.5])],
[SparsePauliOp("XX")],
[SparsePauliOp("IY")],
]
# Apply the same layout as the transpiled circuit.
observables = [
[observable.apply_layout(layout) for observable in observable_set]
for observable_set in observables
]
# Estimate the expectation value for all 300 combinations of observables
# and parameter values, where the pub result will have shape (3, 100).
#
# This shape is due to our array of parameter bindings having shape
# (100, 2), combined with our array of observables having shape (3, 1).
estimator_pub = (transpiled_circuit, observables, params)
# Instantiate the new Estimator object, then run the transpiled circuit
# using the set of parameters and observables.
estimator = Estimator(mode=backend)
job = estimator.run([estimator_pub])
result = job.result()Sorties
Une fois qu'un ou plusieurs PUB ont été envoyés à une QPU pour exécution et qu'une tâche s'est achevée avec succès, les données sont renvoyées sous la forme d'un objet PrimitiveResult conteneur accessible en appelant la RuntimeJobV2.result() méthode.
L'objet PrimitiveResult contient une liste itérable PubResult d'objets qui renferment les résultats d'exécution pour chaque PUB.
Chaque élément de cette liste correspond à chaque PUB soumis à la méthode run() de la primitive (par exemple, un travail soumis avec 20 PUB renverra un PrimitiveResult objet contenant une liste de 20 PubResult objets, chacun correspondant à un PUB ).
Chaque primitive PubResult de l'estimateur contient au moins un tableau de valeurs attendues (PubResult.data.evs) et d'écarts-types associés (soit PubResult.data.stds soit PubResult.data.ensemble_standard_error selon la resilience_level utilisée), mais peut contenir davantage de données en fonction des options d'atténuation des erreurs qui ont été spécifiées.
Chaque PubResult objet possède à la fois un attribut data et un metadata attribut.
- L'attribut
dataest un champ personnaliséDataBinqui contient les valeurs de mesure réelles, les écarts-types, etc. - La
DataBinprésente divers attributs qui dépendent de la forme ou de la structure de l' PUB e associée, ainsi que des options d'atténuation des erreurs spécifiées par la primitive utilisée pour soumettre le travail (par exemple, ZNE ou PEC ). - L'attribut
metadatacontient des informations sur les options d'exécution et de gestion des erreurs utilisées (expliquées plus loin dans la section « Métadonnées du résultat » de cette page).
Voici un schéma illustrant la structure PrimitiveResult des données de la sortie de l'estimateur :
└── PrimitiveResult
├── PubResult[0]
│ ├── metadata
│ └── data ## In the form of a DataBin object
│ ├── evs
│ │ └── List of estimated expectation values in the shape
| | specified by the first pub
│ └── stds
│ └── List of calculated standard deviations in the
| same shape as above
├── PubResult[1]
| ├── metadata
| └── data ## In the form of a DataBin object
| ├── evs
| │ └── List of estimated expectation values in the shape
| | specified by the second pub
| └── stds
| └── List of calculated standard deviations in the
| same shape as above
├── ...
├── ...
└── ...
En termes simples, une tâche renvoie un PrimitiveResult objet et contient une liste d'un ou plusieurs PubResult objets. Ces PubResult objets stockent ensuite les données de mesure pour chaque PUB ion soumise au travail.
L'extrait de code ci-dessous décrit le format PrimitiveResult (et les éléments associés PubResult) de la tâche créée ci-dessus.
print(
f"The result of the submitted job had {len(result)} "
f"PUBs and has a value:\n {result}\n"
)
print(
"The associated PubResult of this job has the following data bins:\n "
"{result[0].data}\n"
)
print(f"And this DataBin has attributes: {result[0].data.keys()}")
print(
"Recall that this shape is due to our array of parameter binding sets"
"having shape (100, 2), where 2 is the number of parameters in the "
"circuit, combined with our array of observables having shape (3, 1). \n"
)
with np.printoptions(threshold=200):
print(
"The expectation values measured from this PUB are: \n"
"{result[0].data.evs}\n"
)Output:
The result of the submitted job had 1 PUBs and has a value:
PrimitiveResult([PubResult(data=DataBin(evs=np.ndarray(<shape=(3, 100), dtype=float64>), stds=np.ndarray(<shape=(3, 100), dtype=float64>), ensemble_standard_error=np.ndarray(<shape=(3, 100), dtype=float64>), shape=(3, 100)), 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})
The associated PubResult of this job has the following data bins:
{result[0].data}
And this DataBin has attributes: dict_keys(['evs', 'stds', 'ensemble_standard_error'])
Recall that this shape is due to our array of parameter binding setshaving shape (100, 2), where 2 is the number of parameters in the circuit, combined with our array of observables having shape (3, 1).
The expectation values measured from this PUB are:
{result[0].data.evs}
Comment la primitive Estimator calcule l'erreur
Outre l'estimation de la moyenne des grandeurs observables transmises dans les PUB d'entrée (le evs champ de la DataBin), l'estimateur tente également de fournir une estimation de l'erreur associée à ces valeurs attendues. Toutes les requêtes Estimator renseignent le stds champ avec une valeur telle que l'erreur-type de la moyenne pour chaque valeur attendue, mais certaines options d'atténuation des erreurs fournissent des informations supplémentaires, telles que ensemble_standard_error.
Considérons une observable unique . En l'absence de ZNE, on peut considérer que chaque itération de l'exécution de l'estimateur fournit une estimation ponctuelle de la valeur attendue . Si les estimations ponctuelles sont regroupées dans un vecteur Os, alors la valeur renvoyée par ensemble_standard_error est équivalente à ce qui suit (où est l 'écart-type de l'estimation de la valeur attendue et est le nombre d'itérations) :
qui considère tous les plans comme faisant partie d'un ensemble unique. Si vous avez demandé une rotation de porte (twirling.enable_gates = True), vous pouvez regrouper les estimations ponctuelles de en ensembles partageant une rotation commune. Appelons ces ensembles d'estimations O_twirls, et il y en a num_randomizations (nombre de tours). C'est stds alors l'erreur-type de la moyenne de O_twirls, comme dans
où est l'écart-type de O_twirls et est le nombre de rotations. Lorsque vous n'activez pas la rotation, stds et ensemble_standard_error sont égaux.
Si vous activez ZNE, les éléments stds décrits ci-dessus deviennent alors des coefficients dans une régression non linéaire appliquée à un modèle d'extrapolation. Ce qui est finalement renvoyé dans ce cas stds , c'est l'incertitude du modèle d'ajustement évaluée pour un facteur de bruit égal à zéro. Lorsque l'ajustement est médiocre ou qu'il comporte une grande incertitude, la valeur indiquée stds peut devenir très élevée. Lorsque ZNE est activé, pub_result.data.evs_noise_factors et pub_result.data.stds_noise_factors sont également renseignés, ce qui vous permet de procéder à votre propre extrapolation.
Métadonnées des résultats
Outre les résultats d'exécution, les objets PrimitiveResult PubResult et contiennent tous deux un attribut de métadonnées concernant le travail qui a été soumis. Les métadonnées contenant des informations sur toutes les publications soumises (telles que les différentes options d'exécution disponibles) se trouvent dans le PrimitiveResult.metatada, tandis que les métadonnées spécifiques à chaque publication PUB se trouvent dans PubResult.metadatale.
Dans le champ des métadonnées, les implémentations de primitives peuvent renvoyer toute information relative à l'exécution qui leur est pertinente, et aucune paire clé-valeur n'est garantie par la primitive de base. Ainsi, les métadonnées renvoyées peuvent varier selon les implémentations des primitives.
# Print out the results metadata
print("The metadata of the PrimitiveResult is:")
for key, val in result.metadata.items():
print(f"'{key}' : {val},")
print("\nThe metadata of the PubResult result is:")
for key, val in result[0].metadata.items():
print(f"'{key}' : {val},")Output:
The metadata of the PrimitiveResult is:
'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,
The metadata of the PubResult result is:
'shots' : 4096,
'target_precision' : 0.015625,
'circuit_metadata' : {},
'resilience' : {},
'num_randomizations' : 32,