{
  "cells": [
    {
      "cell_type": "markdown",
      "id": "552b1077",
      "metadata": {},
      "source": [
        "---\n",
        "title: \"Exécutez votre premier circuit sur le matériel\"\n",
        "description: \"Commencez à utiliser Qiskit avec le matériel d' IBM Quantum dans cet exemple Hello World\"\n",
        "---\n",
        "\n",
        "<span id=\"run-your-first-circuit-on-hardware\" />\n",
        "\n",
        "# Exécutez votre premier circuit sur le matériel\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "7cc19a86-a234-4220-bb4f-d66d3834e0c3",
      "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 figurant sur cette page a été développé selon les 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-ibm-runtime~=0.47.0\n",
        "    ```\n",
        "  </AccordionItem>\n",
        "</Accordion>\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "1a3c196d-545d-417f-b34e-fa422aa9a394",
      "metadata": {},
      "source": [
        "Cet exemple comporte deux parties. Vous allez d'abord créer un programme quantique simple « Hello world » et l'exécuter sur une unité de traitement quantique (QPU).  Étant donné que la recherche quantique réelle nécessite des programmes beaucoup plus robustes, dans la deuxième section ( [Échelle à un grand nombre de qubits](#scale-to-large-numbers-of-qubits) ), vous allez faire passer le programme simple à un niveau utilitaire.\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "7b65f7e0",
      "metadata": {},
      "source": [
        "<span id=\"install-and-authenticate\" />\n",
        "\n",
        "## Installer et authentifier\n",
        "\n",
        "1. Si vous n'avez pas encore installé Qiskit, consultez les instructions dans le guide [de démarrage rapide](/docs/guides/quick-start).\n",
        "\n",
        "   * Installez le client Compute d' IBM Quantum pour exécuter des tâches sur du matériel quantique :\n",
        "\n",
        "     ```bash\n",
        "     pip install qiskit-ibm-runtime\n",
        "     ```\n",
        "\n",
        "   * Configurez un environnement pour exécuter les notebooks Jupyter localement :\n",
        "\n",
        "     ```bash\n",
        "     pip install jupyter\n",
        "     ```\n",
        "\n",
        "2. Configurez votre authentification pour accéder au matériel quantique grâce au programme gratuit [Open Plan](/docs/guides/plans-overview#open-plan).\n",
        "\n",
        "   (Si vous avez reçu une invitation par e-mail pour rejoindre un compte, suivez plutôt les [étapes destinées aux utilisateurs invités](/docs/guides/cloud-setup-invited).)\n",
        "\n",
        "   * Rendez-vous sur [IBM Quantum Platform](/) pour vous connecter ou créer un compte.\n",
        "     <Admonition type=\"note\" title=\"Important\">\n",
        "       Si vous vous connectez via un serveur proxy, vous devez utiliser v0.44.0`qiskit-ibm-runtime` ou une version ultérieure.\n",
        "     </Admonition>\n",
        "\n",
        "   * Générez votre clé API (également appelée *jeton* API) sur le [tableau de bord](/), puis copiez-la dans un emplacement sécurisé.\n",
        "\n",
        "   * Accédez à la page [Instances](/instances) et recherchez l'instance que vous souhaitez utiliser. Passez la souris sur son CRN et cliquez pour le copier.\n",
        "\n",
        "   * Enregistrez vos identifiants localement à l'aide de ce code :\n",
        "\n",
        "     ```python\n",
        "     from qiskit_ibm_runtime import QiskitRuntimeService\n",
        "\n",
        "     QiskitRuntimeService.save_account(\n",
        "         # For `token`, use the 44-character API_KEY you created\n",
        "         # and saved from the IBM Quantum Platform Home dashboard\n",
        "         token=\"<your-api-key>\",\n",
        "         instance=\"<CRN>\", # Optional\n",
        "     )\n",
        "     ```\n",
        "\n",
        "3. Vous pouvez désormais utiliser ce code « Python » chaque fois que vous souhaitez vous authentifier auprès du service Compute de IBM Quantum :\n",
        "   ```python\n",
        "   from qiskit_ibm_runtime import QiskitRuntimeService\n",
        "\n",
        "   # Run every time you need the service\n",
        "   service = QiskitRuntimeService()\n",
        "   ```\n",
        "\n",
        "<Admonition type=\"info\" title=\"Vous n'utilisez pas un environnement Python fiable?\">\n",
        "  Si vous utilisez un ordinateur public ou tout autre environnement non sécurisé, suivez plutôt les [instructions d'authentification manuelle](/docs/guides/cloud-setup-untrusted) afin de protéger vos identifiants d'authentification.\n",
        "</Admonition>\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "80471a0a",
      "metadata": {},
      "source": [
        "<span id=\"create-and-run-a-simple-quantum-program\" />\n",
        "\n",
        "## Créer et exécuter un programme quantique simple\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "85fe979e",
      "metadata": {
        "raw_mimetype": "text/restructuredtext"
      },
      "source": [
        "Les quatre étapes pour écrire un programme quantique à l'aide des modèles Qiskit sont les suivantes :\n",
        "\n",
        "1. Mapper le problème dans un format quantique natif.\n",
        "\n",
        "2. Optimiser les circuits et les opérateurs.\n",
        "\n",
        "3. Exécuter à l'aide d'une fonction primitive quantique.\n",
        "\n",
        "4. Analysez les résultats.\n",
        "\n",
        "<span id=\"step-1-map-the-problem-to-a-quantum-native-format\" />\n",
        "\n",
        "### Etape 1. Mapper le problème vers un format quantique natif\n",
        "\n",
        "Dans un programme quantique, *les circuits quantiques* sont le format natif dans lequel sont représentées les instructions quantiques, et *les opérateurs* représentent les observables à mesurer. Lorsque vous créez un circuit, vous créez généralement un nouvel [`QuantumCircuit`](/docs/api/qiskit/qiskit.circuit.QuantumCircuit#quantumcircuit-class) objet, puis vous y ajoutez des instructions dans l'ordre.\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "21f7a26c",
      "metadata": {},
      "source": [
        "La cellule de code suivante crée un circuit qui produit un *état de Bell,* qui est un état dans lequel deux qubits sont entièrement intriqués l'un avec l'autre.\n",
        "\n",
        "<Admonition type=\"note\" title=\"Remarque : ordre des bits\">\n",
        "  Le Qiskit SDK utilise la numérotation LSb 0 où le $n^{th}$ chiffre a la valeur $1 \\ll n$ ou $2^n$. Pour plus de détails, voir la section [Ordre des bits dans la Qiskit SDK](/docs/guides/bit-ordering) rubrique.\n",
        "</Admonition>\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 2,
      "id": "930ca3b6",
      "metadata": {
        "tags": []
      },
      "outputs": [
        {
          "data": {
            "text/plain": [
              "<Image src=\"/docs/images/guides/hello-world/extracted-outputs/930ca3b6-0.svg\" alt=\"Output of the previous code cell\" />"
            ]
          },
          "execution_count": 2,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "from qiskit import QuantumCircuit\n",
        "from qiskit.quantum_info import SparsePauliOp\n",
        "from qiskit.transpiler import generate_preset_pass_manager\n",
        "from qiskit_ibm_runtime import QiskitRuntimeService\n",
        "from qiskit_ibm_runtime import EstimatorOptions\n",
        "from qiskit_ibm_runtime import EstimatorV2 as Estimator\n",
        "from matplotlib import pyplot as plt\n",
        "# Uncomment the next line if you want to use a simulator:\n",
        "# from qiskit_ibm_runtime.fake_provider import FakeBelemV2\n",
        "\n",
        "\n",
        "# Create a new circuit with two qubits\n",
        "qc = QuantumCircuit(2)\n",
        "\n",
        "# Add a Hadamard gate to qubit 0\n",
        "qc.h(0)\n",
        "\n",
        "# Perform a controlled-X gate on qubit 1, controlled by qubit 0\n",
        "qc.cx(0, 1)\n",
        "\n",
        "# Return a drawing of the circuit using MatPlotLib (\"mpl\").\n",
        "# These guides are written by using Jupyter notebooks, which\n",
        "# display the output of the last line of each cell.\n",
        "# If you're running this in a script, use `print(qc.draw())` to\n",
        "# print a text drawing.\n",
        "qc.draw(\"mpl\")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "0c957de9",
      "metadata": {
        "raw_mimetype": "text/restructuredtext"
      },
      "source": [
        "Consultez [`QuantumCircuit`](/docs/api/qiskit/qiskit.circuit.QuantumCircuit#quantumcircuit-class) la documentation pour connaître toutes les opérations disponibles.\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "f3ef4248-7938-44c1-85f1-edc997f0edcd",
      "metadata": {},
      "source": [
        "Lors de la création de circuits quantiques, vous devez également déterminer quel type de données vous souhaitez obtenir à l'issue de l'exécution. Qiskit propose deux façons de renvoyer des données : vous pouvez obtenir des résultats d'échantillonnage pour un ensemble de qubits que vous choisissez de mesurer, ou vous pouvez obtenir la valeur attendue d'une observable. Préparez votre projet de manière à pouvoir mesurer votre circuit selon l'une de ces deux méthodes à l'aide de primitives (expliquées en détail à [l'étape 3](#step-3-execute-using-the-quantum-primitives) ).\n",
        "\n",
        "Cet exemple mesure les valeurs attendues à l'aide du `qiskit.quantum_info` sous-module, qui est spécifié à l'aide d'opérateurs (objets mathématiques utilisés pour représenter une action ou un processus qui modifie un état quantique). La cellule de code suivante crée six opérateurs de Pauli à deux qubits : `IZ`, `IX`, `ZI` `XI`, `ZZ`, et `XX`.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 3,
      "id": "c57b261c-b757-4432-beab-61b526c98a41",
      "metadata": {
        "tags": []
      },
      "outputs": [],
      "source": [
        "# Set up six different observables.\n",
        "\n",
        "observables_labels = [\"IZ\", \"IX\", \"ZI\", \"XI\", \"ZZ\", \"XX\"]\n",
        "observables = [SparsePauliOp(label) for label in observables_labels]"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "47150779",
      "metadata": {},
      "source": [
        "<Admonition type=\"note\" title=\"Notation de l'opérateur\">\n",
        "  Ici, quelque chose comme `ZZ` l'opérateur est un raccourci pour le produit $Z\\otimes Z$ tensoriel, ce qui signifie mesurer Z sur le qubit 1 et Z sur le qubit 0 ensemble, et obtenir des informations sur la corrélation entre le qubit 1 et le qubit 0. Les valeurs attendues de ce type sont généralement écrites sous la forme $\\langle Z_1 Z_0 \\rangle$.\n",
        "\n",
        "  Si l'état est intriqué, alors la mesure de $\\langle Z_1 Z_0 \\rangle$ devrait être différente de la mesure de $\\langle I_1 \\otimes Z_0 \\rangle \\langle Z_1 \\otimes I_0 \\rangle$. Pour l'état intriqué spécifique créé par notre circuit décrit ci-dessus, la mesure de $\\langle Z_1 Z_0 \\rangle$ devrait être 1 et la mesure de $\\langle I_1 \\otimes Z_0 \\rangle \\langle Z_1 \\otimes I_0 \\rangle$ devrait être zéro.\n",
        "</Admonition>\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "83bf9151-3bc9-40d2-8615-31570238b08e",
      "metadata": {},
      "source": [
        "<span id=\"optimize\" />\n",
        "\n",
        "<span id=\"step-2-optimize-the-circuits-and-operators\" />\n",
        "\n",
        "### Étape 2. Optimiser les circuits et les opérateurs\n",
        "\n",
        "Lors de l'exécution de circuits sur un appareil, il est important d'optimiser l'ensemble des instructions contenues dans le circuit et de minimiser la profondeur globale (grosso modo le nombre d'instructions) du circuit. Cela vous garantit d'obtenir les meilleurs résultats possibles en réduisant les effets des erreurs et du bruit. De plus, les instructions du circuit doivent être conformes à [l](/docs/guides/transpile#instruction-set-architecture) 'architecture du jeu d'instructions (ISA) du dispositif backend et doivent tenir compte des portes de base et de la connectivité des qubits du dispositif.\n",
        "\n",
        "Le code suivant instancie un périphérique réel auquel envoyer une tâche et transforme le circuit et les observables afin qu'ils correspondent à l'ISA de ce backend. Cela nécessite que vous ayez déjà [enregistré vos identifiants.](/docs/guides/cloud-setup)\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 4,
      "id": "9a901271",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "<Image src=\"/docs/images/guides/hello-world/extracted-outputs/9a901271-0.svg\" alt=\"Output of the previous code cell\" />"
            ]
          },
          "execution_count": 4,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "service = QiskitRuntimeService()\n",
        "\n",
        "backend = service.least_busy(simulator=False, operational=True)\n",
        "\n",
        "# Convert to an ISA circuit and layout-mapped observables.\n",
        "pm = generate_preset_pass_manager(backend=backend, optimization_level=1)\n",
        "isa_circuit = pm.run(qc)\n",
        "\n",
        "isa_circuit.draw(\"mpl\", idle_wires=False)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "9acac1d4",
      "metadata": {},
      "source": [
        "<span id=\"step-3-execute-using-the-quantum-primitives\" />\n",
        "\n",
        "### Étape 3. Exécuter à l'aide des primitives quantiques\n",
        "\n",
        "Les ordinateurs quantiques peuvent produire des résultats aléatoires; c'est pourquoi on recueille généralement un échantillon des résultats en exécutant le circuit à plusieurs reprises. Vous pouvez estimer la valeur de l'observable à l'aide de la `Estimator` classe. `Estimator` est l'une des deux [fonctions primitives](/docs/guides/get-started-with-estimator); l'autre est `Sampler`, qui permet d'extraire des données d'un ordinateur quantique.  Ces objets disposent d'une `run()` méthode qui effectue la sélection des circuits, des observables et des paramètres (le cas échéant), à l'aide d'un [bloc unifié primitif ( PUB )](/docs/guides/get-started-with-sampler).\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 5,
      "id": "62c4ca44",
      "metadata": {
        "tags": []
      },
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            ">>> Job ID: d9mqa588csec73fagtu0\n"
          ]
        }
      ],
      "source": [
        "# Construct the Estimator instance.\n",
        "\n",
        "estimator = Estimator(mode=backend)\n",
        "estimator.options.resilience_level = 1\n",
        "estimator.options.default_shots = 5000\n",
        "\n",
        "mapped_observables = [\n",
        "    observable.apply_layout(isa_circuit.layout) for observable in observables\n",
        "]\n",
        "\n",
        "# One pub, with one circuit to run against five different observables.\n",
        "job = estimator.run([(isa_circuit, mapped_observables)])\n",
        "\n",
        "# Use the job ID to retrieve your job data later\n",
        "print(f\">>> Job ID: {job.job_id()}\")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "47479e76",
      "metadata": {},
      "source": [
        "Une fois la tâche soumise, vous pouvez attendre qu'elle soit terminée dans votre instance Python actuelle ou utiliser `job_id` pour récupérer les données ultérieurement.  (Pour plus de détails, consultez la [section sur la récupération des tâches](/docs/guides/monitor-job#retrieve-job-results-at-a-later-time).)\n",
        "\n",
        "Une fois le travail terminé, examinez son résultat à l'aide de `result()` l'attribut du travail.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 6,
      "id": "792d2f01",
      "metadata": {},
      "outputs": [],
      "source": [
        "# This is the result of the entire submission.  You submitted one Pub,\n",
        "# so this contains one inner result (and some metadata of its own).\n",
        "job_result = job.result()\n",
        "\n",
        "# This is the result from our single pub, which had six observables,\n",
        "# so contains information on all six.\n",
        "pub_result = job.result()[0]"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "48317a25",
      "metadata": {},
      "source": [
        "<Admonition type=\"note\" title=\"Alternative : exécutez l'exemple à l'aide d'un simulateur\">\n",
        "  Lorsque vous exécutez votre programme quantique sur un appareil réel, votre charge de travail doit attendre dans une file d'attente avant d'être exécutée. Pour gagner du temps, vous pouvez utiliser le code suivant pour exécuter cette petite charge de travail [`fake_provider`](/docs/api/qiskit-ibm-runtime/fake-provider) en mode de test local `qiskit-ibm-runtime` . Notez que cela n'est possible que pour un petit circuit. Lorsque vous passerez à l'étape suivante, vous devrez utiliser un appareil réel.\n",
        "\n",
        "  ```python\n",
        "\n",
        "  # Use the following code instead if you want to run on a simulator:\n",
        "\n",
        "  from qiskit_ibm_runtime.fake_provider import FakeBelemV2\n",
        "  backend = FakeBelemV2()\n",
        "  estimator = Estimator(backend)\n",
        "\n",
        "  # Convert to an ISA circuit and layout-mapped observables.\n",
        "\n",
        "  pm = generate_preset_pass_manager(backend=backend, optimization_level=1)\n",
        "  isa_circuit = pm.run(qc)\n",
        "  mapped_observables = [\n",
        "      observable.apply_layout(isa_circuit.layout) for observable in observables\n",
        "  ]\n",
        "\n",
        "  job = estimator.run([(isa_circuit, mapped_observables)])\n",
        "  result = job.result()\n",
        "\n",
        "  # This is the result of the entire submission. You submitted one Pub,\n",
        "  # so this contains one inner result (and some metadata of its own).\n",
        "\n",
        "  job_result = job.result()\n",
        "\n",
        "  # This is the result from our single pub, which had five observables,\n",
        "  # so contains information on all five.\n",
        "\n",
        "  pub_result = job.result()[0]\n",
        "  ```\n",
        "</Admonition>\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "d200d1f8",
      "metadata": {},
      "source": [
        "<span id=\"step-4-analyze-the-results\" />\n",
        "\n",
        "### Étape 4 : Analyser les résultats\n",
        "\n",
        "L'étape d'analyse est généralement celle où vous pouvez post-traiter vos résultats en utilisant, par exemple, l'atténuation des erreurs de mesure ou l'extrapolation du bruit zéro (ZNE). Vous pouvez intégrer ces résultats dans un autre flux de travail pour une analyse plus approfondie ou préparer un graphique des valeurs et données clés. En général, cette étape est spécifique à votre problème.  Pour cet exemple, tracez chacune des valeurs attendues qui ont été mesurées pour notre circuit.\n",
        "\n",
        "Les valeurs attendues et les écarts-types des grandeurs observables que vous avez indiquées à Estimator sont accessibles via les attributs et `PubResult.data.stds` du `PubResult.data.evs` résultat de la tâche. Pour récupérer les résultats de Sampler, utilisez la `PubResult.data.meas.get_counts()` fonction, qui renvoie un `dict` tableau de mesures sous la forme de chaînes de bits en tant que clés et de nombres en tant que valeurs correspondantes. Pour plus d'informations, consultez le guide [de démarrage rapide de Sampler](/docs/guides/get-started-with-sampler).\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 8,
      "id": "87143fcc",
      "metadata": {
        "tags": []
      },
      "outputs": [
        {
          "data": {
            "text/plain": [
              "<Image src=\"/docs/images/guides/hello-world/extracted-outputs/87143fcc-0.svg\" alt=\"Output of the previous code cell\" />"
            ]
          },
          "metadata": {},
          "output_type": "display_data"
        }
      ],
      "source": [
        "# Plot the result\n",
        "\n",
        "values = pub_result.data.evs\n",
        "\n",
        "errors = pub_result.data.stds\n",
        "\n",
        "# plotting graph\n",
        "plt.plot(observables_labels, values, \"-o\")\n",
        "plt.xlabel(\"Observables\")\n",
        "plt.ylabel(\"Values\")\n",
        "plt.show()"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "e6a9ba84",
      "metadata": {},
      "source": [
        "Notez que pour les qubits 0 et 1, les valeurs attendues indépendantes de X et Z sont toutes deux égales à 0, tandis que les corrélations (`XX` et `ZZ`) sont égales à 1. C'est une caractéristique distinctive de l'intrication quantique.\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "0bc582d8",
      "metadata": {},
      "source": [
        "<span id=\"scale-to-large-numbers-of-qubits\" />\n",
        "\n",
        "## Évolutivité vers un grand nombre de qubits\n",
        "\n",
        "Dans le domaine de l'informatique quantique, les travaux à l'échelle industrielle sont essentiels pour faire progresser la recherche. Ce type de travail nécessite des calculs à une échelle beaucoup plus grande, avec des circuits pouvant utiliser plus de 100 qubits et plus de 1 000 portes. Cet exemple montre comment vous pouvez réaliser des travaux à l'échelle industrielle sur IBM® des QPU en créant et en analysant un état GHZ de 100 qubits.  Il utilise le workflow Qiskit patterns et se termine par la mesure de la valeur $\\langle Z_0 Z_i \\rangle $ attendue pour chaque qubit.\n",
        "\n",
        "<span id=\"step-1-map-the-problem\" />\n",
        "\n",
        "### Etape 1. Cartographier le problème\n",
        "\n",
        "Écrivez une fonction qui renvoie un `QuantumCircuit` qui prépare un état $n$ GHZ à qubits (essentiellement un état de Bell étendu), puis utilisez cette fonction pour préparer un état GHZ à 100 qubits et collecter les observables à mesurer.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 10,
      "id": "2ac02692",
      "metadata": {},
      "outputs": [],
      "source": [
        "def get_qc_for_n_qubit_GHZ_state(n: int) -> QuantumCircuit:\n",
        "    \"\"\"This function will create a qiskit.QuantumCircuit (qc)\n",
        "        for an n-qubit GHZ state.\n",
        "\n",
        "    Args:\n",
        "        n (int): Number of qubits in the n-qubit GHZ state\n",
        "\n",
        "    Returns:\n",
        "        QuantumCircuit: Quantum circuit that generate the n-qubit GHZ state,\n",
        "            assuming all qubits start in the 0 state\n",
        "    \"\"\"\n",
        "    if isinstance(n, int) and n >= 2:\n",
        "        qc = QuantumCircuit(n)\n",
        "        qc.h(0)\n",
        "        for i in range(n - 1):\n",
        "            qc.cx(i, i + 1)\n",
        "    else:\n",
        "        raise Exception(\"n is not a valid input\")\n",
        "    return qc\n",
        "\n",
        "\n",
        "# Create a new circuit with 100 qubits in the GHZ state\n",
        "n = 100\n",
        "qc = get_qc_for_n_qubit_GHZ_state(n)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "5b3d0d74",
      "metadata": {},
      "source": [
        "Ensuite, mappez les opérateurs qui vous intéressent. Cet exemple utilise les `ZZ` opérateurs entre qubits pour examiner leur comportement à mesure qu'ils s'éloignent les uns des autres.  Des valeurs d'attente de plus en plus inexactes (corrompues) entre des qubits distants révéleraient le niveau de bruit présent.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 11,
      "id": "863a4ec9",
      "metadata": {},
      "outputs": [],
      "source": [
        "# ZZII...II, ZIZI...II, ... , ZIII...IZ\n",
        "operator_strings = [\n",
        "    \"Z\" + \"I\" * i + \"Z\" + \"I\" * (n - 2 - i) for i in range(n - 1)\n",
        "]\n",
        "\n",
        "operators = [SparsePauliOp(operator) for operator in operator_strings]"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "a0b462ce",
      "metadata": {},
      "source": [
        "<span id=\"step-2-optimize-the-problem-for-execution-on-quantum-hardware\" />\n",
        "\n",
        "### Étape 2. Optimiser le problème pour l'exécution sur du matériel quantique\n",
        "\n",
        "Le code suivant transforme le circuit et les observables afin qu'ils correspondent à l'ISA du backend. Cela nécessite que vous ayez déjà [enregistré vos identifiants.](/docs/guides/cloud-setup)\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 12,
      "id": "428f05e7",
      "metadata": {},
      "outputs": [],
      "source": [
        "service = QiskitRuntimeService()\n",
        "\n",
        "backend = service.least_busy(\n",
        "    simulator=False, operational=True, min_num_qubits=100\n",
        ")\n",
        "pm = generate_preset_pass_manager(optimization_level=1, backend=backend)\n",
        "\n",
        "isa_circuit = pm.run(qc)\n",
        "isa_operators_list = [op.apply_layout(isa_circuit.layout) for op in operators]"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "2d2b5065",
      "metadata": {},
      "source": [
        "<span id=\"step-3-execute-on-hardware\" />\n",
        "\n",
        "### Étape 3. Exécuter sur le matériel\n",
        "\n",
        "Soumettez la tâche et activez la suppression des erreurs à l'aide d'une technique permettant de réduire les erreurs, appelée « [découplage dynamique](/docs/api/qiskit-ibm-runtime/options-dynamical-decoupling-options) ». Le niveau de résilience détermine le degré de résilience à mettre en place face aux erreurs. Des niveaux plus élevés permettent d'obtenir des résultats plus précis, au prix d'un temps de traitement plus long.  Pour plus d'explications sur les options définies dans le code ci-dessous, consultez la section « [Techniques d'atténuation et de suppression des erreurs](/docs/guides/error-mitigation-and-suppression-techniques) ».\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 13,
      "id": "3aaa5025",
      "metadata": {},
      "outputs": [],
      "source": [
        "options = EstimatorOptions()\n",
        "options.resilience_level = 1\n",
        "options.dynamical_decoupling.enable = True\n",
        "options.dynamical_decoupling.sequence_type = \"XY4\"\n",
        "\n",
        "# Create an Estimator object\n",
        "estimator = Estimator(backend, options=options)"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 14,
      "id": "b4c3d3e7-0a0f-4023-8948-1082e225f46c",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "d9mqnjmh4e6s738vioqg\n"
          ]
        }
      ],
      "source": [
        "# Submit the circuit to Estimator\n",
        "job = estimator.run([(isa_circuit, isa_operators_list)])\n",
        "job_id = job.job_id()\n",
        "print(job_id)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "0bc64091",
      "metadata": {},
      "source": [
        "<span id=\"step-4-post-process-results\" />\n",
        "\n",
        "### Étape 4 : Résultats du post-traitement\n",
        "\n",
        "Une fois le travail terminé, tracez les résultats et remarquez que $\\langle Z_0 Z_i \\rangle$ diminue à mesure que augmente $i$, même si dans une simulation idéale, tous les $\\langle Z_0 Z_i \\rangle$ devraient être égaux à 1.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 15,
      "id": "de91ebd0",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "<Image src=\"/docs/images/guides/hello-world/extracted-outputs/de91ebd0-0.svg\" alt=\"Output of the previous code cell\" />"
            ]
          },
          "metadata": {},
          "output_type": "display_data"
        }
      ],
      "source": [
        "# data\n",
        "data = list(range(1, len(operators) + 1))  # Distance between the Z operators\n",
        "result = job.result()[0]\n",
        "values = result.data.evs  # Expectation value at each Z operator.\n",
        "values = [\n",
        "    v / values[0] for v in values\n",
        "]  # Normalize the expectation values to evaluate how they decay with distance.\n",
        "\n",
        "# plotting graph\n",
        "plt.plot(data, values, marker=\"o\", label=\"100-qubit GHZ state\")\n",
        "plt.xlabel(\"Distance between qubits $i$\")\n",
        "plt.ylabel(r\"$\\langle Z_i Z_0 \\rangle / \\langle Z_1 Z_0 \\rangle $\")\n",
        "plt.legend()\n",
        "plt.show()"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "0afc307c",
      "metadata": {},
      "source": [
        "Le graphique précédent montre que lorsque la distance entre les qubits augmente, le signal s'affaiblit en raison de la présence de bruit.\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "e7c24c81",
      "metadata": {},
      "source": [
        "<span id=\"next-steps\" />\n",
        "\n",
        "## Etapes suivantes\n",
        "\n",
        "<Admonition type=\"tip\" title=\"Recommandations\">\n",
        "  * Essayez l'un de ces tutoriels :\n",
        "    * [Estimation de l'énergie de l'état fondamental de la chaîne de Heisenberg avec VQE](/docs/tutorials/spin-chain-vqe)\n",
        "    * Résoudre des problèmes d'optimisation à l'aide [du QAOA](/docs/tutorials/quantum-approximate-optimization-algorithm)\n",
        "    * Entraîner des modèles [de noyau quantique](/docs/tutorials/quantum-kernel-training) pour des tâches d'apprentissage automatique\n",
        "  * Vous trouverez des instructions d'installation détaillées dans le guide [d'installation de Qiskit](/docs/guides/install-qiskit).\n",
        "  * Si vous préférez ne pas installer Qiskit localement, consultez les options permettant d'utiliser Qiskit dans un [environnement de développement en ligne](/docs/guides/online-lab-environments).\n",
        "  * Pour enregistrer plusieurs identifiants de compte ou pour spécifier d'autres options de compte, consultez les instructions détaillées dans le guide [Enregistrer vos identifiants de connexion](/docs/guides/save-credentials#save-your-access-credentials).\n",
        "</Admonition>\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "id": "a1b8767d",
      "source": "© IBM Corp., 2017-2026"
    }
  ],
  "metadata": {
    "celltoolbar": "Raw Cell Format",
    "hours": 0.5,
    "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"
    },
    "widgets": {
      "application/vnd.jupyter.widget-state+json": {
        "state": {},
        "version_major": 2,
        "version_minor": 0
      }
    }
  },
  "nbformat": 4,
  "nbformat_minor": 5
}