{
  "cells": [
    {
      "cell_type": "markdown",
      "id": "066d7e4d-a975-4519-b56f-095f861be3ac",
      "metadata": {},
      "source": [
        "---\n",
        "title: \"Données d'entrée et de sortie de l'estimateur\"\n",
        "description: \"Comprendre les formats d'entrée et de sortie de la primitive Estimator\"\n",
        "---\n",
        "\n",
        "<span id=\"estimator-inputs-and-outputs\" />\n",
        "\n",
        "# Données d'entrée et de sortie de l'estimateur\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "23e7dff0-fde5-4c2d-89c2-fc5ab99240fe",
      "metadata": {
        "tags": [
          "version-info"
        ]
      },
      "source": [
        "{/*\n",
        "  DO NOT EDIT THIS CELL!!!\n",
        "  This cell's content is generated automatically by a script. Anything you add\n",
        "  here will be removed next time the notebook is run. To add new content, create\n",
        "  a new cell before or after this one.\n",
        "  */}\n",
        "\n",
        "<Accordion>\n",
        "  <AccordionItem title=\"Versions de package\">\n",
        "    Le code présenté sur cette page a été développé en tenant compte des exigences suivantes.\n",
        "    Nous vous recommandons d'utiliser ces versions ou des versions plus récentes.\n",
        "\n",
        "    ```\n",
        "    qiskit[all]~=2.5.1\n",
        "    qiskit-ibm-runtime~=0.47.0\n",
        "    ```\n",
        "  </AccordionItem>\n",
        "</Accordion>\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "90d0c1e0-28e7-48da-a35f-6016fddea82c",
      "metadata": {},
      "source": [
        "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 » ()**](/docs/guides/primitive-input-output#pubs). Ils servent d'entrées à la méthode [`run()`](/docs/api/qiskit-ibm-runtime/estimator-v2#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.\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "83a5fdd8-6547-47c7-9441-a7458edc7896",
      "metadata": {},
      "source": [
        "<span id=\"inputs\" />\n",
        "\n",
        "## Entrées\n",
        "\n",
        "Chaque ligne « PUB » se présente sous ce format :\n",
        "\n",
        "(`<single circuit>`, `<one or more observables>`, `<optional one or more parameter values>`, `<optional precision>`),\n",
        "\n",
        "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](primitive-input-output#broadcasting-rules) », et une estimation de la valeur attendue est renvoyée pour chaque élément de la structure diffusée.\n",
        "\n",
        "<Admonition types=\"note\">\n",
        "  Si la saisie contient des mesures, celles-ci sont ignorées.\n",
        "</Admonition>\n",
        "\n",
        "Pour la primitive Estimator, une instance de type « PUB » peut contenir au maximum quatre valeurs :\n",
        "\n",
        "* Un élément unique `QuantumCircuit`, pouvant contenir un ou plusieurs [`Parameter`](/docs/api/qiskit/qiskit.circuit.Parameter) objets\n",
        "* 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 `ObservablesArrayLike` formats suivants `Pauli`: `SparsePauliOp`, `PauliList`,, ou `str`.\n",
        "  <Admonition type=\"note\" title=\"Variables liées aux déplacements domicile-travail\">\n",
        "    * [Cette méthode](/docs/api/qiskit/qiskit.quantum_info.PauliList#group_qubit_wise_commuting) permet de regrouper les observables commutatives **d'une même PUB**.\n",
        "    * 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 ».\n",
        "    * 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 ».\n",
        "  </Admonition>\n",
        "* 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 `Parameter` du circuit, ou être omis (ou, de manière équivalente, défini à `None`) si le circuit ne comporte aucun `Parameter` objet.\n",
        "* (Facultatif) Une précision cible pour les valeurs attendues à estimer\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "846b3109-02a1-4783-ad3f-1c22f753c324",
      "metadata": {},
      "source": [
        "***\n",
        "\n",
        "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.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 1,
      "id": "2f50a9f5-2cc1-4d83-9fe1-1b3a8be0d766",
      "metadata": {},
      "outputs": [],
      "source": [
        "from qiskit.circuit import (\n",
        "    Parameter,\n",
        "    QuantumCircuit,\n",
        ")\n",
        "from qiskit.transpiler import generate_preset_pass_manager\n",
        "from qiskit.quantum_info import SparsePauliOp\n",
        "\n",
        "from qiskit_ibm_runtime import (\n",
        "    QiskitRuntimeService,\n",
        "    EstimatorV2 as Estimator,\n",
        ")\n",
        "\n",
        "import numpy as np\n",
        "\n",
        "# Instantiate runtime service and get\n",
        "# the least busy backend\n",
        "service = QiskitRuntimeService()\n",
        "backend = service.least_busy(operational=True, simulator=False)\n",
        "\n",
        "# Define a circuit with two parameters.\n",
        "circuit = QuantumCircuit(2)\n",
        "circuit.h(0)\n",
        "circuit.cx(0, 1)\n",
        "circuit.ry(Parameter(\"a\"), 0)\n",
        "circuit.rz(Parameter(\"b\"), 0)\n",
        "circuit.cx(0, 1)\n",
        "circuit.h(0)\n",
        "\n",
        "# Transpile the circuit\n",
        "pm = generate_preset_pass_manager(optimization_level=1, backend=backend)\n",
        "transpiled_circuit = pm.run(circuit)\n",
        "layout = transpiled_circuit.layout\n",
        "\n",
        "# Now define a sweep over parameter values, the last axis of dimension 2 is\n",
        "# for the two parameters \"a\" and \"b\"\n",
        "params = np.vstack(\n",
        "    [\n",
        "        np.linspace(-np.pi, np.pi, 100),\n",
        "        np.linspace(-4 * np.pi, 4 * np.pi, 100),\n",
        "    ]\n",
        ").T\n",
        "\n",
        "# Define three observables. The inner length-1 lists cause this array of\n",
        "# observables to have shape (3, 1), rather than shape (3,) if they were\n",
        "# omitted.\n",
        "observables = [\n",
        "    [SparsePauliOp([\"XX\", \"IY\"], [0.5, 0.5])],\n",
        "    [SparsePauliOp(\"XX\")],\n",
        "    [SparsePauliOp(\"IY\")],\n",
        "]\n",
        "# Apply the same layout as the transpiled circuit.\n",
        "observables = [\n",
        "    [observable.apply_layout(layout) for observable in observable_set]\n",
        "    for observable_set in observables\n",
        "]\n",
        "\n",
        "# Estimate the expectation value for all 300 combinations of observables\n",
        "# and parameter values, where the pub result will have shape (3, 100).\n",
        "#\n",
        "# This shape is due to our array of parameter bindings having shape\n",
        "# (100, 2), combined with our array of observables having shape (3, 1).\n",
        "estimator_pub = (transpiled_circuit, observables, params)\n",
        "\n",
        "# Instantiate the new Estimator object, then run the transpiled circuit\n",
        "# using the set of parameters and observables.\n",
        "estimator = Estimator(mode=backend)\n",
        "job = estimator.run([estimator_pub])\n",
        "result = job.result()"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "90dccb20-1848-4367-a12d-434110ad5a5c",
      "metadata": {},
      "source": [
        "<span id=\"outputs\" />\n",
        "\n",
        "## Sorties\n",
        "\n",
        "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`](/docs/api/qiskit/qiskit.primitives.PrimitiveResult) conteneur accessible en appelant la `RuntimeJobV2.result()` méthode.\n",
        "\n",
        "L'objet `PrimitiveResult` contient une liste itérable [`PubResult`](/docs/api/qiskit/qiskit.primitives.PubResult) d'objets qui renferment les résultats d'exécution pour chaque PUB.\n",
        "\n",
        "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 ).\n",
        "\n",
        "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.\n",
        "\n",
        "Chaque `PubResult` objet possède à la fois un attribut `data` et un `metadata` attribut.\n",
        "\n",
        "* L'attribut `data` est un champ personnalisé [`DataBin`](/docs/api/qiskit/qiskit.primitives.DataBin) qui contient les valeurs de mesure réelles, les écarts-types, etc.\n",
        "* La `DataBin` pré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](/docs/guides/error-mitigation-and-suppression-techniques#zero-noise-extrapolation-zne) ou [PEC](/docs/guides/error-mitigation-and-suppression-techniques#probabilistic-error-cancellation-pec) ).\n",
        "* L'attribut `metadata` contient 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](#result-metadata) » de cette page).\n",
        "\n",
        "Voici un schéma illustrant la structure `PrimitiveResult` des données de la sortie de l'estimateur :\n",
        "\n",
        "```\n",
        "└── PrimitiveResult\n",
        "    ├── PubResult[0]\n",
        "    │   ├── metadata\n",
        "    │   └── data  ## In the form of a DataBin object\n",
        "    │       ├── evs\n",
        "    │       │   └── List of estimated expectation values in the shape\n",
        "    |       |         specified by the first pub\n",
        "    │       └── stds\n",
        "    │           └── List of calculated standard deviations in the\n",
        "    |                 same shape as above\n",
        "    ├── PubResult[1]\n",
        "    |   ├── metadata\n",
        "    |   └── data  ## In the form of a DataBin object\n",
        "    |       ├── evs\n",
        "    |       │   └── List of estimated expectation values in the shape\n",
        "    |       |        specified by the second pub\n",
        "    |       └── stds\n",
        "    |           └── List of calculated standard deviations in the\n",
        "    |                same shape as above\n",
        "    ├── ...\n",
        "    ├── ...\n",
        "    └── ...\n",
        "```\n",
        "\n",
        "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.\n",
        "\n",
        "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.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 2,
      "id": "53a4d5ae-109b-452b-bbc5-2d7940c5182c",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "The result of the submitted job had 1 PUBs and has a value:\n",
            " 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})\n",
            "\n",
            "The associated PubResult of this job has the following data bins:\n",
            " {result[0].data}\n",
            "\n",
            "And this DataBin has attributes: dict_keys(['evs', 'stds', 'ensemble_standard_error'])\n",
            "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). \n",
            "\n",
            "The expectation values measured from this PUB are: \n",
            "{result[0].data.evs}\n",
            "\n"
          ]
        }
      ],
      "source": [
        "print(\n",
        "    f\"The result of the submitted job had {len(result)} \"\n",
        "    f\"PUBs and has a value:\\n {result}\\n\"\n",
        ")\n",
        "print(\n",
        "    \"The associated PubResult of this job has the following data bins:\\n \"\n",
        "    \"{result[0].data}\\n\"\n",
        ")\n",
        "print(f\"And this DataBin has attributes: {result[0].data.keys()}\")\n",
        "print(\n",
        "    \"Recall that this shape is due to our array of parameter binding sets\"\n",
        "    \"having shape (100, 2), where 2 is the number of parameters in the \"\n",
        "    \"circuit, combined with our array of observables having shape (3, 1). \\n\"\n",
        ")\n",
        "with np.printoptions(threshold=200):\n",
        "    print(\n",
        "        \"The expectation values measured from this PUB are: \\n\"\n",
        "        \"{result[0].data.evs}\\n\"\n",
        "    )"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "000ade51-d940-45f9-84ea-16ad283a930f",
      "metadata": {},
      "source": [
        "<span id=\"how-the-estimator-primitive-calculates-error\" />\n",
        "\n",
        "#### Comment la primitive Estimator calcule l'erreur\n",
        "\n",
        "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`.\n",
        "\n",
        "Considérons une observable unique $\\mathcal{O}$. En l'absence de [ZNE](/docs/guides/error-mitigation-and-suppression-techniques#zero-noise-extrapolation-zne), on peut considérer que chaque itération de l'exécution de l'estimateur fournit une estimation ponctuelle de la valeur attendue $\\langle \\mathcal{O} \\rangle$. 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ù $\\sigma_{\\mathcal{O}}$ est [l](/docs/api/qiskit/qiskit.primitives.BackendEstimatorV2) 'écart-type de l'estimation de la valeur attendue et $N_{shots}$ est le nombre d'itérations) :\n",
        "\n",
        "$\\frac{ \\sigma_{\\mathcal{O}} }{ \\sqrt{N_{shots}} },$\n",
        "\n",
        "qui considère tous les plans comme faisant partie d'un ensemble unique. Si vous avez demandé [une rotation](/docs/guides/error-mitigation-and-suppression-techniques#pauli-twirling) de porte (`twirling.enable_gates = True`), vous pouvez regrouper les estimations ponctuelles de $\\langle \\mathcal{O} \\rangle$ 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\n",
        "\n",
        "$\\frac{ \\sigma_{\\mathcal{O}} }{ \\sqrt{N_{twirls}} },$\n",
        "\n",
        "où $\\sigma_{\\mathcal{O}}$ est l'écart-type de `O_twirls` et $N_{twirls}$ est le nombre de rotations. Lorsque vous n'activez pas la rotation, `stds` et `ensemble_standard_error` sont égaux.\n",
        "\n",
        "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.\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "c4341184-a41a-4442-bc05-838c90ea93b8",
      "metadata": {},
      "source": [
        "<span id=\"result-metadata\" />\n",
        "\n",
        "## Métadonnées des résultats\n",
        "\n",
        "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](/docs/api/qiskit-ibm-runtime/options) disponibles) se trouvent dans le `PrimitiveResult.metatada`, tandis que les métadonnées spécifiques à chaque publication PUB se trouvent dans `PubResult.metadata`le.\n",
        "\n",
        "<Admonition type=\"note\">\n",
        "  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.\n",
        "</Admonition>\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 3,
      "id": "626ba203-44e2-4b8f-b04d-04388b8b1fa1",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "The metadata of the PrimitiveResult is:\n",
            "'dynamical_decoupling' : {'enable': False, 'sequence_type': 'XX', 'extra_slack_distribution': 'middle', 'scheduling_method': 'alap'},\n",
            "'twirling' : {'enable_gates': False, 'enable_measure': True, 'num_randomizations': 'auto', 'shots_per_randomization': 'auto', 'interleave_randomizations': True, 'strategy': 'active-accum'},\n",
            "'resilience' : {'measure_mitigation': True, 'zne_mitigation': False, 'pec_mitigation': False},\n",
            "'version' : 2,\n",
            "\n",
            "The metadata of the PubResult result is:\n",
            "'shots' : 4096,\n",
            "'target_precision' : 0.015625,\n",
            "'circuit_metadata' : {},\n",
            "'resilience' : {},\n",
            "'num_randomizations' : 32,\n"
          ]
        }
      ],
      "source": [
        "# Print out the results metadata\n",
        "print(\"The metadata of the PrimitiveResult is:\")\n",
        "for key, val in result.metadata.items():\n",
        "    print(f\"'{key}' : {val},\")\n",
        "\n",
        "print(\"\\nThe metadata of the PubResult result is:\")\n",
        "for key, val in result[0].metadata.items():\n",
        "    print(f\"'{key}' : {val},\")"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "id": "a1b8767d",
      "source": "© IBM Corp., 2017-2026"
    }
  ],
  "metadata": {
    "celltoolbar": "Raw Cell Format",
    "kernelspec": {
      "display_name": "Python 3",
      "language": "python",
      "name": "python3"
    },
    "language_info": {
      "codemirror_mode": {
        "name": "ipython",
        "version": 3
      },
      "file_extension": ".py",
      "mimetype": "text/x-python",
      "name": "python",
      "nbconvert_exporter": "python",
      "pygments_lexer": "ipython3",
      "version": "3"
    }
  },
  "nbformat": 4,
  "nbformat_minor": 4
}