{
  "cells": [
    {
      "cell_type": "markdown",
      "id": "e6d26387-f218-4f62-80c4-792103129b99",
      "metadata": {},
      "source": [
        "---\n",
        "title: \"Simulazione efficiente dei circuiti stabilizzatori con le primitive Aer di Qiskit\"\n",
        "description: \"Come simulare in modo efficiente i circuiti stabilizzatori utilizzando le primitive Qiskit Aer.\"\n",
        "---\n",
        "\n",
        "<span id=\"efficient-simulation-of-stabilizer-circuits-with-qiskit-aer-primitives\" />\n",
        "\n",
        "# Simulazione efficiente dei circuiti stabilizzatori con le primitive Aer di Qiskit\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "f1bcbbdb-965d-41f0-88dd-bb42834b35b9",
      "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=\"Versioni del pacchetto\">\n",
        "    Il codice di questa pagina è stato sviluppato in base ai seguenti requisiti.\n",
        "    Si consiglia di utilizzare queste versioni o versioni più recenti.\n",
        "\n",
        "    ```\n",
        "    qiskit[all]~=2.5.1\n",
        "    qiskit-aer~=0.17\n",
        "    ```\n",
        "  </AccordionItem>\n",
        "</Accordion>\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "386709ed-183b-4759-bb1b-56cdedf80539",
      "metadata": {},
      "source": [
        "Questa pagina mostra come utilizzare le primitive di Qiskit Aer per simulare in modo efficiente i circuiti stabilizzatori, compresi quelli soggetti al rumore di Pauli.\n",
        "\n",
        "I circuiti stabilizzatori, noti anche come circuiti di Clifford, sono un'importante classe ristretta di circuiti quantistici che possono essere simulati in modo efficiente in modo classico. Esistono diversi modi equivalenti per definire i circuiti stabilizzatori. Una definizione è che un circuito stabilizzatore è un circuito quantistico che consiste unicamente nelle seguenti porte:\n",
        "\n",
        "* [CX](../api/qiskit/qiskit.circuit.library.CXGate)\n",
        "* [Hadamard](../api/qiskit/qiskit.circuit.library.HGate)\n",
        "* [S](../api/qiskit/qiskit.circuit.library.SGate)\n",
        "* [Misurazione](../api/qiskit/circuit#qiskit.circuit.Measure)\n",
        "\n",
        "Si noti che utilizzando Hadamard e S, possiamo costruire qualsiasi porta di rotazione di Pauli ( [$R_x$](/docs/api/qiskit/qiskit.circuit.library.RXGate), [$R_y$](/docs/api/qiskit/qiskit.circuit.library.RYGate), e [$R_z$](/docs/api/qiskit/qiskit.circuit.library.RZGate) ) che ha un angolo contenuto nell'insieme $\\{0, \\frac{\\pi}{2}, \\pi, \\frac{3\\pi}{2}\\}$ (fino alla fase globale), quindi possiamo includere anche questi gate nella definizione.\n",
        "\n",
        "I circuiti stabilizzatori sono importanti per lo studio della correzione quantistica degli errori. La loro simulabilità classica li rende utili anche per verificare l'output dei computer quantistici. Ad esempio, supponiamo di voler eseguire un circuito quantistico che utilizza 100 qubit su un computer quantistico. Come si fa a sapere che il computer quantistico si comporta correttamente? Un circuito quantistico su 100 qubit è fuori dalla portata della simulazione classica a forza bruta. Modificando il circuito in modo che diventi un circuito stabilizzatore, è possibile eseguire sul computer quantistico circuiti che hanno una struttura simile al circuito desiderato, ma che è possibile simulare su un computer classico. Controllando l'uscita del computer quantistico sui circuiti stabilizzatori, si può avere la certezza che si comporti correttamente anche sui circuiti non stabilizzatori. Per un esempio di questa idea nella pratica, si veda [*Evidence for the utility of quantum computing before fault tolerance*](https://www.nature.com/articles/s41586-023-06096-3).\n",
        "\n",
        "[Simulazione esatta e rumorosa con le primitive di Qiskit Aer](simulate-with-qiskit-aer) mostra come utilizzare [Qiskit Aer](https://qiskit.org/ecosystem/aer/) per eseguire simulazioni esatte e rumorose di generici circuiti quantistici. Si consideri il circuito di esempio utilizzato in quell'articolo, un circuito a 8-qubit costruito utilizzando l' [efficiente Su2](../api/qiskit/qiskit.circuit.library.efficient_su2) :\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 1,
      "id": "2d26ac3e-2a6a-4d73-900f-470200a63154",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "<Image src=\"/docs/images/guides/simulate-stabilizer-circuits/extracted-outputs/2d26ac3e-2a6a-4d73-900f-470200a63154-0.svg\" alt=\"Output of the previous code cell\" />"
            ]
          },
          "execution_count": 1,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "from qiskit.circuit.library import efficient_su2\n",
        "\n",
        "n_qubits = 8\n",
        "circuit = efficient_su2(n_qubits)\n",
        "circuit.draw(\"mpl\")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "9f72e683-a828-456d-a5d4-910758cc9add",
      "metadata": {},
      "source": [
        "Utilizzando Qiskit Aer, siamo riusciti a simulare facilmente questo circuito. Tuttavia, supponiamo di impostare il numero di qubit a 500:\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 2,
      "id": "43c8277f-3f0d-4d31-a1c2-e4c541083f5d",
      "metadata": {},
      "outputs": [],
      "source": [
        "n_qubits = 500\n",
        "circuit = efficient_su2(n_qubits)\n",
        "# don't try to draw the circuit because it's too large"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "ecd975b0-2ec0-4a99-a0f6-790d43af19fb",
      "metadata": {},
      "source": [
        "Poiché il costo della simulazione dei circuiti quantistici scala esponenzialmente con il numero di qubit, un circuito di tali dimensioni supererebbe in genere le capacità anche di un simulatore ad alte prestazioni come Qiskit Aer. La simulazione classica di circuiti quantistici generici diventa impraticabile quando il numero di qubit supera approssimativamente i 50-100 qubit. Tuttavia, si noti che il circuito efficient\\_su2 è parametrizzato dagli angoli sulle porte $R_y$ e $R_z$. Se tutti questi angoli sono contenuti nell'insieme $\\{0, \\frac{\\pi}{2}, \\pi, \\frac{3\\pi}{2}\\}$, allora il circuito è un circuito stabilizzatore e può essere simulato in modo efficiente!\n",
        "\n",
        "Nella cella seguente, eseguiamo il circuito con la primitiva Sampler supportata dal simulatore di circuito stabilizzatore, utilizzando parametri scelti a caso in modo che il circuito sia garantito come circuito stabilizzatore.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 3,
      "id": "2210bbe3-1a89-48fe-a4ea-f3c9b1cd37d0",
      "metadata": {},
      "outputs": [],
      "source": [
        "import numpy as np\n",
        "from qiskit.transpiler import generate_preset_pass_manager\n",
        "from qiskit_aer import AerSimulator\n",
        "from qiskit_aer.primitives import SamplerV2 as Sampler\n",
        "\n",
        "measured_circuit = circuit.copy()\n",
        "measured_circuit.measure_all()\n",
        "\n",
        "rng = np.random.default_rng(1234)\n",
        "params = rng.choice(\n",
        "    [0, np.pi / 2, np.pi, 3 * np.pi / 2],\n",
        "    size=circuit.num_parameters,\n",
        ")\n",
        "\n",
        "# Initialize a Sampler backed by the stabilizer circuit simulator\n",
        "exact_sampler = Sampler(\n",
        "    options=dict(backend_options=dict(method=\"stabilizer\"))\n",
        ")\n",
        "# The circuit needs to be transpiled to the AerSimulator target\n",
        "pass_manager = generate_preset_pass_manager(\n",
        "    1, AerSimulator(method=\"stabilizer\")\n",
        ")\n",
        "isa_circuit = pass_manager.run(measured_circuit)\n",
        "pub = (isa_circuit, params)\n",
        "job = exact_sampler.run([pub])\n",
        "result = job.result()\n",
        "pub_result = result[0]\n",
        "counts = pub_result.data.meas.get_counts()"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "445694b0-3e5b-4fc2-a610-f86674065045",
      "metadata": {},
      "source": [
        "Il simulatore di circuiti stabilizzatori supporta anche la simulazione rumorosa, ma solo per una classe ristretta di modelli di rumore. In particolare, qualsiasi rumore quantistico deve essere caratterizzato da un canale di [errore Pauli](https://qiskit.org/ecosystem/aer/stubs/qiskit_aer.noise.pauli_error.html#qiskit_aer.noise.pauli_error). L ['errore di depolarizzazione](https://qiskit.org/ecosystem/aer/stubs/qiskit_aer.noise.depolarizing_error.html) rientra in questa categoria, quindi può essere simulato. È possibile simulare anche canali di rumore classici come l' [errore di lettura](https://qiskit.org/ecosystem/aer/stubs/qiskit_aer.noise.ReadoutError.html).\n",
        "\n",
        "La cella di codice seguente esegue la stessa simulazione di prima, ma questa volta specificando un modello di rumore che aggiunge un errore di depolarizzazione del 2% a ciascun gate CX, nonché un errore di lettura che capovolge ogni bit misurato con una probabilità del 5%.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 4,
      "id": "71dd8d78-6efd-4c4e-900a-1d73deafe46e",
      "metadata": {},
      "outputs": [],
      "source": [
        "from qiskit_aer.noise import NoiseModel, depolarizing_error, ReadoutError\n",
        "\n",
        "noise_model = NoiseModel()\n",
        "cx_depolarizing_prob = 0.02\n",
        "bit_flip_prob = 0.05\n",
        "noise_model.add_all_qubit_quantum_error(\n",
        "    depolarizing_error(cx_depolarizing_prob, 2), [\"cx\"]\n",
        ")\n",
        "noise_model.add_all_qubit_readout_error(\n",
        "    ReadoutError(\n",
        "        [\n",
        "            [1 - bit_flip_prob, bit_flip_prob],\n",
        "            [bit_flip_prob, 1 - bit_flip_prob],\n",
        "        ]\n",
        "    )\n",
        ")\n",
        "\n",
        "noisy_sampler = Sampler(\n",
        "    options=dict(\n",
        "        backend_options=dict(method=\"stabilizer\", noise_model=noise_model)\n",
        "    )\n",
        ")\n",
        "job = noisy_sampler.run([pub])\n",
        "result = job.result()\n",
        "pub_result = result[0]\n",
        "counts = pub_result.data.meas.get_counts()"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "01b3e796-bd06-419f-a2fc-55c8603f662f",
      "metadata": {},
      "source": [
        "Utilizziamo ora la primitiva Estimator supportata dal simulatore di stabilizzatori per calcolare il valore di aspettativa dell'osservabile $ZZ \\cdots Z$. A causa della particolare struttura dei circuiti di stabilizzazione, è molto probabile che il risultato sia pari a 0.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 5,
      "id": "57fb0674-5bd2-44b0-a28e-e73deff455cf",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "0.0"
            ]
          },
          "execution_count": 5,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "from qiskit.quantum_info import SparsePauliOp\n",
        "from qiskit_aer.primitives import EstimatorV2 as Estimator\n",
        "\n",
        "observable = SparsePauliOp(\"Z\" * n_qubits)\n",
        "\n",
        "exact_estimator = Estimator(\n",
        "    options=dict(backend_options=dict(method=\"stabilizer\")),\n",
        ")\n",
        "isa_circuit = pass_manager.run(circuit)\n",
        "pub = (isa_circuit, observable, params)\n",
        "job = exact_estimator.run([pub])\n",
        "result = job.result()\n",
        "pub_result = result[0]\n",
        "exact_value = float(pub_result.data.evs)\n",
        "exact_value"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "9d5e6593-06f0-4e1b-a4f0-7b640a74f6c5",
      "metadata": {},
      "source": [
        "<span id=\"next-steps\" />\n",
        "\n",
        "## Passi successivi\n",
        "\n",
        "<Admonition type=\"tip\" title=\"Suggerimenti\">\n",
        "  * Per simulare circuiti con Qiskit Aer, consultare [la sezione \"Simulazione esatta e con rumore con le primitive di Qiskit Aer](/docs/guides/simulate-with-qiskit-sdk-primitives) \".\n",
        "  * Esaminare la documentazione di [Qiskit Aer](https://qiskit.org/ecosystem/aer/).\n",
        "</Admonition>\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "id": "a1b8767d",
      "source": "© IBM Corp., 2017-2026"
    }
  ],
  "metadata": {
    "kernelspec": {
      "display_name": "Python 3",
      "language": "python",
      "name": "python3"
    },
    "language_info": {
      "codemirror_mode": {
        "name": "ipython",
        "version": 3
      },
      "file_extension": ".py",
      "mimetype": "text/x-python",
      "name": "python",
      "nbconvert_exporter": "python",
      "pygments_lexer": "ipython3",
      "version": "3"
    }
  },
  "nbformat": 4,
  "nbformat_minor": 4
}