{
  "cells": [
    {
      "cell_type": "markdown",
      "id": "4a4b88ed-d21f-4056-9264-0ee8c8ec4b39",
      "metadata": {},
      "source": [
        "---\n",
        "title: \"Simulation précise et bruyante avec les primitives Qiskit Aer\"\n",
        "description: \"Apprenez à réaliser des simulations précises et bruitées de programmes quantiques avec les primitives Qiskit Aer\"\n",
        "---\n",
        "\n",
        "<span id=\"exact-and-noisy-simulation-with-qiskit-aer-primitives\" />\n",
        "\n",
        "# Simulation précise et bruyante avec les primitives Qiskit Aer\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "678b9055-9164-417c-9897-9fde615b97ae",
      "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 de cette page a été développé en tenant compte des exigences suivantes.\n",
        "    Nous recommandons d'utiliser ces versions ou des versions plus récentes.\n",
        "\n",
        "    ```\n",
        "    qiskit[all]~=2.5.1\n",
        "    qiskit-aer~=0.17\n",
        "    ```\n",
        "  </AccordionItem>\n",
        "</Accordion>\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "6a0ae8b1-b413-44ac-9267-fd36345a02df",
      "metadata": {},
      "source": [
        "[La simulation exacte à l'aide des primitives « Qiskit SDK »](/docs/guides/simulate-with-qiskit-sdk-primitives) montre comment utiliser les primitives de référence fournies avec Qiskit pour réaliser une simulation exacte de circuits quantiques. Les processeurs quantiques actuels sont sujets à des erreurs, ou au bruit, de sorte que les résultats d'une simulation exacte ne reflètent pas nécessairement ceux auxquels on pourrait s'attendre en exécutant des circuits sur du matériel réel. Bien que les primitives de référence de Qiskit ne prennent pas en charge la modélisation du bruit, [Qiskit Aer](https://qiskit.org/ecosystem/aer/) propose des implémentations de ces primitives qui, elles, prennent en charge la modélisation du bruit. Qiskit Aer est un simulateur de circuits quantiques hautement performant que vous pouvez utiliser à la place des primitives de référence pour bénéficier de meilleures performances et de fonctionnalités supplémentaires. Il fait partie de l' [écosystème](https://qiskit.github.io/ecosystem/) Qiskit. Dans cet article, nous présentons l'utilisation des primitives de Qiskit Aer pour la simulation exacte et la simulation avec bruit.\n",
        "\n",
        "<Admonition type=\"note\" title=\"Remarques\">\n",
        "  * `qiskit-aer` v0.14 ou une version ultérieure est nécessaire.\n",
        "  * Bien que les primitives de Qiskit Aer implémentent les interfaces de primitives, elles n'offrent pas les mêmes options que les primitives d' IBM Quantum. Le niveau de résilience, par exemple, n'est pas disponible avec les primitives de Qiskit Aer.\n",
        "  * Voir la [documentation de AerSimulator](https://qiskit.github.io/qiskit-aer/stubs/qiskit_aer.AerSimulator) pour plus de détails sur les options de méthodes de simulation prises en charge par Aer.\n",
        "</Admonition>\n",
        "\n",
        "Pour explorer la simulation exacte et bruyante, créez un circuit d'exemple sur huit qubits :\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 1,
      "id": "df70b5fd-971d-4e7d-a23a-8df037c0fa47",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "<Image src=\"/docs/images/guides/simulate-with-qiskit-aer/extracted-outputs/df70b5fd-971d-4e7d-a23a-8df037c0fa47-0.svg\" alt=\"Output of the previous code cell\" />"
            ]
          },
          "execution_count": 1,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "from qiskit.circuit.library import efficient_su2\n",
        "\n",
        "n_qubits = 8\n",
        "circuit = efficient_su2(n_qubits)\n",
        "circuit.draw(\"mpl\")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "2074eaf0-746e-4a36-91d9-db9228f96a0d",
      "metadata": {},
      "source": [
        "Ce circuit contient des paramètres représentant les angles de rotation des portes $R_y$ et $R_z$. Lors de la simulation de ce circuit, nous devons spécifier des valeurs explicites pour ces paramètres. Dans la cellule suivante, nous spécifions quelques valeurs pour ces paramètres et utilisons la primitive Estimator de Qiskit Aer pour calculer la valeur exacte de l'espérance de l'observable $ZZ \\cdots Z$.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 2,
      "id": "40270ca7-1084-4329-aac5-28c87edc3791",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "0.8870140234256602"
            ]
          },
          "execution_count": 2,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "from qiskit.quantum_info import SparsePauliOp\n",
        "from qiskit.transpiler import generate_preset_pass_manager\n",
        "from qiskit_aer import AerSimulator\n",
        "from qiskit_aer.primitives import EstimatorV2 as Estimator\n",
        "\n",
        "observable = SparsePauliOp(\"Z\" * n_qubits)\n",
        "params = [0.1] * circuit.num_parameters\n",
        "\n",
        "exact_estimator = Estimator()\n",
        "# The circuit needs to be transpiled to the AerSimulator target\n",
        "pass_manager = generate_preset_pass_manager(3, AerSimulator())\n",
        "isa_circuit = pass_manager.run(circuit)\n",
        "pub = (isa_circuit, observable, params)\n",
        "job = exact_estimator.run([pub])\n",
        "result = job.result()\n",
        "pub_result = result[0]\n",
        "exact_value = float(pub_result.data.evs)\n",
        "exact_value"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "134d97a2-8420-4931-85b4-324679655e24",
      "metadata": {},
      "source": [
        "Initialisons maintenant un modèle de bruit qui inclut une erreur de dépolarisation de 2 % sur chaque porte CX. Dans la pratique, les erreurs liées aux portes à deux qubits, en l'occurrence les portes CX, constituent la principale source d'erreurs lors de l'exécution d'un circuit. Consultez [la section « Créer des modèles de bruit](/docs/guides/build-noise-models) » pour obtenir un aperçu de la création de modèles de bruit dans Qiskit Aer.\n",
        "\n",
        "Dans la cellule suivante, nous construisons un estimateur qui incorpore ce modèle de bruit et l'utilisons pour calculer la valeur d'espérance de l'observable.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 3,
      "id": "82b2f19a-ba10-46a2-ba1b-89cd27bc0e63",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "0.7247404214143528"
            ]
          },
          "execution_count": 3,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "from qiskit_aer.noise import NoiseModel, depolarizing_error\n",
        "\n",
        "noise_model = NoiseModel()\n",
        "cx_depolarizing_prob = 0.02\n",
        "noise_model.add_all_qubit_quantum_error(\n",
        "    depolarizing_error(cx_depolarizing_prob, 2), [\"cx\"]\n",
        ")\n",
        "\n",
        "noisy_estimator = Estimator(\n",
        "    options=dict(backend_options=dict(noise_model=noise_model))\n",
        ")\n",
        "job = noisy_estimator.run([pub])\n",
        "result = job.result()\n",
        "pub_result = result[0]\n",
        "noisy_value = float(pub_result.data.evs)\n",
        "noisy_value"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "6495f179-3fe6-4971-b023-700b8b2c8cbb",
      "metadata": {},
      "source": [
        "Comme vous pouvez le constater, la valeur attendue en présence de bruit est assez éloignée de la valeur correcte. Dans la pratique, il est possible de recourir à diverses techniques d'atténuation des erreurs pour contrer les effets du bruit, mais l'examen de ces techniques sort du cadre de cet article.\n",
        "\n",
        "Pour avoir une idée très approximative de la façon dont le bruit affecte le résultat final, considérons notre modèle de bruit, qui ajoute une erreur de dépolarisation de 2 % à chaque porte CX. L'erreur de dépolarisation avec la probabilité $p$ est définie comme un canal quantique $E$ qui a l'action suivante sur une matrice de densité $\\rho$ :\n",
        "\n",
        "$$\n",
        "E(\\rho) = (1 - p) \\rho + p\\frac{I}{2^n}\n",
        "$$\n",
        "\n",
        "où $n$ est le nombre de qubits, dans ce cas, 2. C'est-à-dire qu'avec la probabilité $p$, l'état est remplacé par l'état complètement mélangé, et l'état est préservé avec la probabilité $1 - p$. Après $m$ applications du canal dépolarisant, la probabilité que l'état soit préservé serait de $(1 - p)^m$. Par conséquent, nous nous attendons à ce que la probabilité de conserver l'état correct à la fin de la simulation diminue de manière exponentielle avec le nombre de portes CX dans notre circuit.\n",
        "\n",
        "Comptons le nombre de portes CX dans notre circuit et calculons $(1 - p)^m$. Nous appelons `count_ops` pour obtenir un dictionnaire qui associe les noms de portes aux nombres, et nous récupérons l'entrée correspondant à la porte CX.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 4,
      "id": "3c20f7bc-203a-4f40-bb84-7cf3d231d66e",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "0.6542558123199923"
            ]
          },
          "execution_count": 4,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "cx_count = circuit.count_ops()[\"cx\"]\n",
        "(1 - cx_depolarizing_prob) ** cx_count"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "ef506e15-7480-46ba-bce7-aa8f2fa78377",
      "metadata": {},
      "source": [
        "Cette valeur, 65%, donne une estimation approximative de la probabilité que notre état final soit correct. Il s'agit d'une estimation prudente car elle ne tient pas compte de l'état initial de la simulation.\n",
        "\n",
        "La cellule de code suivante montre comment utiliser la primitive Sampler de Qiskit Aer pour échantillonner le circuit bruyant. Nous devons ajouter des mesures au circuit avant de l'exécuter avec la primitive Sampler.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 5,
      "id": "76c43aee-d559-4e5b-8228-e5bba3b4499c",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "{'00000000': 60,\n",
              " '00001111': 1,\n",
              " '11000000': 3,\n",
              " '10100000': 3,\n",
              " '10001111': 1,\n",
              " '00010000': 1,\n",
              " '00001010': 1,\n",
              " '00111100': 1,\n",
              " '01000000': 6,\n",
              " '10000000': 5,\n",
              " '00110000': 1,\n",
              " '00011000': 2,\n",
              " '01100000': 2,\n",
              " '00000110': 2,\n",
              " '11000100': 1,\n",
              " '10000110': 1,\n",
              " '01010000': 2,\n",
              " '00011110': 1,\n",
              " '00010100': 2,\n",
              " '01011010': 1,\n",
              " '00000010': 1,\n",
              " '00001100': 1,\n",
              " '11100000': 1}"
            ]
          },
          "execution_count": 5,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "from qiskit_aer.primitives import SamplerV2 as Sampler\n",
        "\n",
        "measured_circuit = circuit.copy()\n",
        "measured_circuit.measure_all()\n",
        "\n",
        "noisy_sampler = Sampler(\n",
        "    options=dict(backend_options=dict(noise_model=noise_model))\n",
        ")\n",
        "# The circuit needs to be transpiled to the AerSimulator target\n",
        "pass_manager = generate_preset_pass_manager(3, AerSimulator())\n",
        "isa_circuit = pass_manager.run(measured_circuit)\n",
        "pub = (isa_circuit, params, 100)\n",
        "job = noisy_sampler.run([pub])\n",
        "result = job.result()\n",
        "pub_result = result[0]\n",
        "pub_result.data.meas.get_counts()"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "46a8c6b7-3f7c-48e4-9b73-b04a5458ba33",
      "metadata": {},
      "source": [
        "<span id=\"next-steps\" />\n",
        "\n",
        "## Etapes suivantes\n",
        "\n",
        "<Admonition type=\"tip\" title=\"Recommandations\">\n",
        "  * Pour simuler des circuits simples et de petite taille, consultez la section « [Simulation exacte à l'aide des primitives d' Qiskit SDK](/docs/guides/simulate-with-qiskit-sdk-primitives) ».\n",
        "  * Consultez la documentation de [Qiskit Aer.](https://qiskit.github.io/qiskit-aer/)\n",
        "</Admonition>\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "id": "a1b8767d",
      "source": "© IBM Corp., 2017-2026"
    }
  ],
  "metadata": {
    "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
}