{
  "cells": [
    {
      "cell_type": "markdown",
      "id": "b97a7e0a-66a6-46b2-b33f-47feeefad60d",
      "metadata": {},
      "source": [
        "---\n",
        "title: \"Utilitaire II\"\n",
        "description: \"Ce cahier suit les méthodes et techniques de la leçon 7. Notre objectif est de résoudre numériquement l'équation de Schrödinger dépendante du temps.\"\n",
        "---\n",
        "\n",
        "{/* cspell:ignore sharex */}\n",
        "\n",
        "<span id=\"utility-scale-experiment-ii\" />\n",
        "\n",
        "# Expérience à l'échelle industrielle II\n",
        "\n",
        "<Admonition type=\"note\">\n",
        "  Yukio Kawashima (12 juillet 2024)\n",
        "\n",
        "  [Télécharger le pdf](https://ibm.ent.box.com/s/bipgoms7gr6b6vhkoc1uw6oi4wsanfoq) de la conférence originale. Notez que certains extraits de code peuvent devenir obsolètes car il s'agit d'images statiques.\n",
        "\n",
        "  *Le temps approximatif d'exécution de cette expérience par la QPU est de 2 m 30 s.*\n",
        "\n",
        "  (Ce cahier utilise des textes, des illustrations et des codes provenant d'un [cahier de travaux dirigés](https://github.com/qiskit-community/qiskit-algorithms/blob/main/docs/tutorials/13_trotterQRTE.ipynb) sur les algorithmes Qiskit, aujourd'hui abandonné)\n",
        "</Admonition>\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "76421ffc-f47f-46a4-8198-af3bc21e3c5d",
      "metadata": {},
      "source": [
        "<span id=\"1-introduction-and-review-of-time-evolution\" />\n",
        "\n",
        "## 1. Introduction et examen de l'évolution dans le temps\n",
        "\n",
        "Ce cahier suit les méthodes et techniques de la leçon 7. Notre objectif est de résoudre numériquement l'équation de Schrödinger dépendante du temps. Comme nous l'avons vu dans la leçon 7, la trotterisation consiste en l'application successive d'une ou plusieurs portes quantiques, choisies pour approximer l'évolution temporelle d'un système pour une tranche de temps donnée. Nous reprenons ici cette discussion par souci de commodité. N'hésitez pas à passer aux cellules de code ci-dessous si vous avez récemment révisé la leçon 7.\n",
        "\n",
        "A partir de l'équation de Schrödinger, l'évolution temporelle d'un système initialement dans l'état $\\vert\\psi(0)\\rangle$ prend la forme :\n",
        "\n",
        "$$\n",
        "\\vert \\psi(t) \\rangle = e^{-i H t} \\vert \\psi(0) \\rangle \\text{,}\n",
        "$$\n",
        "\n",
        "où $H$ est le hamiltonien indépendant du temps qui régit le système. Nous considérons un hamiltonien qui peut être écrit comme une somme pondérée de termes de Pauli $H=\\sum_j a_j P_j$, $P_j$ représentant un produit tensoriel de termes de Pauli agissant sur $n$ qubits. En particulier, ces termes de Pauli peuvent commuter entre eux ou non. Étant donné un état à l'instant $t=0$, comment obtenir l'état du système à un instant ultérieur $|\\psi(t)\\rangle$ à l'aide d'un ordinateur quantique? L'exponentielle d'un opérateur peut être plus facilement comprise à travers sa série de Taylor :\n",
        "\n",
        "$$\n",
        "e^{-i H t} = 1-iHt-\\frac{1}{2}H^2t^2+...\n",
        "$$\n",
        "\n",
        "Certaines exponentielles très basiques, comme $e^{iZ}$, peuvent être facilement mises en œuvre sur des ordinateurs quantiques à l'aide d'un ensemble compact de portes quantiques. La plupart des hamiltoniens qui nous intéressent n'ont pas un seul terme, mais plusieurs. Notez ce qui se passe si $H = H_1+H_2$ :\n",
        "\n",
        "$$\n",
        "e^{-i H t} = 1-i(H_1+H_2)t-\\frac{1}{2}(H_1+H_2)^2t^2+...\n",
        "$$\n",
        "\n",
        "Lorsque $H_1$ et $H_2$ commutent, nous avons le cas familier (qui est également vrai pour les nombres, et les variables $a$ et $b$ ci-dessous) :\n",
        "\n",
        "$$\n",
        "e^{-i (a+b) t} = e^{-i a t}e^{-i b t}\n",
        "$$\n",
        "\n",
        "Mais lorsque les opérateurs ne commutent pas, les termes ne peuvent pas être réarrangés dans la série de Taylor pour simplifier de cette manière. L'expression d'hamiltoniens compliqués dans des portes quantiques constitue donc un défi.\n",
        "\n",
        "Une solution consiste à considérer un temps très petit $t$, de sorte que le terme du premier ordre dans l'expansion de Taylor domine. Dans cette hypothèse :\n",
        "\n",
        "$$\n",
        "e^{-i (H_1+H_2) t} \\approx 1-i(H_1+H_2)t \\approx (1-i H_1 t)(1-i H_2 t) \\approx e^{-i H_1 t}e^{-i H_2 t}\n",
        "$$\n",
        "\n",
        "Bien entendu, il se peut que nous devions faire évoluer notre état pendant une période plus longue. Pour ce faire, il est nécessaire de procéder à de nombreux petits pas dans le temps. Ce processus s'appelle la trotterisation :\n",
        "\n",
        "$$\n",
        "\\vert \\psi(t) \\rangle \\approx \\left(\\prod_j e^{-i a_j P_j t/r} \\right)^r \\vert\\psi(0) \\rangle \\text{,}\n",
        "$$\n",
        "\n",
        "Ici, $t/r$ est la tranche de temps (étape de l'évolution) que nous choisissons. Il en résulte une porte à appliquer $r$ fois. Un pas de temps plus petit conduit à une approximation plus précise. Toutefois, cela conduit également à des circuits plus profonds qui, dans la pratique, entraînent une plus grande accumulation d'erreurs (un problème non négligeable pour les dispositifs quantiques à court terme).\n",
        "\n",
        "Aujourd'hui, nous allons étudier l'évolution temporelle du [modèle d'Ising](https://en.wikipedia.org/wiki/Ising_model) sur des treillis linéaires de sites $N=2$ et $N=6$. Ces treillis sont constitués d'un réseau de spins $\\sigma_i$ qui n'interagissent qu'avec leurs voisins les plus proches. Ces spins peuvent avoir deux orientations : $\\uparrow$ et $\\downarrow$, qui correspondent à une magnétisation de $+1$ et $-1$ respectivement.\n",
        "\n",
        "$$\n",
        "H = - J \\sum_{i=0}^{N-2} Z_i Z_{i+1} - h \\sum_{i=0}^{N-1} X_i  \\text{,}\n",
        "$$\n",
        "\n",
        "où $J$ décrit l'énergie d'interaction et $h$ l'amplitude d'un champ externe (dans la direction x ci-dessus, mais nous modifierons cette valeur). Écrivons cette expression en utilisant les matrices de Pauli, et en considérant que le champ externe a un angle $\\alpha$ par rapport à la direction transversale,\n",
        "\n",
        "$$\n",
        "H = -J \\sum_{i=0}^{N-2} Z_i Z_{i+1} -h \\sum_{i=0}^{N-1} (\\sin\\alpha Z_i + \\cos\\alpha X_i) \\text{.}\n",
        "$$\n",
        "\n",
        "Ce hamiltonien est utile car il nous permet d'étudier facilement les effets d'un champ extérieur. Dans la base de calcul, le système sera codé comme suit :\n",
        "\n",
        "|      État quantique      |           Représentation du spin           |\n",
        "| :----------------------: | :----------------------------------------: |\n",
        "| $\\lvert 0 0 0 0 \\rangle$ |     $\\uparrow\\uparrow\\uparrow\\uparrow$     |\n",
        "| $\\lvert 1 0 0 0 \\rangle$ |    $\\downarrow\\uparrow\\uparrow\\uparrow$    |\n",
        "|         $\\ldots$         |                  $\\ldots$                  |\n",
        "| $\\lvert 1 1 1 1 \\rangle$ | $\\downarrow\\downarrow\\downarrow\\downarrow$ |\n",
        "\n",
        "Nous commencerons par étudier l'évolution temporelle d'un tel système quantique. Plus précisément, nous visualiserons l'évolution dans le temps de certaines propriétés du système, comme l'aimantation.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 1,
      "id": "81aff7b3-67e5-453b-9f5b-68baf5209560",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "'2.0.2'"
            ]
          },
          "execution_count": 1,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "# Check the version of Qiskit\n",
        "import qiskit\n",
        "\n",
        "qiskit.__version__"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 2,
      "id": "c88eda88-da8a-4e5e-9b8b-53ac0d0ed91b",
      "metadata": {
        "scrolled": true,
        "tags": []
      },
      "outputs": [],
      "source": [
        "# Import the qiskit library\n",
        "\n",
        "import numpy as np\n",
        "import warnings\n",
        "\n",
        "from qiskit import QuantumCircuit, QuantumRegister\n",
        "from qiskit.circuit.library import PauliEvolutionGate\n",
        "from qiskit.quantum_info import SparsePauliOp\n",
        "from qiskit.synthesis import LieTrotter\n",
        "from qiskit.transpiler.preset_passmanagers import generate_preset_pass_manager\n",
        "\n",
        "from qiskit_aer import AerSimulator\n",
        "from qiskit_ibm_runtime import QiskitRuntimeService, Estimator\n",
        "\n",
        "warnings.filterwarnings(\"ignore\")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "ed6c1602-d994-46d6-9426-d38272a63d56",
      "metadata": {},
      "source": [
        "<span id=\"2-defining-the-transverse-field-ising-hamiltonian\" />\n",
        "\n",
        "## 2. Définition de l'hamiltonien d'Ising à champ transversal\n",
        "\n",
        "Nous considérons ici le modèle d'Ising à champ transverse 1-D.\n",
        "\n",
        "Tout d'abord, nous allons créer une fonction qui prend en compte les paramètres du système $N$, $J$, et $h$, et renvoie notre hamiltonien sous la forme d'un `SparsePauliOp`. A [SparsePauliOp](/docs/api/qiskit/qiskit.quantum_info.SparsePauliOp) est une représentation éparse d'un opérateur en termes de termes de [Pauli](/docs/api/qiskit/qiskit.quantum_info.Pauli) pondérés.\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "b3137f47-640a-4382-95b6-6bb9e760bc96",
      "metadata": {},
      "source": [
        "<span id=\"21-activity-1\" />\n",
        "\n",
        "### 2.1 Activité 1\n",
        "\n",
        "Construire une fonction pour construire un hamiltonien d'Ising à champ transverse (voir l'équation ci-dessus) avec comme arguments \"le nombre de qubits\", \"le paramètre J\" et \"le paramètre h\". Essayez de le faire vous-même en utilisant les exemples précédents. Faites défiler la page vers le bas pour connaître la solution.\n",
        "\n",
        "**La solution :**\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 3,
      "id": "3de92af7-7504-4dca-b0b4-0d934f0c2069",
      "metadata": {},
      "outputs": [],
      "source": [
        "def get_hamiltonian(nqubits, J, h):\n",
        "    # List of Hamiltonian terms as 3-tuples containing\n",
        "    # (1) the Pauli string,\n",
        "    # (2) the qubit indices corresponding to the Pauli string,\n",
        "    # (3) the coefficient.\n",
        "    ZZ_tuples = [(\"ZZ\", [i, i + 1], -J) for i in range(0, nqubits - 1)]\n",
        "    X_tuples = [(\"X\", [i], -h) for i in range(0, nqubits)]\n",
        "\n",
        "    # We create the Hamiltonian as a SparsePauliOp, via the method\n",
        "    # `from_sparse_list`, and multiply by the interaction term.\n",
        "    hamiltonian = SparsePauliOp.from_sparse_list(\n",
        "        [*ZZ_tuples, *X_tuples], num_qubits=nqubits\n",
        "    )\n",
        "    return hamiltonian.simplify()"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "8b147fb0-6c3e-4eaf-8553-8850b53ff121",
      "metadata": {},
      "source": [
        "Nous commencerons par étudier l'évolution temporelle d'un système quantique, tout en suivant l'évolution de l'aimantation.\n",
        "Nous comparons ici les résultats des simulateurs Statevector et Matrix Product State.\n",
        "\n",
        "<span id=\"define-the-hamiltonian\" />\n",
        "\n",
        "#### Définir l'hamiltonien\n",
        "\n",
        "Le système que nous considérons maintenant a une taille de $N=20$.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 4,
      "id": "56764f93-3851-4b1c-b9e2-ea34161ddd85",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "SparsePauliOp(['IIIIIIIIIIIIIIIIIIZZ', 'IIIIIIIIIIIIIIIIIZZI', 'IIIIIIIIIIIIIIIIZZII', 'IIIIIIIIIIIIIIIZZIII', 'IIIIIIIIIIIIIIZZIIII', 'IIIIIIIIIIIIIZZIIIII', 'IIIIIIIIIIIIZZIIIIII', 'IIIIIIIIIIIZZIIIIIII', 'IIIIIIIIIIZZIIIIIIII', 'IIIIIIIIIZZIIIIIIIII', 'IIIIIIIIZZIIIIIIIIII', 'IIIIIIIZZIIIIIIIIIII', 'IIIIIIZZIIIIIIIIIIII', 'IIIIIZZIIIIIIIIIIIII', 'IIIIZZIIIIIIIIIIIIII', 'IIIZZIIIIIIIIIIIIIII', 'IIZZIIIIIIIIIIIIIIII', 'IZZIIIIIIIIIIIIIIIII', 'ZZIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIX', 'IIIIIIIIIIIIIIIIIIXI', 'IIIIIIIIIIIIIIIIIXII', 'IIIIIIIIIIIIIIIIXIII', 'IIIIIIIIIIIIIIIXIIII', 'IIIIIIIIIIIIIIXIIIII', 'IIIIIIIIIIIIIXIIIIII', 'IIIIIIIIIIIIXIIIIIII', 'IIIIIIIIIIIXIIIIIIII', 'IIIIIIIIIIXIIIIIIIII', 'IIIIIIIIIXIIIIIIIIII', 'IIIIIIIIXIIIIIIIIIII', 'IIIIIIIXIIIIIIIIIIII', 'IIIIIIXIIIIIIIIIIIII', 'IIIIIXIIIIIIIIIIIIII', 'IIIIXIIIIIIIIIIIIIII', 'IIIXIIIIIIIIIIIIIIII', 'IIXIIIIIIIIIIIIIIIII', 'IXIIIIIIIIIIIIIIIIII', 'XIIIIIIIIIIIIIIIIIII'],\n",
              "              coeffs=[-1.+0.j, -1.+0.j, -1.+0.j, -1.+0.j, -1.+0.j, -1.+0.j, -1.+0.j, -1.+0.j,\n",
              " -1.+0.j, -1.+0.j, -1.+0.j, -1.+0.j, -1.+0.j, -1.+0.j, -1.+0.j, -1.+0.j,\n",
              " -1.+0.j, -1.+0.j, -1.+0.j,  5.+0.j,  5.+0.j,  5.+0.j,  5.+0.j,  5.+0.j,\n",
              "  5.+0.j,  5.+0.j,  5.+0.j,  5.+0.j,  5.+0.j,  5.+0.j,  5.+0.j,  5.+0.j,\n",
              "  5.+0.j,  5.+0.j,  5.+0.j,  5.+0.j,  5.+0.j,  5.+0.j,  5.+0.j])"
            ]
          },
          "execution_count": 4,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "n_qubits = 20\n",
        "hamiltonian = get_hamiltonian(nqubits=n_qubits, J=1.0, h=-5.0)\n",
        "hamiltonian"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "eb075fee-fdb5-4016-bea2-643b444062b8",
      "metadata": {},
      "source": [
        "<span id=\"set-the-parameters-of-the-time-evolution-simulation\" />\n",
        "\n",
        "#### Définir les paramètres de la simulation d'évolution temporelle\n",
        "\n",
        "Nous considérons ici le Lie-Trotter (premier ordre).\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 5,
      "id": "3a5af3d3-015b-4a5c-86cd-52830067a1e2",
      "metadata": {},
      "outputs": [],
      "source": [
        "num_timesteps = 20\n",
        "evolution_time = 2.0\n",
        "dt = evolution_time / num_timesteps\n",
        "product_formula_lt = LieTrotter()"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "e5fc52a2-15af-464f-aac2-890417745c82",
      "metadata": {},
      "source": [
        "<span id=\"prepare-the-quantum-circuit-initial-state\" />\n",
        "\n",
        "#### Préparer le circuit quantique (état initial)\n",
        "\n",
        "Créer un état initial. Nous partirons de l'état fondamental, qui est un état ferromagnétique (tout en haut ou tout en bas). Ici, nous utilisons un exemple de tous les \"ups\" (qui sont tous \"0\").\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 6,
      "id": "64f622f2-6e1c-4b42-b548-dd3e5aa32786",
      "metadata": {
        "scrolled": true,
        "tags": []
      },
      "outputs": [
        {
          "data": {
            "text/plain": [
              "<Image src=\"/learning/images/courses/utility-scale-quantum-computing/utility-ii/extracted-outputs/f3f6c2f1-63b7-4bb8-83d3-af579900ea6f-0.avif\" alt=\"Output of the previous code cell\" />"
            ]
          },
          "execution_count": 6,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "initial_circuit = QuantumCircuit(n_qubits)\n",
        "initial_circuit.prepare_state(\"00000000000000000000\")\n",
        "# Change reps and see the difference when you decompose the circuit\n",
        "initial_circuit.decompose(reps=1).draw(\"mpl\")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "dab0957f-186f-475f-bdee-907469b54174",
      "metadata": {},
      "source": [
        "<span id=\"prepare-the-quantum-circuit-2-single-circuit-for-time-evolution\" />\n",
        "\n",
        "#### Préparer le circuit quantique 2 (circuit unique pour l'évolution temporelle)\n",
        "\n",
        "Nous construisons ici un circuit pour un seul pas de temps en utilisant Lie-Trotter.\n",
        "La formule du produit de Lie (premier ordre) est implémentée dans la classe [LieTrotter](/docs/api/qiskit/qiskit.synthesis.LieTrotter) classe. Une formule du premier ordre consiste en l'approximation mentionnée dans l'introduction, où l'exponentielle matricielle d'une somme est approximée par un produit d'exponentielles matricielles :\n",
        "\n",
        "$$\n",
        "e^{H_1+H_2} \\approx e^{H_1} e^{H_2}\n",
        "$$\n",
        "\n",
        "Comptons les opérations pour ce circuit.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 7,
      "id": "b812f4b6-fb83-4c89-a8bc-ac0d85784720",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "\n",
            "Trotter step with Lie-Trotter\n",
            "-----------------------------\n",
            "Depth: 58\n",
            "Gate count: 77\n",
            "Nonlocal gate count: 38\n",
            "Gate breakdown: CX: 38, U3: 20, U1: 19\n",
            "\n"
          ]
        },
        {
          "data": {
            "text/plain": [
              "<Image src=\"/learning/images/courses/utility-scale-quantum-computing/utility-ii/extracted-outputs/dbc253b8-17a1-4cb7-aede-bddfa59fab8a-1.avif\" alt=\"Output of the previous code cell\" />"
            ]
          },
          "execution_count": 7,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "single_step_evolution_gates_lt = PauliEvolutionGate(\n",
        "    hamiltonian, dt, synthesis=product_formula_lt\n",
        ")\n",
        "single_step_evolution_lt = QuantumCircuit(n_qubits)\n",
        "single_step_evolution_lt.append(\n",
        "    single_step_evolution_gates_lt, single_step_evolution_lt.qubits\n",
        ")\n",
        "\n",
        "print(\n",
        "    f\"\"\"\n",
        "Trotter step with Lie-Trotter\n",
        "-----------------------------\n",
        "Depth: {single_step_evolution_lt.decompose(reps=3).depth()}\n",
        "Gate count: {len(single_step_evolution_lt.decompose(reps=3))}\n",
        "Nonlocal gate count: {single_step_evolution_lt.decompose(reps=3).num_nonlocal_gates()}\n",
        "Gate breakdown: {\", \".join([f\"{k.upper()}: {v}\" for k, v in single_step_evolution_lt.decompose(reps=3).count_ops().items()])}\n",
        "\"\"\"\n",
        ")\n",
        "single_step_evolution_lt.decompose(reps=3).draw(\"mpl\", fold=-1)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "474e7a29-82bc-470e-8556-87e88195f213",
      "metadata": {},
      "source": [
        "<span id=\"set-the-operators-to-be-measured\" />\n",
        "\n",
        "#### Définir les opérateurs à mesurer\n",
        "\n",
        "Définissons un *opérateur d'aimantation* $\\sum_i Z_i  / N$.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 8,
      "id": "2488d18d-70f0-43a2-9675-4d34562e47ce",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "magnetization :  SparsePauliOp(['IIIIIIIIIIIIIIIIIIIZ', 'IIIIIIIIIIIIIIIIIIZI', 'IIIIIIIIIIIIIIIIIZII', 'IIIIIIIIIIIIIIIIZIII', 'IIIIIIIIIIIIIIIZIIII', 'IIIIIIIIIIIIIIZIIIII', 'IIIIIIIIIIIIIZIIIIII', 'IIIIIIIIIIIIZIIIIIII', 'IIIIIIIIIIIZIIIIIIII', 'IIIIIIIIIIZIIIIIIIII', 'IIIIIIIIIZIIIIIIIIII', 'IIIIIIIIZIIIIIIIIIII', 'IIIIIIIZIIIIIIIIIIII', 'IIIIIIZIIIIIIIIIIIII', 'IIIIIZIIIIIIIIIIIIII', 'IIIIZIIIIIIIIIIIIIII', 'IIIZIIIIIIIIIIIIIIII', 'IIZIIIIIIIIIIIIIIIII', 'IZIIIIIIIIIIIIIIIIII', 'ZIIIIIIIIIIIIIIIIIII'],\n",
            "              coeffs=[0.05+0.j, 0.05+0.j, 0.05+0.j, 0.05+0.j, 0.05+0.j, 0.05+0.j, 0.05+0.j,\n",
            " 0.05+0.j, 0.05+0.j, 0.05+0.j, 0.05+0.j, 0.05+0.j, 0.05+0.j, 0.05+0.j,\n",
            " 0.05+0.j, 0.05+0.j, 0.05+0.j, 0.05+0.j, 0.05+0.j, 0.05+0.j])\n"
          ]
        }
      ],
      "source": [
        "magnetization = (\n",
        "    SparsePauliOp.from_sparse_list(\n",
        "        [(\"Z\", [i], 1.0) for i in range(0, n_qubits)], num_qubits=n_qubits\n",
        "    )\n",
        "    / n_qubits\n",
        ")\n",
        "print(\"magnetization : \", magnetization)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "308ed03d-432d-4113-9c06-2ce10c02ecd5",
      "metadata": {},
      "source": [
        "<span id=\"perform-time-evolution-simulation\" />\n",
        "\n",
        "#### Effectuer une simulation d'évolution temporelle\n",
        "\n",
        "Nous surveillerons l'aimantation (valeur d'espérance de l'opérateur d'aimantation). Nous utiliserons les simulateurs Statevector et MPS et comparerons les résultats.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 9,
      "id": "25bd2824-009e-4d76-be83-a906bf8b0d44",
      "metadata": {
        "scrolled": true
      },
      "outputs": [],
      "source": [
        "# Step 1. Map the problem\n",
        "# Initiate the circuit\n",
        "evolved_state = QuantumCircuit(initial_circuit.num_qubits)\n",
        "# Start from the initial spin configuration\n",
        "evolved_state.append(initial_circuit, evolved_state.qubits)\n",
        "\n",
        "# Define backend (simulator)\n",
        "# MPS\n",
        "backend_mps = AerSimulator(method=\"matrix_product_state\")\n",
        "# Statevector\n",
        "backend_sv = AerSimulator(method=\"statevector\")\n",
        "\n",
        "# Set Runtime Estimator\n",
        "# MPS\n",
        "estimator_mps = Estimator(mode=backend_mps)\n",
        "# Statevector\n",
        "estimator_sv = Estimator(mode=backend_sv)\n",
        "\n",
        "# Step 2. Optimize\n",
        "# Set pass manager\n",
        "# MPS\n",
        "pm_mps = generate_preset_pass_manager(optimization_level=3, backend=backend_mps)\n",
        "# Statevector\n",
        "pm_sv = generate_preset_pass_manager(optimization_level=3, backend=backend_sv)\n",
        "\n",
        "# Transpile initial circuit\n",
        "# MPS\n",
        "evolved_state_mps = pm_mps.run(evolved_state)\n",
        "# Statevector\n",
        "evolved_state_sv = pm_sv.run(evolved_state)\n",
        "\n",
        "# Apply layout to the operator\n",
        "# MPS\n",
        "magnetization_mps = magnetization.apply_layout(evolved_state_mps.layout)\n",
        "# Statevector\n",
        "magnetization_sv = magnetization.apply_layout(evolved_state_sv.layout)\n",
        "\n",
        "mag_mps_list = []\n",
        "mag_sv_list = []\n",
        "\n",
        "# Step 3. Run the circuit\n",
        "# Estimate expectation values for t=0.0: MPS\n",
        "job = estimator_mps.run([(evolved_state_mps, [magnetization_mps])])\n",
        "# Get estimated expectation values: MPS\n",
        "evs = job.result()[0].data.evs\n",
        "# Collect data: MPS\n",
        "mag_mps_list.append(evs[0])\n",
        "\n",
        "# Estimate expectation values for t=0.0: Statevector\n",
        "job = estimator_sv.run([(evolved_state_sv, [magnetization_sv])])\n",
        "# Get estimated expectation values: Statevector\n",
        "evs = job.result()[0].data.evs\n",
        "# Collect data: Statevector\n",
        "mag_sv_list.append(evs[0])\n",
        "\n",
        "# Start time evolution\n",
        "for n in range(num_timesteps):\n",
        "    # Step 1. Map the problem\n",
        "    # Expand the circuit to describe delta-t\n",
        "    evolved_state.append(single_step_evolution_lt, evolved_state.qubits)\n",
        "    # Step 2. Optimize\n",
        "    # Transpile the circuit: MPS\n",
        "    evolved_state_mps = pm_mps.run(evolved_state)\n",
        "    # Apply the physical layout of the qubits to the operator: MPS\n",
        "    magnetization_mps = magnetization.apply_layout(evolved_state_mps.layout)\n",
        "    # Step 3. Run the circuit\n",
        "    # Estimate expectation values at delta-t: MPS\n",
        "    job = estimator_mps.run([(evolved_state_mps, [magnetization_mps])])\n",
        "    # Get estimated expectation values: MPS\n",
        "    evs = job.result()[0].data.evs\n",
        "    # Collect data: MPS\n",
        "    mag_mps_list.append(evs[0])\n",
        "\n",
        "    # Step 2. Optimize\n",
        "    # Transpile the circuit: Statevector\n",
        "    evolved_state_sv = pm_sv.run(evolved_state)\n",
        "    # Apply the physical layout of the qubits to the operator: Statevector\n",
        "    magnetization_sv = magnetization.apply_layout(evolved_state_sv.layout)\n",
        "    # Step 3. Run the circuit\n",
        "    # Estimate expectation values at delta-t: Statevector\n",
        "    job = estimator_sv.run([(evolved_state_sv, [magnetization_sv])])\n",
        "    # Get estimated expectation values: Statevector\n",
        "    evs = job.result()[0].data.evs\n",
        "    # Collect data: Statevector\n",
        "    mag_sv_list.append(evs[0])\n",
        "\n",
        "# Transform the list of expectation values (at each time step) to arrays\n",
        "mag_mps_array = np.array(mag_mps_list)\n",
        "mag_sv_array = np.array(mag_sv_list)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "046df34e-4cc8-455a-a3e8-f6b345c9249a",
      "metadata": {},
      "source": [
        "<span id=\"plot-the-time-evolution-of-the-observables\" />\n",
        "\n",
        "#### Tracer l'évolution temporelle des observables\n",
        "\n",
        "Nous traçons les valeurs d'attente que nous avons mesurées en fonction du temps. Confirmer la concordance entre les résultats des simulateurs de l'espace vectoriel d'état et de l'espace produit de la matrice.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "1762b191-c234-4acc-a6ea-8433a59ef3f8",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "Text(0.5, 0.98, 'Observable evolution')"
            ]
          },
          "execution_count": 10,
          "metadata": {},
          "output_type": "execute_result"
        },
        {
          "data": {
            "text/plain": [
              "<Image src=\"/learning/images/courses/utility-scale-quantum-computing/utility-ii/extracted-outputs/7583b935-afce-40c8-807d-6d61d43af13c-1.avif\" alt=\"Output of the previous code cell\" />"
            ]
          },
          "metadata": {},
          "output_type": "display_data"
        }
      ],
      "source": [
        "import matplotlib.pyplot as plt\n",
        "\n",
        "# Step 4. Post-processing\n",
        "fig, axes = plt.subplots(2, sharex=True)\n",
        "times = np.linspace(0, evolution_time, num_timesteps + 1)  # includes initial state\n",
        "axes[0].plot(\n",
        "    times, mag_mps_array, label=\"MPS\", marker=\"x\", c=\"darkmagenta\", ls=\"-\", lw=0.8\n",
        ")\n",
        "axes[1].plot(\n",
        "    times, mag_sv_array, label=\"SV\", marker=\"x\", c=\"darkmagenta\", ls=\"-\", lw=0.8\n",
        ")\n",
        "\n",
        "axes[0].set_ylabel(\"MPS\")\n",
        "axes[1].set_ylabel(\"Statevector\")\n",
        "axes[1].set_xlabel(\"Time\")\n",
        "fig.suptitle(\"Observable evolution\")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "4a4a4efa-de95-470e-8030-1b842e63f904",
      "metadata": {},
      "source": [
        "Nous commencerons à étudier l'évolution temporelle d'un système quantique, tout en gardant la trace de ses propriétés.\n",
        "Nous comparons ici les résultats du simulateur Matrix Product State et du dispositif quantique réel.\n",
        "\n",
        "<span id=\"22-activity-2\" />\n",
        "\n",
        "### 2.2 Activité 2\n",
        "\n",
        "<span id=\"define-the-hamiltonian\" />\n",
        "\n",
        "#### Définir l'hamiltonien\n",
        "\n",
        "Le système que nous considérons maintenant a une taille de $N=70$. Notez que les autres conditions sont les mêmes que pour le problème à 20 qubits. Essayez par vous-même; défilez vers le bas pour trouver la solution.\n",
        "\n",
        "**La solution :**\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 11,
      "id": "b8ee438b-69ac-438d-a8c9-a2055c347f0e",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "SparsePauliOp(['IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZZ', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZZI', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZZII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZZIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZZIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZZIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZZIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZZIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZZIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZZIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZZIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZZIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZZIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZZIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZZIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZZIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZZIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZZIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZZIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZZIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZZIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZZIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZZIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZZIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZZIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZZIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZZIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZZIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZZIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZZIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZZIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIZZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIZZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIZZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIZZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIZZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIZZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIZZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIZZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIZZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIZZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIZZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIZZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIZZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIZZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIZZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIZZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIZZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIZZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIZZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIZZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIZZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIZZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIZZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIZZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIZZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIZZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIZZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIZZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IZZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'ZZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIX', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIXI', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIXII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIXIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIXIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIXIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIXIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIXIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIXIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIXIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIXIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIXIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIXIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIXIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIXIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIXIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIXIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIXIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIXIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIXIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIXIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIXIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIXIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIXIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIXIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIXIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIXIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIXIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIXIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIXIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIXIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIXIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIXIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIXIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIXIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIXIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIXIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIXIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIXIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIXIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIXIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIXIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIXIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIXIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIXIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIXIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIXIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIXIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIXIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIXIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIXIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIXIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIXIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIXIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIXIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIXIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIXIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIXIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIXIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIXIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIXIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIXIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIXIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIXIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIXIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIXIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIXIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIXIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IXIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'XIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII'],\n",
              "              coeffs=[-1.+0.j, -1.+0.j, -1.+0.j, -1.+0.j, -1.+0.j, -1.+0.j, -1.+0.j, -1.+0.j,\n",
              " -1.+0.j, -1.+0.j, -1.+0.j, -1.+0.j, -1.+0.j, -1.+0.j, -1.+0.j, -1.+0.j,\n",
              " -1.+0.j, -1.+0.j, -1.+0.j, -1.+0.j, -1.+0.j, -1.+0.j, -1.+0.j, -1.+0.j,\n",
              " -1.+0.j, -1.+0.j, -1.+0.j, -1.+0.j, -1.+0.j, -1.+0.j, -1.+0.j, -1.+0.j,\n",
              " -1.+0.j, -1.+0.j, -1.+0.j, -1.+0.j, -1.+0.j, -1.+0.j, -1.+0.j, -1.+0.j,\n",
              " -1.+0.j, -1.+0.j, -1.+0.j, -1.+0.j, -1.+0.j, -1.+0.j, -1.+0.j, -1.+0.j,\n",
              " -1.+0.j, -1.+0.j, -1.+0.j, -1.+0.j, -1.+0.j, -1.+0.j, -1.+0.j, -1.+0.j,\n",
              " -1.+0.j, -1.+0.j, -1.+0.j, -1.+0.j, -1.+0.j, -1.+0.j, -1.+0.j, -1.+0.j,\n",
              " -1.+0.j, -1.+0.j, -1.+0.j, -1.+0.j, -1.+0.j,  5.+0.j,  5.+0.j,  5.+0.j,\n",
              "  5.+0.j,  5.+0.j,  5.+0.j,  5.+0.j,  5.+0.j,  5.+0.j,  5.+0.j,  5.+0.j,\n",
              "  5.+0.j,  5.+0.j,  5.+0.j,  5.+0.j,  5.+0.j,  5.+0.j,  5.+0.j,  5.+0.j,\n",
              "  5.+0.j,  5.+0.j,  5.+0.j,  5.+0.j,  5.+0.j,  5.+0.j,  5.+0.j,  5.+0.j,\n",
              "  5.+0.j,  5.+0.j,  5.+0.j,  5.+0.j,  5.+0.j,  5.+0.j,  5.+0.j,  5.+0.j,\n",
              "  5.+0.j,  5.+0.j,  5.+0.j,  5.+0.j,  5.+0.j,  5.+0.j,  5.+0.j,  5.+0.j,\n",
              "  5.+0.j,  5.+0.j,  5.+0.j,  5.+0.j,  5.+0.j,  5.+0.j,  5.+0.j,  5.+0.j,\n",
              "  5.+0.j,  5.+0.j,  5.+0.j,  5.+0.j,  5.+0.j,  5.+0.j,  5.+0.j,  5.+0.j,\n",
              "  5.+0.j,  5.+0.j,  5.+0.j,  5.+0.j,  5.+0.j,  5.+0.j,  5.+0.j,  5.+0.j,\n",
              "  5.+0.j,  5.+0.j,  5.+0.j])"
            ]
          },
          "execution_count": 11,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "# Set the number of qubits\n",
        "n_qubits2 = 70\n",
        "# Construct the Hamiltonian by calling the function you made in Activity 1\n",
        "hamiltonian2 = get_hamiltonian(nqubits=n_qubits2, J=1.0, h=-5.0)\n",
        "hamiltonian2"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "8bcad10c-1ad8-4d62-ba05-6c3d4792e4b9",
      "metadata": {},
      "source": [
        "<span id=\"23-activity-3\" />\n",
        "\n",
        "### 2.3 Activité 3\n",
        "\n",
        "Créer un état initial. Nous partirons de l'état fondamental, qui est un état ferromagnétique (tout en haut ou tout en bas). Ici, nous utilisons un exemple de tous les \"ups\" (qui sont tous \"0\"). Essayez par vous-même; défilez vers le bas pour trouver la solution.\n",
        "\n",
        "**La solution :**\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 12,
      "id": "b7bfecd3-cc23-4005-89d5-61754b72ac7d",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "<Image src=\"/learning/images/courses/utility-scale-quantum-computing/utility-ii/extracted-outputs/edacae4b-ab0e-4f1b-8c3d-001ade87e64e-0.avif\" alt=\"Output of the previous code cell\" />"
            ]
          },
          "execution_count": 12,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "# Initiate the (quantum)circuit\n",
        "initial_circuit2 = QuantumCircuit(n_qubits2)\n",
        "# Use QuantumCircuit.prepare_state() to define the initial state\n",
        "initial_circuit2.prepare_state(\n",
        "    \"0000000000000000000000000000000000000000000000000000000000000000000000\"\n",
        ")\n",
        "# Change reps and see the difference when you decompose the circuit\n",
        "initial_circuit2.decompose(reps=1).draw(\"mpl\")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "d3699dfb-5f77-4c2b-b4c7-13ca873b032b",
      "metadata": {},
      "source": [
        "<span id=\"24-activity-4\" />\n",
        "\n",
        "### 2.4 Activité 4\n",
        "\n",
        "<span id=\"prepare-the-quantum-circuit-2-single-circuit-for-time-evolution-for-the-70-qubit-problem\" />\n",
        "\n",
        "#### Préparez le circuit quantique 2 (circuit unique pour l'évolution temporelle) pour le problème à 70 qubits\n",
        "\n",
        "Nous construisons ici un circuit pour un seul pas de temps en utilisant Lie-Trotter.\n",
        "Comme dans le cas des 20 qubits, la formule du produit de Lie (premier ordre) est implémentée dans la classe [LieTrotter](/docs/api/qiskit/qiskit.synthesis.LieTrotter) classe. Là encore, la formule du premier ordre consiste en l'approximation mentionnée ci-dessus :\n",
        "\n",
        "$$\n",
        "e^{H_1+H_2} \\approx e^{H_1} e^{H_2}\n",
        "$$\n",
        "\n",
        "Essayez vous-même, en partant de l'exemple du cas de 20 qubits. Comme précédemment, comptez les opérations pour ce circuit.\n",
        "\n",
        "**La solution :**\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 13,
      "id": "adb8395b-478a-4db0-b85e-456be61c9e69",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "\n",
            "Trotter step with Lie-Trotter\n",
            "-----------------------------\n",
            "Depth: 208\n",
            "Gate count: 277\n",
            "Nonlocal gate count: 138\n",
            "Gate breakdown: CX: 138, U3: 70, U1: 69\n",
            "\n"
          ]
        },
        {
          "data": {
            "text/plain": [
              "<Image src=\"/learning/images/courses/utility-scale-quantum-computing/utility-ii/extracted-outputs/4f3385fc-d214-4405-8e37-eefe45cee98c-1.avif\" alt=\"Output of the previous code cell\" />"
            ]
          },
          "execution_count": 13,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "# Construct the gates using PauliEvolutionGate()\n",
        "single_step_evolution_gates_lt2 = PauliEvolutionGate(\n",
        "    hamiltonian2, dt, synthesis=LieTrotter()\n",
        ")\n",
        "# Initiate the quantum circuit\n",
        "single_step_evolution_lt2 = QuantumCircuit(n_qubits2)\n",
        "# Append the gates defined above\n",
        "single_step_evolution_lt2.append(\n",
        "    single_step_evolution_gates_lt2, single_step_evolution_lt2.qubits\n",
        ")\n",
        "\n",
        "print(\n",
        "    f\"\"\"\n",
        "Trotter step with Lie-Trotter\n",
        "-----------------------------\n",
        "Depth: {single_step_evolution_lt2.decompose(reps=3).depth()}\n",
        "Gate count: {len(single_step_evolution_lt2.decompose(reps=3))}\n",
        "Nonlocal gate count: {single_step_evolution_lt2.decompose(reps=3).num_nonlocal_gates()}\n",
        "Gate breakdown: {\", \".join([f\"{k.upper()}: {v}\" for k, v in single_step_evolution_lt2.decompose(reps=3).count_ops().items()])}\n",
        "\"\"\"\n",
        ")\n",
        "single_step_evolution_lt2.decompose(reps=3).draw(\"mpl\", fold=-1)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "acede2cd-d3d8-45b8-8bc5-b307fc1f32fe",
      "metadata": {},
      "source": [
        "<span id=\"25-activity-5\" />\n",
        "\n",
        "### 2.5 Activité 5\n",
        "\n",
        "<span id=\"set-the-operators-to-be-measured\" />\n",
        "\n",
        "#### Définir les opérateurs à mesurer\n",
        "\n",
        "Nous définissons un *opérateur d'aimantation* exactement analogue à celui du cas 20-qubits : $\\sum_i Z_i  / N$. Essayez vous-même en modifiant la solution à 20 qubits.\n",
        "\n",
        "**La solution :**\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 14,
      "id": "9cac351a-b15c-4aff-87f1-c877946664d3",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "magnetization :  SparsePauliOp(['IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZ', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZI', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'ZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII'],\n",
            "              coeffs=[0.01428571+0.j, 0.01428571+0.j, 0.01428571+0.j, 0.01428571+0.j,\n",
            " 0.01428571+0.j, 0.01428571+0.j, 0.01428571+0.j, 0.01428571+0.j,\n",
            " 0.01428571+0.j, 0.01428571+0.j, 0.01428571+0.j, 0.01428571+0.j,\n",
            " 0.01428571+0.j, 0.01428571+0.j, 0.01428571+0.j, 0.01428571+0.j,\n",
            " 0.01428571+0.j, 0.01428571+0.j, 0.01428571+0.j, 0.01428571+0.j,\n",
            " 0.01428571+0.j, 0.01428571+0.j, 0.01428571+0.j, 0.01428571+0.j,\n",
            " 0.01428571+0.j, 0.01428571+0.j, 0.01428571+0.j, 0.01428571+0.j,\n",
            " 0.01428571+0.j, 0.01428571+0.j, 0.01428571+0.j, 0.01428571+0.j,\n",
            " 0.01428571+0.j, 0.01428571+0.j, 0.01428571+0.j, 0.01428571+0.j,\n",
            " 0.01428571+0.j, 0.01428571+0.j, 0.01428571+0.j, 0.01428571+0.j,\n",
            " 0.01428571+0.j, 0.01428571+0.j, 0.01428571+0.j, 0.01428571+0.j,\n",
            " 0.01428571+0.j, 0.01428571+0.j, 0.01428571+0.j, 0.01428571+0.j,\n",
            " 0.01428571+0.j, 0.01428571+0.j, 0.01428571+0.j, 0.01428571+0.j,\n",
            " 0.01428571+0.j, 0.01428571+0.j, 0.01428571+0.j, 0.01428571+0.j,\n",
            " 0.01428571+0.j, 0.01428571+0.j, 0.01428571+0.j, 0.01428571+0.j,\n",
            " 0.01428571+0.j, 0.01428571+0.j, 0.01428571+0.j, 0.01428571+0.j,\n",
            " 0.01428571+0.j, 0.01428571+0.j, 0.01428571+0.j, 0.01428571+0.j,\n",
            " 0.01428571+0.j, 0.01428571+0.j])\n"
          ]
        }
      ],
      "source": [
        "# Define the magnetization operator in SparsePauliOp\n",
        "magnetization2 = (\n",
        "    SparsePauliOp.from_sparse_list(\n",
        "        [(\"Z\", [i], 1.0) for i in range(0, n_qubits2)], num_qubits=n_qubits2\n",
        "    )\n",
        "    / n_qubits2\n",
        ")\n",
        "print(\"magnetization : \", magnetization2)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "91f92286-acb7-4946-9f5f-150587e7f4d0",
      "metadata": {},
      "source": [
        "<span id=\"26-activity-6\" />\n",
        "\n",
        "### 2.6 Activité 6\n",
        "\n",
        "<span id=\"perform-time-evolution-simulation\" />\n",
        "\n",
        "#### Effectuer une simulation d'évolution temporelle\n",
        "\n",
        "Nous surveillerons l'aimantation (valeur d'espérance de l'opérateur d'aimantation). Nous utiliserons le simulateur MPS pour obtenir la valeur de référence afin de comparer les résultats calculés à partir du matériel. Vous avez déjà utilisé le simulateur MPS dans ce tutoriel. Modifiez cet exemple si nécessaire pour l'adapter à ce nouveau calcul.\n",
        "\n",
        "**La solution :**\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 15,
      "id": "7e7b754c-deff-40fd-9250-8b4deafa18d6",
      "metadata": {},
      "outputs": [],
      "source": [
        "# Step 1. Map the problem\n",
        "# Initiate the circuit\n",
        "evolved_state2 = QuantumCircuit(initial_circuit2.num_qubits)\n",
        "# Start from the initial spin configuration\n",
        "evolved_state2.append(initial_circuit2, evolved_state2.qubits)\n",
        "# Define backend (MPs simulator)\n",
        "backend_mps2 = AerSimulator(method=\"matrix_product_state\")\n",
        "# Initiate Runtime Estimator\n",
        "estimator_mps2 = Estimator(mode=backend_mps2)\n",
        "# Step 2. Optimize\n",
        "# Initiate pass manager\n",
        "pm_mps2 = generate_preset_pass_manager(optimization_level=3, backend=backend_mps2)\n",
        "# Transpile\n",
        "evolved_state_mps2 = pm_mps2.run(evolved_state2)\n",
        "# Apply qubit layout to the observable to measure\n",
        "magnetization_mps2 = magnetization2.apply_layout(evolved_state_mps2.layout)\n",
        "# Initiate list\n",
        "mag_mps_list2 = []\n",
        "# Step 3. Run the circuit\n",
        "# Estimate expectation values for t=0.0\n",
        "job = estimator_mps2.run([(evolved_state_mps2, [magnetization_mps2])])\n",
        "# Get estimated expectation values\n",
        "evs = job.result()[0].data.evs\n",
        "# Append to list\n",
        "mag_mps_list2.append(evs[0])\n",
        "\n",
        "# Start time evolution\n",
        "for n in range(num_timesteps):\n",
        "    # Step 1. Map the problem\n",
        "    # Expand the circuit to describe delta-t\n",
        "    evolved_state2.append(single_step_evolution_lt2, evolved_state2.qubits)\n",
        "    # Step 2. Optimize\n",
        "    # Transpile the circuit\n",
        "    evolved_state_mps2 = pm_mps2.run(evolved_state2)\n",
        "    # Apply the physical layout of the qubits to the operator\n",
        "    magnetization_mps2 = magnetization2.apply_layout(evolved_state_mps2.layout)\n",
        "    # Step 3. Run the circuit\n",
        "    # Estimate expectation values at delta-t\n",
        "    job = estimator_mps2.run([(evolved_state_mps2, [magnetization_mps2])])\n",
        "    # Get estimated expectation values\n",
        "    evs = job.result()[0].data.evs\n",
        "    # Append to list\n",
        "    mag_mps_list2.append(evs[0])\n",
        "# Transform the list of expectation values (at each time step) to arrays\n",
        "mag_mps_array2 = np.array(mag_mps_list2)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "c8612280-d29b-4952-826f-16a686a051dd",
      "metadata": {},
      "source": [
        "Comme dans toutes les leçons précédentes, nous mettrons en œuvre le cadre des modèles Qiskit. Jusqu'à présent, la leçon s'est concentrée sur la création de circuits quantiques corrects pour décrire notre problème. Il s'agit en fait de l'étape 1.\n",
        "\n",
        "<span id=\"step-2-optimize-for-target-hardware\" />\n",
        "\n",
        "#### Étape 2 : Optimisation pour le matériel cible\n",
        "\n",
        "Nous commençons par définir le backend cible.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "610ecd2c-9a47-43c1-872b-a4038fb83817",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "'ibm_kingston'"
            ]
          },
          "execution_count": 19,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "service = QiskitRuntimeService()\n",
        "backend = service.least_busy(operational=True, simulator=False)\n",
        "backend.name"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "ba36b8f4-9fae-4151-b3fa-8f848eb77a0d",
      "metadata": {},
      "source": [
        "Nous transposons les circuits et les rassemblons dans une liste. Cette opération peut prendre quelques minutes.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 20,
      "id": "116e914e-8fa4-4e60-9980-af71d9bcc2f9",
      "metadata": {},
      "outputs": [],
      "source": [
        "pm_hw = generate_preset_pass_manager(optimization_level=3, backend=backend)\n",
        "circuit_isa = []\n",
        "# Step 1. Map the problem\n",
        "evolved_state_hw = QuantumCircuit(initial_circuit2.num_qubits)\n",
        "evolved_state_hw.append(initial_circuit2, evolved_state_hw.qubits)\n",
        "# Step 2. Optimize\n",
        "circuit_isa.append(pm_hw.run(evolved_state_hw))\n",
        "\n",
        "for n in range(num_timesteps):\n",
        "    # Step 1. Map the problem\n",
        "    evolved_state_hw.append(single_step_evolution_lt2, evolved_state_hw.qubits)\n",
        "    # Step 2. Optimize\n",
        "    circuit_isa.append(pm_hw.run(evolved_state_hw))"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "60c95c4c-9eab-4c14-b17d-c710beecb2ce",
      "metadata": {},
      "source": [
        "<span id=\"step-3-execute-on-target-hardware\" />\n",
        "\n",
        "#### Étape 3 : Exécuter sur le matériel cible\n",
        "\n",
        "Nous allons définir l'estimateur du temps d'exécution et construire la liste des PUB. Nous devons également appliquer le schéma aux opérateurs à mesurer.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 21,
      "id": "3da4db25-5e78-4a86-b740-75fdacbdb831",
      "metadata": {},
      "outputs": [],
      "source": [
        "# Step 2. Optimize\n",
        "estimator_hw = Estimator(mode=backend)\n",
        "pub_list = []\n",
        "for circuit in circuit_isa:\n",
        "    temp = (circuit, magnetization2.apply_layout(circuit.layout))\n",
        "    pub_list.append(temp)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "2433f80e-5ed8-4e73-8adb-c4c688a79775",
      "metadata": {},
      "source": [
        "Nous sommes maintenant prêts à exécuter le travail.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 22,
      "id": "ba037ca8-dd6f-4962-a7f4-65f0bde66f8b",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "d147hfdqf56g0081sxs0\n"
          ]
        }
      ],
      "source": [
        "job = estimator_hw.run(pub_list)\n",
        "job_id = job.job_id()\n",
        "print(job_id)"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 28,
      "id": "efcb2851-3529-4e76-8a0f-1b65be8f4818",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "'DONE'"
            ]
          },
          "execution_count": 28,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "# check job status\n",
        "job.status()"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "f5dd6d18-08e9-49eb-90b4-8b6037fd6d34",
      "metadata": {},
      "source": [
        "<span id=\"step-4-post-process-results\" />\n",
        "\n",
        "#### Étape 4 : Post-traitement des résultats\n",
        "\n",
        "Nous allons d'abord obtenir les résultats.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 20,
      "id": "eb661ec3-b8fd-4e2b-a525-547685cc6864",
      "metadata": {},
      "outputs": [],
      "source": [
        "job = service.job(job_id)\n",
        "pub_result = job.result()"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "1840130b-3c40-4a10-ac83-1bc4350a1f58",
      "metadata": {},
      "source": [
        "Nous devons maintenant extraire les valeurs d'espérance de ces résultats.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 21,
      "id": "be186c8e-0408-4d2d-b843-5d27c82ba99c",
      "metadata": {},
      "outputs": [],
      "source": [
        "mag_hw_list = []\n",
        "for res in pub_result:\n",
        "    evs = res.data.evs\n",
        "    mag_hw_list.append(evs)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "0a03e25f-d447-4c52-9595-c776c9b7a23c",
      "metadata": {},
      "source": [
        "Nous l'utiliserons à des fins de comparaison ci-dessous. Voyons d'abord si nous pouvons encore optimiser nos circuits.\n",
        "\n",
        "<span id=\"3-solution-using-a-real-quantum-computer-ii\" />\n",
        "\n",
        "## 3. Solution utilisant un véritable ordinateur quantique II\n",
        "\n",
        "Revenons à l'étape 1 du schéma de Qiskit et voyons si nous pouvons réduire la profondeur de notre circuit.\n",
        "\n",
        "<span id=\"31-step-1-map-the-problem-to-quantum-circuits-and-operators\" />\n",
        "\n",
        "### 3.1 Étape 1. Cartographier le problème à l'aide de circuits et d'opérateurs quantiques\n",
        "\n",
        "<span id=\"activity-7\" />\n",
        "\n",
        "#### Activité 7\n",
        "\n",
        "Construire un circuit d'évolution temporelle. Utilisez vos connaissances des leçons précédentes pour essayer de réduire la profondeur du circuit.\n",
        "\n",
        "**La solution :**\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 22,
      "id": "52a28d34-0852-4099-bcb8-ea9487701d43",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "\n",
            "Trotter step with Lie-Trotter\n",
            "-----------------------------\n",
            "Depth: 7\n",
            "Gate count: 277\n",
            "Nonlocal gate count: 138\n",
            "Gate breakdown: CX: 138, U3: 70, U1: 69\n",
            "\n"
          ]
        },
        {
          "data": {
            "text/plain": [
              "<Image src=\"/learning/images/courses/utility-scale-quantum-computing/utility-ii/extracted-outputs/769902d2-acce-4252-8c44-cba3cc0f9be5-1.avif\" alt=\"Output of the previous code cell\" />"
            ]
          },
          "execution_count": 22,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "# Define J\n",
        "J = 1.0\n",
        "# Define h\n",
        "h = -5.0\n",
        "# Create instruction for rotation around ZZ:\n",
        "# Initiate the circuit (use 2 qubits)\n",
        "Rzz_circ = QuantumCircuit(2)\n",
        "# Add Rzz gate (do not forget to multiply the angle by 2.0)\n",
        "Rzz_circ.rzz(-J * dt * 2.0, 0, 1)\n",
        "# Transform the QuantumCircuit to instruction (QuantumCircuit.to_instruction())\n",
        "Rzz_instr = Rzz_circ.to_instruction(label=\"RZZ\")\n",
        "\n",
        "# Create instruction for rotation around X:\n",
        "# Initiate the circuit (use 1 qubit)\n",
        "Rx_circ = QuantumCircuit(1)\n",
        "# Add Rx gate (do not forget to multiply the angle by 2.0)\n",
        "Rx_circ.rx(-h * dt * 2.0, 0)\n",
        "# Transform the QuantumCircuit to instruction (QuantumCircuit.to_instruction())\n",
        "Rx_instr = Rx_circ.to_instruction(label=\"RX\")\n",
        "\n",
        "# Define the interaction list\n",
        "interaction_list = [\n",
        "    [[i, i + 1] for i in range(0, n_qubits2 - 1, 2)],\n",
        "    [[i, i + 1] for i in range(1, n_qubits2 - 1, 2)],\n",
        "]  # linear chain\n",
        "\n",
        "# Define the registers\n",
        "qr = QuantumRegister(n_qubits2)\n",
        "# Initiate the circuit\n",
        "single_step_evolution_sh = QuantumCircuit(qr)\n",
        "# Construct the Rzz gates\n",
        "for i, color in enumerate(interaction_list):\n",
        "    for interaction in color:\n",
        "        single_step_evolution_sh.append(Rzz_instr, interaction)\n",
        "\n",
        "# Construct the Rx gates\n",
        "for i in range(0, n_qubits2):\n",
        "    single_step_evolution_sh.append(Rx_instr, [i])\n",
        "\n",
        "print(\n",
        "    f\"\"\"\n",
        "Trotter step with Lie-Trotter\n",
        "-----------------------------\n",
        "Depth: {single_step_evolution_sh.decompose(reps=3).depth()}\n",
        "Gate count: {len(single_step_evolution_sh.decompose(reps=3))}\n",
        "Nonlocal gate count: {single_step_evolution_sh.decompose(reps=3).num_nonlocal_gates()}\n",
        "Gate breakdown: {\", \".join([f\"{k.upper()}: {v}\" for k, v in single_step_evolution_sh.decompose(reps=3).count_ops().items()])}\n",
        "\"\"\"\n",
        ")\n",
        "\n",
        "single_step_evolution_sh.decompose(reps=2).draw(\"mpl\")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "5cde0bf4-37e8-469a-a88f-bb9c37168cea",
      "metadata": {},
      "source": [
        "Cette initiative a été couronnée de succès. Nous pouvons maintenant procéder aux étapes restantes des modèles Qiskit.\n",
        "\n",
        "<span id=\"32-step-2-optimize-for-target-hardware\" />\n",
        "\n",
        "### 3.2 Étape 2. Optimiser pour le matériel cible\n",
        "\n",
        "Transpilez les circuits et rassemblez-les dans une liste. Là encore, cela peut prendre quelques minutes.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 32,
      "id": "958e2251-2a1e-4caf-b501-946f32b4fe9e",
      "metadata": {},
      "outputs": [],
      "source": [
        "pm_hw2 = generate_preset_pass_manager(backend=backend, optimization_level=3)\n",
        "circuit_isa2 = []\n",
        "# Step 1. Map the problem\n",
        "evolved_state_hw2 = QuantumCircuit(initial_circuit2.num_qubits)\n",
        "evolved_state_hw2.append(initial_circuit2, evolved_state_hw2.qubits)\n",
        "# Step 2. Optimize\n",
        "circuit_isa2.append(pm_hw2.run(evolved_state_hw2))\n",
        "for n in range(num_timesteps):\n",
        "    # Step 1. Map the problem\n",
        "    evolved_state_hw2.append(single_step_evolution_sh, evolved_state_hw2.qubits)\n",
        "    # Step 2. Optimize\n",
        "    circuit_isa2.append(pm_hw2.run(evolved_state_hw2))"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "8c74b53d-abac-48ac-883c-029adcd4894c",
      "metadata": {},
      "source": [
        "Définir l'estimateur du temps d'exécution et construire la liste des PUB.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 33,
      "id": "754e4c6d-04cc-4cc1-af81-c6fc13c353e0",
      "metadata": {},
      "outputs": [],
      "source": [
        "estimator_hw2 = Estimator(mode=backend)\n",
        "pub_list2 = []\n",
        "for circuit in circuit_isa2:\n",
        "    temp = (circuit, magnetization2.apply_layout(circuit.layout))\n",
        "    pub_list2.append(temp)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "e2fa2986-701d-4f68-ab38-d6bf24a599c6",
      "metadata": {},
      "source": [
        "<span id=\"33-step-3-execute-on-target-hardware\" />\n",
        "\n",
        "### 3.3 Étape 3. Exécuter sur le matériel cible\n",
        "\n",
        "Exécutez le travail.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 34,
      "id": "5288e0f3-e12c-4e8c-80f8-6e2535ffb0d1",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "d147qqeqf56g0081sye0\n"
          ]
        }
      ],
      "source": [
        "job2 = estimator_hw2.run(pub_list2)\n",
        "job2_id = job2.job_id()\n",
        "print(job2_id)"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 36,
      "id": "37dfc4b9-4757-4a87-a1a4-972a372b931a",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "'DONE'"
            ]
          },
          "execution_count": 36,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "# check job status\n",
        "job2.status()"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "4d08139b-71af-4578-b3b5-45f9a3741c0b",
      "metadata": {},
      "source": [
        "Obtenez les résultats.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 24,
      "id": "83d2d003-2f97-4294-a745-2e0a1c7ae80c",
      "metadata": {},
      "outputs": [],
      "source": [
        "job2 = service.job(job2_id)\n",
        "pub_result2 = job2.result()"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "7f32a06a-2974-4f22-9dbe-d2ec6143f3cf",
      "metadata": {},
      "source": [
        "<span id=\"34-step-4-post-processing\" />\n",
        "\n",
        "### 3.4 Étape 4. Post-traitement\n",
        "\n",
        "Extraire les valeurs attendues des résultats.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 25,
      "id": "402c9208-9a1d-4424-8ef2-636407c398d7",
      "metadata": {},
      "outputs": [],
      "source": [
        "mag_hw_list2 = []\n",
        "for res in pub_result2:\n",
        "    evs = res.data.evs\n",
        "    mag_hw_list2.append(evs)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "0c255702-0ef3-46ff-bb6e-4675af2676a3",
      "metadata": {},
      "source": [
        "Transformer la liste en tableaux numpy pour le tracé.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 26,
      "id": "0d28a88f-990c-4330-9506-4cf23ae57415",
      "metadata": {},
      "outputs": [],
      "source": [
        "mag_hw_array = np.array(mag_hw_list)\n",
        "mag_hw_array2 = np.array(mag_hw_list2)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "128662bd-44dc-4730-bdaa-fd686d1dbf04",
      "metadata": {},
      "source": [
        "Traçons maintenant les résultats et comparons les résultats matériels (circuit par défaut et circuit peu profond) avec le simulateur MPS. Comment l'erreur dans le matériel réel influence-t-elle les résultats?\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 27,
      "id": "3aa52fc2-1685-482c-8673-c25096ddb44f",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "Text(0.5, 0.98, 'Observable evolution')"
            ]
          },
          "execution_count": 27,
          "metadata": {},
          "output_type": "execute_result"
        },
        {
          "data": {
            "text/plain": [
              "<Image src=\"/learning/images/courses/utility-scale-quantum-computing/utility-ii/extracted-outputs/83c809cb-299c-4071-a662-d10ba7e24996-1.avif\" alt=\"Output of the previous code cell\" />"
            ]
          },
          "metadata": {},
          "output_type": "display_data"
        }
      ],
      "source": [
        "fig, axes = plt.subplots(3, sharex=True)\n",
        "times = np.linspace(0, evolution_time, num_timesteps + 1)  # includes initial state\n",
        "axes[0].plot(\n",
        "    times, mag_mps_array2, label=\"MPS\", marker=\"x\", c=\"darkmagenta\", ls=\"-\", lw=0.8\n",
        ")\n",
        "axes[1].plot(\n",
        "    times, mag_hw_array, label=\"HW\", marker=\"x\", c=\"darkmagenta\", ls=\"-\", lw=0.8\n",
        ")\n",
        "axes[2].plot(\n",
        "    times, mag_hw_array2, label=\"HW2\", marker=\"x\", c=\"darkmagenta\", ls=\"-\", lw=0.8\n",
        ")\n",
        "axes[0].set_ylabel(\"MPS\")\n",
        "axes[1].set_ylabel(\"HW\")\n",
        "axes[2].set_ylabel(\"HW2\")\n",
        "axes[2].set_xlabel(\"Time\")\n",
        "fig.suptitle(\"Observable evolution\")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "ec7c30e2-eea0-4fb7-80c8-e0dfb826c95e",
      "metadata": {},
      "source": [
        "Félicitations ! Vous avez fait un pas de plus dans votre voyage quantique à l'échelle de l'utilité. Il ne reste plus qu'une leçon!\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"
    },
    "widgets": {
      "application/vnd.jupyter.widget-state+json": {
        "state": {},
        "version_major": 2,
        "version_minor": 0
      }
    }
  },
  "nbformat": 4,
  "nbformat_minor": 4
}