{
  "cells": [
    {
      "cell_type": "markdown",
      "id": "fd07a3db-1aa2-4884-98db-6f68765c3edc",
      "metadata": {},
      "source": [
        "---\n",
        "title: \"Lärmmodelle erstellen\"\n",
        "description: \"Erfahren Sie, wie Sie Rauschmodelle für das Fehlermanagement erstellen.\"\n",
        "---\n",
        "\n",
        "<span id=\"build-noise-models\" />\n",
        "\n",
        "# Lärmmodelle erstellen\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "35e9a88b-6872-42b0-ac4f-36bf8898f2fa",
      "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=\"Paketversionen\">\n",
        "    Der Code auf dieser Seite wurde unter Berücksichtigung der folgenden Anforderungen entwickelt.\n",
        "    Wir empfehlen die Verwendung dieser oder neuerer Versionen.\n",
        "\n",
        "    ```\n",
        "    qiskit[all]~=2.5.2\n",
        "    qiskit-ibm-runtime~=0.47.0\n",
        "    qiskit-aer~=0.17\n",
        "    ```\n",
        "  </AccordionItem>\n",
        "</Accordion>\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "19c35f2c-437a-48b7-8c9f-9ac3526811a7",
      "metadata": {},
      "source": [
        "Diese Seite zeigt, wie man mit dem Qiskit Aer [`noise`](https://qiskit.org/ecosystem/aer/apidocs/aer_noise.html) modul zur Erstellung von Rauschmodellen für die Simulation von Quantenschaltungen in Anwesenheit von Fehlern. Dies ist nützlich für die Emulation verrauschter Quantenprozessoren und für die Untersuchung der Auswirkungen von Rauschen auf die Ausführung von Quantenalgorithmen.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 1,
      "id": "85a94e7b-6b43-4a4a-a3b6-a412e1d66c7d",
      "metadata": {
        "ExecuteTime": {
          "end_time": "2019-08-19T17:00:43.403378Z",
          "start_time": "2019-08-19T17:00:41.139269Z"
        }
      },
      "outputs": [],
      "source": [
        "import numpy as np\n",
        "from qiskit import QuantumCircuit\n",
        "from qiskit.quantum_info import Kraus, SuperOp\n",
        "from qiskit.visualization import plot_histogram\n",
        "from qiskit.transpiler import generate_preset_pass_manager\n",
        "from qiskit_aer import AerSimulator\n",
        "\n",
        "# Import from Qiskit Aer noise module\n",
        "from qiskit_aer.noise import (\n",
        "    NoiseModel,\n",
        "    QuantumError,\n",
        "    ReadoutError,\n",
        "    depolarizing_error,\n",
        "    pauli_error,\n",
        "    thermal_relaxation_error,\n",
        ")"
      ]
    },
    {
      "attachments": {},
      "cell_type": "markdown",
      "id": "da49be49-d174-413c-b05d-20236817aac2",
      "metadata": {
        "slideshow": {
          "slide_type": "slide"
        }
      },
      "source": [
        "<span id=\"qiskit-aer-noise-module\" />\n",
        "\n",
        "## Qiskit `noise` Aer-Modul\n",
        "\n",
        "Das Modul Qiskit Aer `noise` enthält Python Klassen, um maßgeschneiderte Geräuschmodelle für die Simulation zu erstellen. Es gibt drei Schlüsselklassen:\n",
        "\n",
        "1. Die Klasse `NoiseModel` speichert ein Rauschmodell, das für die Rauschsimulation verwendet wird.\n",
        "\n",
        "2. Die Klasse `QuantumError` , die CPTP-Gate-Fehler beschreibt. Diese können angewendet werden:\n",
        "   * Nach *Tor-* oder *Reset-Anweisungen*\n",
        "   * Anweisungen vor der *Messung*.\n",
        "\n",
        "3. Die Klasse `ReadoutError` , die klassische Auslesefehler beschreibt.\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "ea2762d5-7260-4ce9-9e44-2950331ba3e7",
      "metadata": {},
      "source": [
        "<span id=\"initialize-a-noise-model-from-a-backend\" />\n",
        "\n",
        "## Ein Rauschmodell aus einem Backend initialisieren\n",
        "\n",
        "Sie können ein Rauschmodell mit Parametern initialisieren, die auf der Grundlage der aktuellsten Kalibrierungsdaten für ein physikalisches Backend festgelegt wurden.\n",
        "\n",
        "<Admonition type=\"note\">\n",
        "  In diesen Beispielen wird das `FakeSherbrooke``qiskit_ibm_runtime` Mock-Backend von verwendet, Sie können es jedoch mit jedem Qiskit-kompatiblen echten oder simulierten Backend ausprobieren.\n",
        "</Admonition>\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 2,
      "id": "b47efd06-6a64-455a-be12-07054e800a34",
      "metadata": {},
      "outputs": [],
      "source": [
        "from qiskit_ibm_runtime.fake_provider import FakeSherbrooke\n",
        "\n",
        "backend = FakeSherbrooke()\n",
        "noise_model = NoiseModel.from_backend(backend)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "54f7cb42-dd95-4089-afbb-db9e83d41b50",
      "metadata": {},
      "source": [
        "Dies führt zu einem Rauschmodell, das die Fehler, die bei der Verwendung dieses Backends auftreten würden, annähernd wiedergibt. Wenn Sie eine detailliertere Kontrolle über die Parameter des Rauschmodells haben möchten, müssen Sie Ihr eigenes Rauschmodell erstellen, wie im Rest dieser Seite beschrieben.\n",
        "\n"
      ]
    },
    {
      "attachments": {},
      "cell_type": "markdown",
      "id": "a4940a81-d6ab-4f15-8505-05282c67d823",
      "metadata": {},
      "source": [
        "<span id=\"quantum-errors\" />\n",
        "\n",
        "## Quantenfehler\n",
        "\n",
        "Anstatt direkt mit dem `QuantumError` Objekt zu arbeiten, gibt es viele Hilfsfunktionen, die automatisch einen bestimmten Typ von parametrisiertem Quantenfehler generieren. Diese sind im `noise` Modul enthalten und umfassen Funktionen für viele gängige Fehlertypen, die in der Quantencomputerforschung verwendet werden. Die Funktionsnamen und die Art der Fehler, die sie zurückgeben, sind:\n",
        "\n",
        "| Standardfehlerfunktion          | Details zu                                                                                                                                                                                                                                              |\n",
        "| ------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n",
        "| `kraus_error`                   | einen allgemeinen n-Qubit-CPTP-Fehlerkanal in Form einer Liste von Kraus-Matrizen $[K_0, ...]$.                                                                                                                                                         |\n",
        "| `mixed_unitary_error`           | einen n-qubit gemischten unitären Fehler, der als eine Liste von unitären Matrizen und Wahrscheinlichkeiten angegeben wird $[(U_0, p_0),...]$.                                                                                                          |\n",
        "| `coherent_unitary_error`        | ein n-Qubit kohärenter unitärer Fehler, der als eine einzige unitäre Matrix $U$ gegeben ist.                                                                                                                                                            |\n",
        "| `pauli_error`                   | ein n-Qubit-Pauli-Fehlerkanal (gemischt unitär), der als Liste von Pauli und Wahrscheinlichkeiten angegeben ist $[(P_0, p_0),...]$                                                                                                                      |\n",
        "| `depolarizing_error`            | einen n-qubit depolarisierenden Fehlerkanal, der durch eine Depolarisationswahrscheinlichkeit $p$ parametrisiert ist.                                                                                                                                   |\n",
        "| `reset_error`                   | ein Einzelqubit-Reset-Fehler, parametrisiert durch die Wahrscheinlichkeiten $p_0, p_1$ eines Resets in den Zustand $\\vert0\\rangle$ $\\vert1\\rangle$.                                                                                                     |\n",
        "| `thermal_relaxation_error`      | ein thermischer Relaxationskanal für ein einzelnes Qubit, parametrisiert durch die Relaxationszeitkonstanten $T_1$, $T_2$, die Torzeit $t$ und die thermische Population im angeregten Zustand $p_1$.                                                   |\n",
        "| `phase_amplitude_damping_error` | Ein verallgemeinerter kombinierter Phasen- und Amplitudendämpfungs-Fehlerkanal, der durch einen Amplitudendämpfungsparameter $\\lambda$, einen Phasendämpfungsparameter $\\gamma$ und eine thermische Population im angeregten Zustand $p_1$ gegeben ist. |\n",
        "| `amplitude_damping_error`       | Ein verallgemeinerter Amplitudendämpfungs-Fehlerkanal, der durch einen Amplitudendämpfungsparameter $\\lambda$ und eine thermische Population im angeregten Zustand $p_1$ gegeben ist.                                                                   |\n",
        "| `phase_damping_error`           | Ein Einzelqubit-Phasendämpfungsfehlerkanal, der durch einen Phasendämpfungs-Parameter $\\gamma$ gegeben ist.                                                                                                                                             |\n",
        "\n",
        "<span id=\"combine-quantum-errors\" />\n",
        "\n",
        "### Quantenfehler kombinieren\n",
        "\n",
        "`QuantumError` instanzen können mit Hilfe von Komposition, Tensorprodukt und Tensorexpansion (Tensorprodukt umgekehrter Ordnung) kombiniert werden, um neue `QuantumErrors` zu erzeugen:\n",
        "\n",
        "* Zusammensetzung: $\\cal{E}(\\rho)=\\cal{E_2}(\\cal{E_1}(\\rho))$ als `error = error1.compose(error2)`\n",
        "* Tensorprodukt: $\\cal{E}(\\rho) =(\\cal{E_1}\\otimes\\cal{E_2})(\\rho)$ als `error = error1.tensor(error2)`\n",
        "* Produkt erweitern: $\\cal{E}(\\rho) =(\\cal{E_2}\\otimes\\cal{E_1})(\\rho)$ als `error = error1.expand(error2)`\n",
        "\n"
      ]
    },
    {
      "attachments": {},
      "cell_type": "markdown",
      "id": "cd42ec1c-a971-4dd8-913c-2a4fd4f4a845",
      "metadata": {},
      "source": [
        "<span id=\"example\" />\n",
        "\n",
        "### Beispiel\n",
        "\n",
        "Konstruktion eines 5%igen Ein-Qubit-Bitflip-Fehlers:\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 3,
      "id": "437a8576-084c-499f-af7e-12b0a2fbfcd0",
      "metadata": {
        "ExecuteTime": {
          "end_time": "2019-08-19T17:00:43.420358Z",
          "start_time": "2019-08-19T17:00:43.416062Z"
        }
      },
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "QuantumError on 1 qubits. Noise circuits:\n",
            "  P(0) = 0.05, Circuit = \n",
            "   ┌───┐\n",
            "q: ┤ X ├\n",
            "   └───┘\n",
            "  P(1) = 0.95, Circuit = \n",
            "   ┌───┐\n",
            "q: ┤ I ├\n",
            "   └───┘\n",
            "QuantumError on 1 qubits. Noise circuits:\n",
            "  P(0) = 0.05, Circuit = \n",
            "   ┌───┐\n",
            "q: ┤ Z ├\n",
            "   └───┘\n",
            "  P(1) = 0.95, Circuit = \n",
            "   ┌───┐\n",
            "q: ┤ I ├\n",
            "   └───┘\n"
          ]
        }
      ],
      "source": [
        "# Construct a 1-qubit bit-flip and phase-flip errors\n",
        "p_error = 0.05\n",
        "bit_flip = pauli_error([(\"X\", p_error), (\"I\", 1 - p_error)])\n",
        "phase_flip = pauli_error([(\"Z\", p_error), (\"I\", 1 - p_error)])\n",
        "print(bit_flip)\n",
        "print(phase_flip)"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 4,
      "id": "d71ef2d9-e386-4649-9e1c-a7bfe7342687",
      "metadata": {
        "ExecuteTime": {
          "end_time": "2019-08-19T17:00:43.435843Z",
          "start_time": "2019-08-19T17:00:43.432211Z"
        }
      },
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "QuantumError on 1 qubits. Noise circuits:\n",
            "  P(0) = 0.0025000000000000005, Circuit = \n",
            "   ┌───┐┌───┐\n",
            "q: ┤ X ├┤ Z ├\n",
            "   └───┘└───┘\n",
            "  P(1) = 0.0475, Circuit = \n",
            "   ┌───┐┌───┐\n",
            "q: ┤ X ├┤ I ├\n",
            "   └───┘└───┘\n",
            "  P(2) = 0.0475, Circuit = \n",
            "   ┌───┐┌───┐\n",
            "q: ┤ I ├┤ Z ├\n",
            "   └───┘└───┘\n",
            "  P(3) = 0.9025, Circuit = \n",
            "   ┌───┐┌───┐\n",
            "q: ┤ I ├┤ I ├\n",
            "   └───┘└───┘\n"
          ]
        }
      ],
      "source": [
        "# Compose two bit-flip and phase-flip errors\n",
        "bitphase_flip = bit_flip.compose(phase_flip)\n",
        "print(bitphase_flip)"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 5,
      "id": "ffa9fd9c-3d98-4285-8daf-ee22ca2b0d55",
      "metadata": {
        "ExecuteTime": {
          "end_time": "2019-08-19T17:00:43.460191Z",
          "start_time": "2019-08-19T17:00:43.456782Z"
        }
      },
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "QuantumError on 2 qubits. Noise circuits:\n",
            "  P(0) = 0.0025000000000000005, Circuit = \n",
            "     ┌───┐\n",
            "q_0: ┤ X ├\n",
            "     ├───┤\n",
            "q_1: ┤ Z ├\n",
            "     └───┘\n",
            "  P(1) = 0.0475, Circuit = \n",
            "     ┌───┐\n",
            "q_0: ┤ I ├\n",
            "     ├───┤\n",
            "q_1: ┤ Z ├\n",
            "     └───┘\n",
            "  P(2) = 0.0475, Circuit = \n",
            "     ┌───┐\n",
            "q_0: ┤ X ├\n",
            "     ├───┤\n",
            "q_1: ┤ I ├\n",
            "     └───┘\n",
            "  P(3) = 0.9025, Circuit = \n",
            "     ┌───┐\n",
            "q_0: ┤ I ├\n",
            "     ├───┤\n",
            "q_1: ┤ I ├\n",
            "     └───┘\n"
          ]
        }
      ],
      "source": [
        "# Tensor product two bit-flip and phase-flip errors with\n",
        "# bit-flip on qubit-0, phase-flip on qubit-1\n",
        "error2 = phase_flip.tensor(bit_flip)\n",
        "print(error2)"
      ]
    },
    {
      "attachments": {},
      "cell_type": "markdown",
      "id": "80e275c7-b856-4301-9266-0eb7a783e0f8",
      "metadata": {},
      "source": [
        "<span id=\"convert-to-and-from-quantumchannel-operators\" />\n",
        "\n",
        "### In und aus Operatoren des „ QuantumChannel “ konvertieren\n",
        "\n",
        "Wir können auch zwischen `QuantumError` Objekten in Qiskit Aer und `QuantumChannel` Objekten in Qiskit hin und her konvertieren.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 6,
      "id": "2006e158-bea6-4e18-a06c-31b567401b6c",
      "metadata": {
        "ExecuteTime": {
          "end_time": "2019-08-19T17:00:43.482424Z",
          "start_time": "2019-08-19T17:00:43.473779Z"
        }
      },
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "Kraus([[[-9.74679434e-01+1.19363805e-16j,\n",
            "          0.00000000e+00+0.00000000e+00j],\n",
            "        [ 0.00000000e+00+0.00000000e+00j,\n",
            "         -9.74679434e-01+0.00000000e+00j]],\n",
            "\n",
            "       [[ 0.00000000e+00+0.00000000e+00j,\n",
            "          4.69834045e-18-2.23606798e-01j],\n",
            "        [-2.26855945e-17-2.23606798e-01j,\n",
            "          5.03721386e-33+4.96506831e-17j]]],\n",
            "      input_dims=(2,), output_dims=(2,))\n"
          ]
        }
      ],
      "source": [
        "# Convert to Kraus operator\n",
        "bit_flip_kraus = Kraus(bit_flip)\n",
        "print(bit_flip_kraus)"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 7,
      "id": "425a9b6f-e078-4a48-ab1c-a5621a8b773a",
      "metadata": {
        "ExecuteTime": {
          "end_time": "2019-08-19T17:00:43.509521Z",
          "start_time": "2019-08-19T17:00:43.503976Z"
        }
      },
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "SuperOp([[1. +0.j, 0. +0.j, 0. +0.j, 0. +0.j],\n",
            "         [0. +0.j, 0.9+0.j, 0. +0.j, 0. +0.j],\n",
            "         [0. +0.j, 0. +0.j, 0.9+0.j, 0. +0.j],\n",
            "         [0. +0.j, 0. +0.j, 0. +0.j, 1. +0.j]],\n",
            "        input_dims=(2,), output_dims=(2,))\n"
          ]
        }
      ],
      "source": [
        "# Convert to Superoperator\n",
        "phase_flip_sop = SuperOp(phase_flip)\n",
        "print(phase_flip_sop)"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 8,
      "id": "97624c98-f1c0-4a9b-be5b-2c664d368e9f",
      "metadata": {
        "ExecuteTime": {
          "end_time": "2019-08-19T17:00:43.794037Z",
          "start_time": "2019-08-19T17:00:43.778223Z"
        }
      },
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "QuantumError on 1 qubits. Noise circuits:\n",
            "  P(0) = 1.0, Circuit = \n",
            "   ┌───────┐\n",
            "q: ┤ kraus ├\n",
            "   └───────┘\n"
          ]
        },
        {
          "data": {
            "text/plain": [
              "True"
            ]
          },
          "execution_count": 8,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "# Convert back to a quantum error\n",
        "print(QuantumError(bit_flip_kraus))\n",
        "\n",
        "# Check conversion is equivalent to original error\n",
        "QuantumError(bit_flip_kraus) == bit_flip"
      ]
    },
    {
      "attachments": {},
      "cell_type": "markdown",
      "id": "7f663dfe-e238-418c-bff4-c751468a6678",
      "metadata": {},
      "source": [
        "<span id=\"readout-error\" />\n",
        "\n",
        "### Auslesungsfehler\n",
        "\n",
        "Klassische Auslesungsfehler werden durch eine Liste von Zuordnungswahrscheinlichkeitsvektoren angegeben $P(A|B)$ :\n",
        "\n",
        "* $A$ ist der *aufgezeichnete* klassische Bitwert\n",
        "* $B$ ist der *wahre* Bitwert, der von der Messung zurückgegeben wird\n",
        "\n",
        "Zum Beispiel für ein Qubit: $ P(A|B) = [P(A|0), P(A|1)]$.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 9,
      "id": "f70f39f8-dec5-46cb-a194-4768cffbd6db",
      "metadata": {
        "ExecuteTime": {
          "end_time": "2019-08-19T17:00:44.659598Z",
          "start_time": "2019-08-19T17:00:44.654818Z"
        }
      },
      "outputs": [
        {
          "data": {
            "text/plain": [
              "ReadoutError([[0.95 0.05]\n",
              " [0.1  0.9 ]])"
            ]
          },
          "execution_count": 9,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "# Measurement misassignment probabilities\n",
        "p0given1 = 0.1\n",
        "p1given0 = 0.05\n",
        "\n",
        "ReadoutError([[1 - p1given0, p1given0], [p0given1, 1 - p0given1]])"
      ]
    },
    {
      "attachments": {},
      "cell_type": "markdown",
      "id": "e77fcdcd-346c-4f78-83eb-0c32359ba62c",
      "metadata": {},
      "source": [
        "Auslesefehler können auch mit `compose`, `tensor` und `expand` kombiniert werden, wie bei Quantenfehlern.\n",
        "\n"
      ]
    },
    {
      "attachments": {},
      "cell_type": "markdown",
      "id": "b2258427-2283-435c-b964-60423c3b0f39",
      "metadata": {},
      "source": [
        "<span id=\"add-errors-to-a-noise-model\" />\n",
        "\n",
        "## Fehler zu einem Rauschmodell hinzufügen\n",
        "\n",
        "Wenn man einen Quantenfehler zu einem Rauschmodell hinzufügt, muss man angeben, auf welche Art von *Anweisung* er wirkt und auf welche Qubits er angewendet werden soll. Es gibt zwei Fälle von Quantenfehlern:\n",
        "\n",
        "1. All-Qubit-Quantenfehler\n",
        "2. Spezifischer Qubit-Quantenfehler\n",
        "\n",
        "<span id=\"1-all-qubit-quantum-error\" />\n",
        "\n",
        "### 1. All-Qubit-Quantenfehler\n",
        "\n",
        "Dadurch wird bei jedem Auftreten eines Befehls derselbe Fehler verursacht, unabhängig davon, auf welche Qubits er wirkt.\n",
        "\n",
        "Sie wird als `noise_model.add_all_qubit_quantum_error(error, instructions)` hinzugefügt:\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 10,
      "id": "0a5ae501-87e5-4930-96c1-b0af2d6993ce",
      "metadata": {
        "ExecuteTime": {
          "end_time": "2019-08-19T17:00:45.882254Z",
          "start_time": "2019-08-19T17:00:45.877630Z"
        }
      },
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "NoiseModel:\n",
            "  Basis gates: ['cx', 'id', 'rz', 'sx', 'u1', 'u2', 'u3']\n",
            "  Instructions with noise: ['u2', 'u3', 'u1']\n",
            "  All-qubits errors: ['u1', 'u2', 'u3']\n"
          ]
        }
      ],
      "source": [
        "# Create an empty noise model\n",
        "noise_model = NoiseModel()\n",
        "\n",
        "# Add depolarizing error to all single qubit u1, u2, u3 gates\n",
        "error = depolarizing_error(0.05, 1)\n",
        "noise_model.add_all_qubit_quantum_error(error, [\"u1\", \"u2\", \"u3\"])\n",
        "\n",
        "# Print noise model info\n",
        "print(noise_model)"
      ]
    },
    {
      "attachments": {},
      "cell_type": "markdown",
      "id": "f2f360be-5d7b-435d-980a-e20450a0267f",
      "metadata": {},
      "source": [
        "<span id=\"2-specific-qubit-quantum-error\" />\n",
        "\n",
        "### 2. Spezifischer Qubit-Quantenfehler\n",
        "\n",
        "Damit wird der Fehler auf jedes Vorkommen eines Befehls angewendet, der auf eine bestimmte Liste von Qubits wirkt. Man beachte, dass die Reihenfolge der Qubits eine Rolle spielt: Ein Fehler, der bei einem Zwei-Qubit-Tor auf die Qubits \\[0 und 1] angewendet wird, ist anders als ein Fehler, der auf die Qubits \\[1 und 0] angewendet wird.\n",
        "\n",
        "Sie wird als `noise_model.add_quantum_error(error, instructions, qubits)` hinzugefügt:\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 11,
      "id": "05d7e61f-75dc-488b-bfab-c00ad87fe1ea",
      "metadata": {
        "ExecuteTime": {
          "end_time": "2019-08-19T17:00:46.615959Z",
          "start_time": "2019-08-19T17:00:46.612055Z"
        }
      },
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "NoiseModel:\n",
            "  Basis gates: ['cx', 'id', 'rz', 'sx', 'u1', 'u2', 'u3']\n",
            "  Instructions with noise: ['u2', 'u3', 'u1']\n",
            "  Qubits with noise: [0]\n",
            "  Specific qubit errors: [('u1', (0,)), ('u2', (0,)), ('u3', (0,))]\n"
          ]
        }
      ],
      "source": [
        "# Create an empty noise model\n",
        "noise_model = NoiseModel()\n",
        "\n",
        "# Add depolarizing error to all single qubit u1, u2, u3 gates on qubit 0 only\n",
        "error = depolarizing_error(0.05, 1)\n",
        "noise_model.add_quantum_error(error, [\"u1\", \"u2\", \"u3\"], [0])\n",
        "\n",
        "# Print noise model info\n",
        "print(noise_model)"
      ]
    },
    {
      "attachments": {},
      "cell_type": "markdown",
      "id": "c2dc1bb3-66a9-4d63-8341-0c4c45ed89d6",
      "metadata": {},
      "source": [
        "<span id=\"note-on-non-local-qubit-quantum-error\" />\n",
        "\n",
        "### Hinweis zu nicht-lokalen Qubit-Quantenfehlern\n",
        "\n",
        "`NoiseModel` unterstützt keine Hinzufügung von nicht-lokalen Quantenfehlern bei Qubits. Sie sollten außerhalb von `NoiseModel`. behandelt werden. Das bedeutet, dass Sie [Ihren eigenen Transpiler-Pass](/docs/guides/custom-transpiler-pass) (`TransformationPass`) schreiben und diesen unmittelbar vor dem Start des Simulators ausführen sollten, wenn Sie Ihre Quantenfehler unter Ihren eigenen Bedingungen in Ihre Schaltung einfügen möchten.\n",
        "\n"
      ]
    },
    {
      "attachments": {},
      "cell_type": "markdown",
      "id": "2617effb-ae2e-44a3-8a7b-28b68b756ac6",
      "metadata": {},
      "source": [
        "<span id=\"execute-a-noisy-simulation-with-a-noise-model\" />\n",
        "\n",
        "### Führen Sie eine Geräuschsimulation mit einem Geräuschmodell durch\n",
        "\n",
        "Der Befehl `AerSimulator(noise_model=noise_model)` gibt einen für das angegebene Rauschmodell konfigurierten Simulator zurück. Neben der Einstellung des Rauschmodells des Simulators werden auch die Basis-Gates des Simulators entsprechend den Gates des Rauschmodells überschrieben.\n",
        "\n"
      ]
    },
    {
      "attachments": {},
      "cell_type": "markdown",
      "id": "7df257fd-424b-486e-a607-7d4c392b4c98",
      "metadata": {
        "slideshow": {
          "slide_type": "subslide"
        }
      },
      "source": [
        "<span id=\"noise-model-examples\" />\n",
        "\n",
        "## Beispiele für Geräuschmodelle\n",
        "\n",
        "Wir werden nun einige Beispiele für Rauschmodelle geben. Für unsere Demonstrationen verwenden wir eine einfache Testschaltung, die einen n-Qubit-GHZ-Zustand erzeugt:\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 12,
      "id": "43df6b1f-b07a-4bf2-bba6-c7ec35eec620",
      "metadata": {
        "ExecuteTime": {
          "end_time": "2019-08-19T17:00:48.817405Z",
          "start_time": "2019-08-19T17:00:48.806966Z"
        },
        "slideshow": {
          "slide_type": "fragment"
        }
      },
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "        ┌───┐                ░ ┌─┐         \n",
            "   q_0: ┤ H ├──■─────────────░─┤M├─────────\n",
            "        └───┘┌─┴─┐           ░ └╥┘┌─┐      \n",
            "   q_1: ─────┤ X ├──■────────░──╫─┤M├──────\n",
            "             └───┘┌─┴─┐      ░  ║ └╥┘┌─┐   \n",
            "   q_2: ──────────┤ X ├──■───░──╫──╫─┤M├───\n",
            "                  └───┘┌─┴─┐ ░  ║  ║ └╥┘┌─┐\n",
            "   q_3: ───────────────┤ X ├─░──╫──╫──╫─┤M├\n",
            "                       └───┘ ░  ║  ║  ║ └╥┘\n",
            "meas: 4/════════════════════════╩══╩══╩══╩═\n",
            "                                0  1  2  3 \n"
          ]
        }
      ],
      "source": [
        "# System Specification\n",
        "n_qubits = 4\n",
        "circ = QuantumCircuit(n_qubits)\n",
        "\n",
        "# Test Circuit\n",
        "circ.h(0)\n",
        "for qubit in range(n_qubits - 1):\n",
        "    circ.cx(qubit, qubit + 1)\n",
        "circ.measure_all()\n",
        "print(circ)"
      ]
    },
    {
      "attachments": {},
      "cell_type": "markdown",
      "id": "eea319ec-8764-4d77-8863-c5a2e9ae370a",
      "metadata": {},
      "source": [
        "<span id=\"ideal-simulation\" />\n",
        "\n",
        "### Ideale Simulation\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 13,
      "id": "bc713d11-755e-41e4-94f0-1ed76e3c2469",
      "metadata": {
        "ExecuteTime": {
          "end_time": "2019-08-19T17:00:50.560988Z",
          "start_time": "2019-08-19T17:00:50.415545Z"
        }
      },
      "outputs": [
        {
          "data": {
            "text/plain": [
              "<Image src=\"/docs/images/guides/build-noise-models/extracted-outputs/bc713d11-755e-41e4-94f0-1ed76e3c2469-0.svg\" alt=\"Output of the previous code cell\" />"
            ]
          },
          "execution_count": 13,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "# Ideal simulator and execution\n",
        "sim_ideal = AerSimulator()\n",
        "result_ideal = sim_ideal.run(circ).result()\n",
        "plot_histogram(result_ideal.get_counts(0))"
      ]
    },
    {
      "attachments": {},
      "cell_type": "markdown",
      "id": "ac7111a6-04dc-4068-9044-54d93e745116",
      "metadata": {
        "slideshow": {
          "slide_type": "subslide"
        }
      },
      "source": [
        "<span id=\"noise-example-1-basic-bit-flip-error-noise-model\" />\n",
        "\n",
        "## Rauschbeispiel 1: Einfaches Bit-Flip-Fehler-Rauschmodell\n",
        "\n",
        "Betrachten wir ein einfaches Beispiel für ein Spielzeug-Rauschmodell, das in der Forschung zur Quanteninformationstheorie üblich ist:\n",
        "\n",
        "* Bei der Anwendung eines Ein-Qubit-Gatters wird der Zustand des Qubits mit der Wahrscheinlichkeit `p_gate1` umgedreht.\n",
        "* Bei der Anwendung eines Zwei-Qubit-Gatters sind auf jedes Qubit Einzel-Qubit-Fehler anzuwenden.\n",
        "* Beim Zurücksetzen eines Qubits wird es mit der Wahrscheinlichkeit `p_reset` auf 1 statt auf 0 zurückgesetzt.\n",
        "* Bei der Messung eines Qubits wird der Zustand des Qubits mit der Wahrscheinlichkeit `p_meas` umgedreht.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 14,
      "id": "fee3c383-0499-4d1f-be9f-32b41a31f561",
      "metadata": {
        "ExecuteTime": {
          "end_time": "2019-08-19T17:00:51.543615Z",
          "start_time": "2019-08-19T17:00:51.536564Z"
        }
      },
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "NoiseModel:\n",
            "  Basis gates: ['cx', 'id', 'rz', 'sx', 'u1', 'u2', 'u3']\n",
            "  Instructions with noise: ['u2', 'u1', 'reset', 'cx', 'measure', 'u3']\n",
            "  All-qubits errors: ['reset', 'measure', 'u1', 'u2', 'u3', 'cx']\n"
          ]
        }
      ],
      "source": [
        "# Example error probabilities\n",
        "p_reset = 0.03\n",
        "p_meas = 0.1\n",
        "p_gate1 = 0.05\n",
        "\n",
        "# QuantumError objects\n",
        "error_reset = pauli_error([(\"X\", p_reset), (\"I\", 1 - p_reset)])\n",
        "error_meas = pauli_error([(\"X\", p_meas), (\"I\", 1 - p_meas)])\n",
        "error_gate1 = pauli_error([(\"X\", p_gate1), (\"I\", 1 - p_gate1)])\n",
        "error_gate2 = error_gate1.tensor(error_gate1)\n",
        "\n",
        "# Add errors to noise model\n",
        "noise_bit_flip = NoiseModel()\n",
        "noise_bit_flip.add_all_qubit_quantum_error(error_reset, \"reset\")\n",
        "noise_bit_flip.add_all_qubit_quantum_error(error_meas, \"measure\")\n",
        "noise_bit_flip.add_all_qubit_quantum_error(error_gate1, [\"u1\", \"u2\", \"u3\"])\n",
        "noise_bit_flip.add_all_qubit_quantum_error(error_gate2, [\"cx\"])\n",
        "\n",
        "print(noise_bit_flip)"
      ]
    },
    {
      "attachments": {},
      "cell_type": "markdown",
      "id": "dbf3f5ee-0f66-4a37-b512-038a21ce2ed2",
      "metadata": {},
      "source": [
        "<span id=\"execute-the-noisy-simulation\" />\n",
        "\n",
        "### Führen Sie die laute Simulation aus\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 15,
      "id": "abeb9f09-d762-406d-983e-0357ade59636",
      "metadata": {
        "ExecuteTime": {
          "end_time": "2019-08-19T17:00:52.951874Z",
          "start_time": "2019-08-19T17:00:52.687440Z"
        },
        "slideshow": {
          "slide_type": "-"
        }
      },
      "outputs": [
        {
          "data": {
            "text/plain": [
              "<Image src=\"/docs/images/guides/build-noise-models/extracted-outputs/abeb9f09-d762-406d-983e-0357ade59636-0.svg\" alt=\"Output of the previous code cell\" />"
            ]
          },
          "execution_count": 15,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "# Create noisy simulator backend\n",
        "sim_noise = AerSimulator(noise_model=noise_bit_flip)\n",
        "\n",
        "# Transpile circuit for noisy basis gates\n",
        "passmanager = generate_preset_pass_manager(\n",
        "    optimization_level=3, backend=sim_noise\n",
        ")\n",
        "circ_tnoise = passmanager.run(circ)\n",
        "\n",
        "# Run and get counts\n",
        "result_bit_flip = sim_noise.run(circ_tnoise).result()\n",
        "counts_bit_flip = result_bit_flip.get_counts(0)\n",
        "\n",
        "# Plot noisy output\n",
        "plot_histogram(counts_bit_flip)"
      ]
    },
    {
      "attachments": {},
      "cell_type": "markdown",
      "id": "ced838fa-105d-4bdf-b240-51b78ff18e29",
      "metadata": {},
      "source": [
        "<span id=\"example-2-t1/t2-thermal-relaxation\" />\n",
        "\n",
        "## Beispiel 2: Thermische Relaxation von T1/T2\n",
        "\n",
        "Betrachten wir nun ein realistischeres Fehlermodell, das auf thermischer Relaxation mit der Qubit-Umgebung beruht:\n",
        "\n",
        "* Jedes Qubit ist durch eine thermische Relaxationszeitkonstante $T_1$ und eine Dephasierungszeitkonstante $T_2$ parametrisiert.\n",
        "* Beachten Sie, dass wir $T_2 \\le 2 T_1$ haben müssen.\n",
        "* Die Fehlerquoten bei Befehlen werden durch die Gatterzeiten und die Qubit-Werte $T_1$, $T_2$ bestimmt.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 16,
      "id": "b2ab3829-98fa-4b5d-b622-25c155abfdf0",
      "metadata": {
        "ExecuteTime": {
          "end_time": "2019-08-19T17:00:54.577456Z",
          "start_time": "2019-08-19T17:00:54.491018Z"
        }
      },
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "NoiseModel:\n",
            "  Basis gates: ['cx', 'id', 'rz', 'sx', 'u2', 'u3']\n",
            "  Instructions with noise: ['u2', 'reset', 'cx', 'measure', 'u3']\n",
            "  Qubits with noise: [0, 1, 2, 3]\n",
            "  Specific qubit errors: [('reset', (0,)), ('reset', (1,)), ('reset', (2,)), ('reset', (3,)), ('measure', (0,)), ('measure', (1,)), ('measure', (2,)), ('measure', (3,)), ('u2', (0,)), ('u2', (1,)), ('u2', (2,)), ('u2', (3,)), ('u3', (0,)), ('u3', (1,)), ('u3', (2,)), ('u3', (3,)), ('cx', (0, 0)), ('cx', (0, 1)), ('cx', (0, 2)), ('cx', (0, 3)), ('cx', (1, 0)), ('cx', (1, 1)), ('cx', (1, 2)), ('cx', (1, 3)), ('cx', (2, 0)), ('cx', (2, 1)), ('cx', (2, 2)), ('cx', (2, 3)), ('cx', (3, 0)), ('cx', (3, 1)), ('cx', (3, 2)), ('cx', (3, 3))]\n"
          ]
        }
      ],
      "source": [
        "# T1 and T2 values for qubits 0-3\n",
        "T1s = np.random.normal(\n",
        "    50e3, 10e3, 4\n",
        ")  # Sampled from normal distribution mean 50 microsec\n",
        "T2s = np.random.normal(\n",
        "    70e3, 10e3, 4\n",
        ")  # Sampled from normal distribution mean 50 microsec\n",
        "\n",
        "# Truncate random T2s <= T1s\n",
        "T2s = np.array([min(T2s[j], 2 * T1s[j]) for j in range(4)])\n",
        "\n",
        "# Instruction times (in nanoseconds)\n",
        "time_u1 = 0  # virtual gate\n",
        "time_u2 = 50  # (single X90 pulse)\n",
        "time_u3 = 100  # (two X90 pulses)\n",
        "time_cx = 300\n",
        "time_reset = 1000  # 1 microsecond\n",
        "time_measure = 1000  # 1 microsecond\n",
        "\n",
        "# QuantumError objects\n",
        "errors_reset = [\n",
        "    thermal_relaxation_error(t1, t2, time_reset) for t1, t2 in zip(T1s, T2s)\n",
        "]\n",
        "errors_measure = [\n",
        "    thermal_relaxation_error(t1, t2, time_measure) for t1, t2 in zip(T1s, T2s)\n",
        "]\n",
        "errors_u1 = [\n",
        "    thermal_relaxation_error(t1, t2, time_u1) for t1, t2 in zip(T1s, T2s)\n",
        "]\n",
        "errors_u2 = [\n",
        "    thermal_relaxation_error(t1, t2, time_u2) for t1, t2 in zip(T1s, T2s)\n",
        "]\n",
        "errors_u3 = [\n",
        "    thermal_relaxation_error(t1, t2, time_u3) for t1, t2 in zip(T1s, T2s)\n",
        "]\n",
        "errors_cx = [\n",
        "    [\n",
        "        thermal_relaxation_error(t1a, t2a, time_cx).expand(\n",
        "            thermal_relaxation_error(t1b, t2b, time_cx)\n",
        "        )\n",
        "        for t1a, t2a in zip(T1s, T2s)\n",
        "    ]\n",
        "    for t1b, t2b in zip(T1s, T2s)\n",
        "]\n",
        "\n",
        "# Add errors to noise model\n",
        "noise_thermal = NoiseModel()\n",
        "for j in range(4):\n",
        "    noise_thermal.add_quantum_error(errors_reset[j], \"reset\", [j])\n",
        "    noise_thermal.add_quantum_error(errors_measure[j], \"measure\", [j])\n",
        "    noise_thermal.add_quantum_error(errors_u1[j], \"u1\", [j])\n",
        "    noise_thermal.add_quantum_error(errors_u2[j], \"u2\", [j])\n",
        "    noise_thermal.add_quantum_error(errors_u3[j], \"u3\", [j])\n",
        "    for k in range(4):\n",
        "        noise_thermal.add_quantum_error(errors_cx[j][k], \"cx\", [j, k])\n",
        "\n",
        "print(noise_thermal)"
      ]
    },
    {
      "attachments": {},
      "cell_type": "markdown",
      "id": "a3dd27c5-c032-44b9-ada9-19280e8a0140",
      "metadata": {},
      "source": [
        "<span id=\"execute-the-noisy-simulation\" />\n",
        "\n",
        "### Führen Sie die laute Simulation aus\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 17,
      "id": "ff52bf52-1323-40fc-a631-2b1889b21b20",
      "metadata": {
        "ExecuteTime": {
          "end_time": "2019-08-19T17:00:55.689241Z",
          "start_time": "2019-08-19T17:00:55.515394Z"
        }
      },
      "outputs": [
        {
          "data": {
            "text/plain": [
              "<Image src=\"/docs/images/guides/build-noise-models/extracted-outputs/ff52bf52-1323-40fc-a631-2b1889b21b20-0.svg\" alt=\"Output of the previous code cell\" />"
            ]
          },
          "execution_count": 17,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "# Run the noisy simulation\n",
        "sim_thermal = AerSimulator(noise_model=noise_thermal)\n",
        "\n",
        "# Transpile circuit for noisy basis gates\n",
        "passmanager = generate_preset_pass_manager(\n",
        "    optimization_level=3, backend=sim_thermal\n",
        ")\n",
        "circ_tthermal = passmanager.run(circ)\n",
        "\n",
        "# Run and get counts\n",
        "result_thermal = sim_thermal.run(circ_tthermal).result()\n",
        "counts_thermal = result_thermal.get_counts(0)\n",
        "\n",
        "# Plot noisy output\n",
        "plot_histogram(counts_thermal)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "0df436e1-b43c-41b1-9581-a4d530e51a7b",
      "metadata": {},
      "source": [
        "<span id=\"next-steps\" />\n",
        "\n",
        "## Nächste Schritte\n",
        "\n",
        "<Admonition type=\"tip\" title=\"Empfehlungen\">\n",
        "  * Informationen zur Simulation von Schaltungen mit Rauschen finden Sie unter „[Exakte und rauschbehaftete Simulation mit Qiskit Aer-Primitiven](/docs/guides/simulate-with-qiskit-sdk-primitives) “.\n",
        "  * Lesen Sie die Referenz des [Qiskit Aer noise module](https://qiskit.org/ecosystem/aer/apidocs/aer_noise.html).\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
}