{
  "cells": [
    {
      "cell_type": "markdown",
      "id": "434beca8-b15d-4f42-a887-4636fb692789",
      "metadata": {},
      "source": [
        "---\n",
        "title: \"Panoramica delle classi di operatori\"\n",
        "description: \"Utilizza il modulo di informazione quantistica Qiskit per costruire e manipolare gli operatori\"\n",
        "---\n",
        "\n",
        "<span id=\"overview-of-operator-classes\" />\n",
        "\n",
        "# Panoramica delle classi di operatori\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "434beca86fbddfbe-75b2-44d7-8783-b756382fd6d5",
      "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.2\n",
        "    ```\n",
        "  </AccordionItem>\n",
        "</Accordion>\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "1c4cfc09-242c-4389-b03e-8c241c573306",
      "metadata": {},
      "source": [
        "In Qiskit, gli operatori quantistici sono rappresentati utilizzando le classi del modulo [`quantum_info`](/docs/api/qiskit/quantum_info) modulo. La classe di operatori più importante è [`SparsePauliOp`](/docs/api/qiskit/qiskit.quantum_info.SparsePauliOp)che rappresenta un operatore quantistico generale come combinazione lineare di stringhe di Pauli. `SparsePauliOp` è la classe più comunemente usata per rappresentare le osservabili quantistiche. Il resto di questa pagina spiega come utilizzare `SparsePauliOp` e altre classi di operatori.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 1,
      "id": "6fc6f151-f2ca-44f6-811b-d15c71ee1fa6",
      "metadata": {
        "ExecuteTime": {
          "end_time": "2019-08-21T09:02:56.554914Z",
          "start_time": "2019-08-21T09:02:54.249612Z"
        }
      },
      "outputs": [],
      "source": [
        "import numpy as np\n",
        "from qiskit.quantum_info.operators import Operator, Pauli, SparsePauliOp"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "23a940b3-fce0-4f84-8461-5a72c0ce9aa7",
      "metadata": {},
      "source": [
        "<span id=\"sparsepauliop\" />\n",
        "\n",
        "## SparsePauliOp\n",
        "\n",
        "La [`SparsePauliOp`](/docs/api/qiskit/qiskit.quantum_info.SparsePauliOp) rappresenta una combinazione lineare di stringhe Pauli. Esistono diversi modi per inizializzare un `SparsePauliOp`, ma il modo più flessibile è quello di utilizzare il metodo [`from_sparse_list`](/docs/api/qiskit/qiskit.quantum_info.SparsePauliOp#from_sparse_list) come dimostra la seguente cella di codice. `from_sparse_list` accetta un elenco di triplette `(pauli_string, qubit_indices, coefficient)` .\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 2,
      "id": "90053827-6a1f-4fb4-8188-808afe3ddd4f",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "SparsePauliOp(['XIIZI', 'IYIIY'],\n",
              "              coeffs=[ 1.+0.j, -1.+1.j])"
            ]
          },
          "execution_count": 2,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "op1 = SparsePauliOp.from_sparse_list(\n",
        "    [(\"ZX\", [1, 4], 1.0), (\"YY\", [0, 3], -1 + 1j)], num_qubits=5\n",
        ")\n",
        "op1"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "fc7ffabb-5245-4687-b84b-25176a64dc07",
      "metadata": {},
      "source": [
        "`SparsePauliOp` supporta le operazioni aritmetiche, come dimostra la seguente cella di codice.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 3,
      "id": "2e21467f-b6fe-4ac5-9654-66dec83a97fb",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "op1 + op2:\n",
            "SparsePauliOp(['XIIZI', 'IYIIY', 'ZIIXX', 'IIZZI'],\n",
            "              coeffs=[ 1.+0.j, -1.+1.j,  1.+2.j, -1.+1.j])\n",
            "\n",
            "2 * op1:\n",
            "SparsePauliOp(['XIIZI', 'IYIIY'],\n",
            "              coeffs=[ 2.+0.j, -2.+2.j])\n",
            "\n",
            "op1 @ op2:\n",
            "SparsePauliOp(['YIIYX', 'XIZII', 'ZYIXZ', 'IYZZY'],\n",
            "              coeffs=[ 1.+2.j, -1.+1.j, -1.+3.j,  0.-2.j])\n",
            "\n",
            "op1.tensor(op2):\n",
            "SparsePauliOp(['XIIZIZIIXX', 'XIIZIIIZZI', 'IYIIYZIIXX', 'IYIIYIIZZI'],\n",
            "              coeffs=[ 1.+2.j, -1.+1.j, -3.-1.j,  0.-2.j])\n"
          ]
        }
      ],
      "source": [
        "op2 = SparsePauliOp.from_sparse_list(\n",
        "    [(\"XXZ\", [0, 1, 4], 1 + 2j), (\"ZZ\", [1, 2], -1 + 1j)], num_qubits=5\n",
        ")\n",
        "\n",
        "# Addition\n",
        "print(\"op1 + op2:\")\n",
        "print(op1 + op2)\n",
        "print()\n",
        "# Multiplication by a scalar\n",
        "print(\"2 * op1:\")\n",
        "print(2 * op1)\n",
        "print()\n",
        "# Operator multiplication (composition)\n",
        "print(\"op1 @ op2:\")\n",
        "print(op1 @ op2)\n",
        "print()\n",
        "# Tensor product\n",
        "print(\"op1.tensor(op2):\")\n",
        "print(op1.tensor(op2))"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "85fb16f2-5296-4c4d-9836-249358fd7e12",
      "metadata": {},
      "source": [
        "<span id=\"pauli\" />\n",
        "\n",
        "## Pauli\n",
        "\n",
        "La classe [`Pauli`](/docs/api/qiskit/qiskit.quantum_info.Pauli) rappresenta una singola stringa Pauli con un coefficiente di fase opzionale dall'insieme $\\set{+1, i, -1, -i}$. Una `Pauli` può essere inizializzata passando una stringa di caratteri dell'insieme `{\"I\", \"X\", \"Y\", \"Z\"}`, eventualmente preceduta da uno degli `{\"\", \"i\", \"-\", \"-i\"}` per rappresentare il coefficiente di fase.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 4,
      "id": "edc33fe7-989e-489b-92f6-81975b20bd05",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "Pauli('iXX')"
            ]
          },
          "execution_count": 4,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "op1 = Pauli(\"iXX\")\n",
        "op1"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "82c19270-98d0-4543-bad5-5bfaacee406f",
      "metadata": {},
      "source": [
        "La seguente cella di codice dimostra l'uso di alcuni attributi e metodi.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 5,
      "id": "69b105cd-e978-45be-a3e9-bab344d9111f",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "Dimension of iXX: (4, 4)\n",
            "Phase of iXX: 3\n",
            "Matrix representation of iXX: \n",
            " [[0.+0.j 0.+0.j 0.+0.j 0.+1.j]\n",
            " [0.+0.j 0.+0.j 0.+1.j 0.+0.j]\n",
            " [0.+0.j 0.+1.j 0.+0.j 0.+0.j]\n",
            " [0.+1.j 0.+0.j 0.+0.j 0.+0.j]]\n"
          ]
        }
      ],
      "source": [
        "print(f\"Dimension of {op1}: {op1.dim}\")\n",
        "print(f\"Phase of {op1}: {op1.phase}\")\n",
        "print(f\"Matrix representation of {op1}: \\n {op1.to_matrix()}\")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "4c4b1efe-4025-4b88-bbce-d0b3060e0ab1",
      "metadata": {},
      "source": [
        "`Pauli` gli oggetti possiedono una serie di altri metodi per manipolare gli operatori, come ad esempio determinare il suo adjoint, se (anti)commuta con un altro `Pauli`, e calcolare il prodotto di punti con un altro `Pauli`. Per maggiori informazioni, consultare la [documentazione API](/docs/api/qiskit/qiskit.quantum_info.Pauli).\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "0f02f8da-fab6-4ba6-b4ec-80d577cf8914",
      "metadata": {},
      "source": [
        "<span id=\"operator\" />\n",
        "\n",
        "## Operatore\n",
        "\n",
        "La [`Operator`](/docs/api/qiskit/qiskit.quantum_info.Operator) rappresenta un operatore lineare generale. A differenza di `SparsePauliOp`, `Operator` memorizza l'operatore lineare come matrice densa. Poiché la memoria richiesta per memorizzare una matrice densa scala esponenzialmente con il numero di qubit, la classe `Operator` è adatta solo per l'uso con un piccolo numero di qubit.\n",
        "\n",
        "È possibile inizializzare un `Operator` passando direttamente un array Numpy che memorizza la matrice dell'operatore. Ad esempio, la seguente cella di codice crea un operatore Pauli XX a due qubit:\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 6,
      "id": "f8d9d183-586c-44ac-aa93-317a2adb40ad",
      "metadata": {
        "ExecuteTime": {
          "end_time": "2019-08-21T09:02:56.572857Z",
          "start_time": "2019-08-21T09:02:56.566140Z"
        }
      },
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "Operator([[0.+0.j, 0.+0.j, 0.+0.j, 1.+0.j],\n",
            "          [0.+0.j, 0.+0.j, 1.+0.j, 0.+0.j],\n",
            "          [0.+0.j, 1.+0.j, 0.+0.j, 0.+0.j],\n",
            "          [1.+0.j, 0.+0.j, 0.+0.j, 0.+0.j]],\n",
            "         input_dims=(2, 2), output_dims=(2, 2))\n"
          ]
        }
      ],
      "source": [
        "XX = Operator(\n",
        "    np.array(\n",
        "        [\n",
        "            [0, 0, 0, 1],\n",
        "            [0, 0, 1, 0],\n",
        "            [0, 1, 0, 0],\n",
        "            [1, 0, 0, 0],\n",
        "        ]\n",
        "    )\n",
        ")\n",
        "XX"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "4ded9878-c239-4e79-a60e-fff048c15784",
      "metadata": {},
      "source": [
        "L'oggetto operatore memorizza la matrice sottostante e la dimensione di ingresso e di uscita dei sottosistemi.\n",
        "\n",
        "* `data`: Per accedere all'array Numpy sottostante, è possibile utilizzare la proprietà `Operator.data` .\n",
        "* `dim`: Per ottenere le dimensioni totali di ingresso e uscita dell'operatore, è possibile utilizzare la proprietà `Operator.dim` . \\*Nota: il risultato viene restituito come tupla \\*`(input_dim, output_dim)`, *la cui forma è l'inverso di quella della matrice sottostante.*\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 7,
      "id": "d9a6fe93-00a1-498f-9110-67b022db0a4f",
      "metadata": {
        "ExecuteTime": {
          "end_time": "2019-08-21T09:02:56.589962Z",
          "start_time": "2019-08-21T09:02:56.585681Z"
        }
      },
      "outputs": [
        {
          "data": {
            "text/plain": [
              "array([[0.+0.j, 0.+0.j, 0.+0.j, 1.+0.j],\n",
              "       [0.+0.j, 0.+0.j, 1.+0.j, 0.+0.j],\n",
              "       [0.+0.j, 1.+0.j, 0.+0.j, 0.+0.j],\n",
              "       [1.+0.j, 0.+0.j, 0.+0.j, 0.+0.j]])"
            ]
          },
          "execution_count": 7,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "XX.data"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 8,
      "id": "784a657a-1731-4ecd-9bc0-aa0b96bc27e8",
      "metadata": {
        "ExecuteTime": {
          "end_time": "2019-08-21T09:02:56.615497Z",
          "start_time": "2019-08-21T09:02:56.611146Z"
        }
      },
      "outputs": [
        {
          "data": {
            "text/plain": [
              "(4, 4)"
            ]
          },
          "execution_count": 8,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "input_dim, output_dim = XX.dim\n",
        "input_dim, output_dim"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "0f84bf31-ce41-454a-9e2c-11c0ec4a04dc",
      "metadata": {},
      "source": [
        "La classe operatore tiene anche traccia delle dimensioni del sottosistema, che possono essere utilizzate per comporre gli operatori tra loro. È possibile accedervi utilizzando le funzioni `input_dims` e `output_dims` .\n",
        "\n",
        "Per $2^N$ da parte degli operatori di $2^M$, le dimensioni di ingresso e di uscita sono automaticamente assunte come M-qubit e N-qubit:\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 9,
      "id": "b4576985-9ae2-46f0-a29d-9ca3bea53bf0",
      "metadata": {
        "ExecuteTime": {
          "end_time": "2019-08-21T09:02:56.804167Z",
          "start_time": "2019-08-21T09:02:56.798857Z"
        }
      },
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "Input dimensions: (2, 2)\n",
            "Output dimensions: (2,)\n"
          ]
        }
      ],
      "source": [
        "op = Operator(np.random.rand(2**1, 2**2))\n",
        "print(\"Input dimensions:\", op.input_dims())\n",
        "print(\"Output dimensions:\", op.output_dims())"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "9bae9b8c-b7f5-4e1e-ad8b-4482f19af531",
      "metadata": {},
      "source": [
        "Se la matrice di ingresso non è divisibile in sottosistemi di qubit, verrà memorizzata come operatore a singolo qubit. Ad esempio, per una matrice $6\\times6$ :\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 10,
      "id": "186c1ac5-0bf2-4a86-84d8-bffa3f1763a1",
      "metadata": {
        "ExecuteTime": {
          "end_time": "2019-08-21T09:02:57.764881Z",
          "start_time": "2019-08-21T09:02:57.760401Z"
        }
      },
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "Input dimensions: (6,)\n",
            "Output dimensions: (6,)\n"
          ]
        }
      ],
      "source": [
        "op = Operator(np.random.rand(6, 6))\n",
        "print(\"Input dimensions:\", op.input_dims())\n",
        "print(\"Output dimensions:\", op.output_dims())"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "e813709d-4ac3-4abc-863f-9d5d262ba753",
      "metadata": {},
      "source": [
        "La dimensione di ingresso e di uscita può anche essere specificata manualmente quando si inizializza un nuovo operatore:\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 11,
      "id": "e14faef6-3b05-4447-9960-3b140ddff1a1",
      "metadata": {
        "ExecuteTime": {
          "end_time": "2019-08-21T09:02:58.292849Z",
          "start_time": "2019-08-21T09:02:58.287354Z"
        }
      },
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "Input dimensions: (4,)\n",
            "Output dimensions: (2,)\n"
          ]
        }
      ],
      "source": [
        "# Force input dimension to be (4,) rather than (2, 2)\n",
        "op = Operator(np.random.rand(2**1, 2**2), input_dims=[4])\n",
        "print(\"Input dimensions:\", op.input_dims())\n",
        "print(\"Output dimensions:\", op.output_dims())"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 12,
      "id": "41845475-f6e9-4057-b21e-89cf1a62f672",
      "metadata": {
        "ExecuteTime": {
          "end_time": "2019-08-21T09:02:58.779572Z",
          "start_time": "2019-08-21T09:02:58.774878Z"
        }
      },
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "Input dimensions: (2, 3)\n",
            "Output dimensions: (2, 3)\n"
          ]
        }
      ],
      "source": [
        "# Specify system is a qubit and qutrit\n",
        "op = Operator(np.random.rand(6, 6), input_dims=[2, 3], output_dims=[2, 3])\n",
        "print(\"Input dimensions:\", op.input_dims())\n",
        "print(\"Output dimensions:\", op.output_dims())"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "1ed55128-5b97-4733-ac0f-6b762e48691b",
      "metadata": {},
      "source": [
        "È inoltre possibile estrarre solo le dimensioni di ingresso o di uscita di un sottoinsieme di sottosistemi utilizzando le funzioni `input_dims` e `output_dims` :\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 13,
      "id": "c9fe7460-8e93-47aa-acc1-425bfe797c17",
      "metadata": {
        "ExecuteTime": {
          "end_time": "2019-08-21T09:03:02.187313Z",
          "start_time": "2019-08-21T09:03:02.183719Z"
        }
      },
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "Dimension of input system 0: (2,)\n",
            "Dimension of input system 1: (3,)\n"
          ]
        }
      ],
      "source": [
        "print(\"Dimension of input system 0:\", op.input_dims([0]))\n",
        "print(\"Dimension of input system 1:\", op.input_dims([1]))"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "3e8538f5-77d4-4683-838f-abff122cd3f7",
      "metadata": {},
      "source": [
        "<span id=\"next-steps\" />\n",
        "\n",
        "## Passi successivi\n",
        "\n",
        "<Admonition type=\"tip\" title=\"Suggerimenti\">\n",
        "  * Scopri come [specificare gli osservabili nella base di Pauli](/docs/guides/specify-observables-pauli).\n",
        "  * Vedi un esempio di utilizzo degli operatori nel tutorial [Combina le opzioni di mitigazione degli errori con la primitiva Estimator](/docs/tutorials/combine-error-mitigation-techniques).\n",
        "  * Leggi [un](/docs/guides/operator-class) approfondimento sulla classe Operator.\n",
        "  * Esplorare il riferimento all' [API dell'operatore](/docs/api/qiskit/qiskit.quantum_info.Operator#operator).\n",
        "</Admonition>\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "id": "a1b8767d",
      "source": "© IBM Corp., 2017-2026"
    }
  ],
  "metadata": {
    "anaconda-cloud": {},
    "celltoolbar": "Tags",
    "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"
    },
    "varInspector": {
      "cols": {
        "lenName": 16,
        "lenType": 16,
        "lenVar": 40
      },
      "kernels_config": {
        "python": {
          "delete_cmd_postfix": "",
          "delete_cmd_prefix": "del ",
          "library": "var_list.py",
          "varRefreshCmd": "print(var_dic_list())"
        },
        "r": {
          "delete_cmd_postfix": ") ",
          "delete_cmd_prefix": "rm(",
          "library": "var_list.r",
          "varRefreshCmd": "cat(var_dic_list()) "
        }
      },
      "types_to_exclude": [
        "module",
        "function",
        "builtin_function_or_method",
        "instance",
        "_Feature"
      ],
      "window_display": false
    }
  },
  "nbformat": 4,
  "nbformat_minor": 4
}