{
  "cells": [
    {
      "cell_type": "markdown",
      "id": "e6d26387-f218-4f62-80c4-792103129b99",
      "metadata": {},
      "source": [
        "---\n",
        "title: \"Effiziente Simulation von Stabilisierungsschaltungen mit Qiskit Aer-Primitiven\"\n",
        "description: \"Wie man Stabilisierungsschaltungen mit Qiskit Aer-Primitiven effizient simuliert.\"\n",
        "---\n",
        "\n",
        "<span id=\"efficient-simulation-of-stabilizer-circuits-with-qiskit-aer-primitives\" />\n",
        "\n",
        "# Effiziente Simulation von Stabilisierungsschaltungen mit Qiskit Aer-Primitiven\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=\"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-aer~=0.17\n",
        "    ```\n",
        "  </AccordionItem>\n",
        "</Accordion>\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "386709ed-183b-4759-bb1b-56cdedf80539",
      "metadata": {},
      "source": [
        "Diese Seite zeigt, wie Qiskit Aer Primitive verwendet werden können, um Stabilisatorschaltungen effizient zu simulieren, einschließlich solcher, die Pauli-Rauschen unterliegen.\n",
        "\n",
        "Stabilisatorschaltungen, auch bekannt als Clifford-Schaltungen, sind eine wichtige eingeschränkte Klasse von Quantenschaltungen, die effizient klassisch simuliert werden können. Es gibt mehrere gleichwertige Möglichkeiten, Stabilisierungsschaltungen zu definieren. Eine Definition besagt, dass eine Stabilisierungsschaltung eine Quantenschaltung ist, die ausschließlich aus den folgenden Gattern besteht:\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",
        "* [Messwert](../api/qiskit/circuit#qiskit.circuit.Measure)\n",
        "\n",
        "Man beachte, dass man mit Hilfe von Hadamard und S ein beliebiges Pauli-Drehungstor konstruieren kann ( [$R_x$](/docs/api/qiskit/qiskit.circuit.library.RXGate), [$R_y$](/docs/api/qiskit/qiskit.circuit.library.RYGate), und [$R_z$](/docs/api/qiskit/qiskit.circuit.library.RZGate) ) konstruieren kann, dessen Winkel in der Menge $\\{0, \\frac{\\pi}{2}, \\pi, \\frac{3\\pi}{2}\\}$ (bis zur globalen Phase) enthalten ist, so dass wir auch diese Gatter in die Definition einbeziehen können.\n",
        "\n",
        "Stabilisierungsschaltungen sind wichtig für die Untersuchung der Quantenfehlerkorrektur. Aufgrund ihrer klassischen Simulierbarkeit eignen sie sich auch zur Überprüfung der Leistung von Quantencomputern. Nehmen wir zum Beispiel an, Sie wollen einen Quantenschaltkreis mit 100 Qubits auf einem Quantencomputer ausführen. Woher weiß man, dass sich der Quantencomputer korrekt verhält? Ein Quantenschaltkreis mit 100 Qubits übersteigt die Möglichkeiten einer klassischen Brute-force-Simulation. Indem Sie Ihre Schaltung so modifizieren, dass sie zu einer Stabilisierungsschaltung wird, können Sie auf dem Quantencomputer Schaltungen ausführen, die eine ähnliche Struktur wie Ihre gewünschte Schaltung haben, die Sie aber auf einem klassischen Computer simulieren können. Wenn Sie die Leistung des Quantencomputers an den Stabilisatorschaltungen überprüfen, können Sie sicher sein, dass er sich auch an den Nicht-Stabilisatorschaltungen korrekt verhält. Ein Beispiel für diese Idee in der Praxis finden Sie unter [*Beweise für den Nutzen der Quanteninformatik vor der Fehlertoleranz*](https://www.nature.com/articles/s41586-023-06096-3).\n",
        "\n",
        "[Exakte und verrauschte Simulationen mit Qiskit Aer Primitiven](simulate-with-qiskit-aer) zeigt, wie man [Qiskit Aer](https://qiskit.org/ecosystem/aer/) verwendet, um exakte und verrauschte Simulationen von generischen Quantenschaltungen durchzuführen. Betrachten Sie die in diesem Artikel verwendete Beispielschaltung, eine 8-Qubit-Schaltung, die mit [efficient\\_su2](../api/qiskit/qiskit.circuit.library.efficient_su2) gebaut wurde:\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": [
        "Mit Qiskit Aer konnten wir diese Schaltung leicht simulieren. Nehmen wir jedoch an, wir setzen die Anzahl der Qubits auf 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": [
        "Da die Kosten für die Simulation von Quantenschaltungen exponentiell mit der Anzahl der Qubits skalieren, würde eine so große Schaltung im Allgemeinen selbst die Möglichkeiten eines Hochleistungssimulators wie Qiskit Aer übersteigen. Die klassische Simulation allgemeiner Quantenschaltungen wird undurchführbar, wenn die Anzahl der Qubits etwa 50 bis 100 Qubits übersteigt. Beachten Sie jedoch, dass die efficient\\_su2 Schaltung durch Winkel auf $R_y$ und $R_z$ Gattern parametrisiert ist. Wenn alle diese Winkel in der Menge $\\{0, \\frac{\\pi}{2}, \\pi, \\frac{3\\pi}{2}\\}$ enthalten sind, dann ist die Schaltung eine Stabilisatorschaltung, und sie kann effizient simuliert werden!\n",
        "\n",
        "In der folgenden Zelle führen wir die Schaltung mit dem Sampler-Primitiv aus, das durch den Stabilisator-Schaltungssimulator unterstützt wird, und verwenden dabei zufällig ausgewählte Parameter, so dass die Schaltung garantiert eine Stabilisator-Schaltung ist.\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": [
        "Der Stabilisator-Schaltungssimulator unterstützt auch die Simulation von Rauschen, allerdings nur für eine begrenzte Klasse von Rauschmodellen. Insbesondere muss jedes Quantenrauschen durch einen [Pauli-Fehlerkanal](https://qiskit.org/ecosystem/aer/stubs/qiskit_aer.noise.pauli_error.html#qiskit_aer.noise.pauli_error) gekennzeichnet sein. [Der Depolarisationsfehler](https://qiskit.org/ecosystem/aer/stubs/qiskit_aer.noise.depolarizing_error.html) fällt in diese Kategorie, so dass er ebenfalls simuliert werden kann. Klassische Rauschkanäle wie [Auslesefehler](https://qiskit.org/ecosystem/aer/stubs/qiskit_aer.noise.ReadoutError.html) können ebenfalls simuliert werden.\n",
        "\n",
        "Die folgende Codezelle führt dieselbe Simulation wie zuvor aus, aber diesmal mit einem Rauschmodell, das jedem CX-Gatter einen Depolarisationsfehler von 2 % hinzufügt, sowie einen Auslesefehler, der jedes gemessene Bit mit einer Wahrscheinlichkeit von 5 % umkehrt.\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": [
        "Verwenden wir nun das Estimator-Primitiv, das vom Stabilisatorsimulator unterstützt wird, um den Erwartungswert der Beobachtungsgröße $ZZ \\cdots Z$ zu berechnen. Aufgrund der besonderen Struktur von Stabilisatorschaltungen ist das Ergebnis sehr wahrscheinlich 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",
        "## Nächste Schritte\n",
        "\n",
        "<Admonition type=\"tip\" title=\"Empfehlungen\">\n",
        "  * Informationen zur Simulation von Schaltungen mit Qiskit Aer finden Sie unter „[Exakte und verrauschte Simulation mit Qiskit Aer-Primitiven](/docs/guides/simulate-with-qiskit-sdk-primitives) “.\n",
        "  * Lesen Sie die [Qiskit Aer-Dokumentation](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
}