{
  "cells": [
    {
      "cell_type": "markdown",
      "id": "3a5616bf-6edb-4539-872a-03217649edcb",
      "metadata": {},
      "source": [
        "---\n",
        "title: \"Erstellen Sie einen Passmanager für die dynamische Entkopplung\"\n",
        "description: \"Wie man einen Pass-Manager für dynamische Entkopplung in Qiskit erstellt.\"\n",
        "---\n",
        "\n",
        "<span id=\"create-a-pass-manager-for-dynamical-decoupling\" />\n",
        "\n",
        "# Erstellen Sie einen Passmanager für die dynamische Entkopplung\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "a5662d8c-46f8-40a8-92b5-af63c32d303f",
      "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",
        "    ```\n",
        "  </AccordionItem>\n",
        "</Accordion>\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "1ed6dc8d-b6f2-43dc-bb40-ceec0f311764",
      "metadata": {},
      "source": [
        "Auf dieser Seite wird gezeigt, wie man mit dem [`PadDynamicalDecoupling`](/docs/api/qiskit/qiskit.transpiler.passes.PadDynamicalDecoupling) pass verwenden, um eine Fehlerunterdrückungstechnik namens *dynamische Entkopplung* in die Schaltung einzubauen.\n",
        "\n",
        "Die dynamische Entkopplung funktioniert durch das Hinzufügen von Impulssequenzen (bekannt als *dynamische Entkopplungssequenzen* ) zu untätigen Qubits, um sie um die Bloch-Sphäre zu drehen, was die Wirkung von Rauschkanälen aufhebt und dadurch die Dekohärenz unterdrückt. Diese Impulsfolgen ähneln den Refokussierungsimpulsen, die bei der kernmagnetischen Resonanz verwendet werden. Eine vollständige Beschreibung finden Sie in [A Quantum Engineer's Guide to Superconducting Qubits](https://arxiv.org/abs/1904.06560).\n",
        "\n",
        "Da der Durchgang `PadDynamicalDecoupling` nur auf geplanten Schaltungen arbeitet und Gatter einbezieht, die nicht unbedingt Basisgatter unseres Ziels sind, benötigen Sie die [`ALAPScheduleAnalysis`](/docs/api/qiskit/qiskit.transpiler.passes.ALAPScheduleAnalysis) und [`BasisTranslator`](/docs/api/qiskit/qiskit.transpiler.passes.BasisTranslator) durchgänge ebenfalls.\n",
        "\n",
        "Rufen Sie die `target` Informationen aus der `backend` Tabelle ab und speichern Sie die Operationsnamen als `basis_gates` \\[Dateiname], da die Tabelle angepasst `target` werden muss, um Zeitangaben für die bei der dynamischen Entkopplung verwendeten Gatter hinzuzufügen.\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.  Ihre Ergebnisse können davon abweichen.\n",
        "</Admonition>\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 1,
      "id": "c55c6e3b-4016-4866-b2ec-19793e89d215",
      "metadata": {},
      "outputs": [],
      "source": [
        "from qiskit_ibm_runtime.fake_provider import FakeSherbrooke\n",
        "\n",
        "backend = FakeSherbrooke()\n",
        "\n",
        "target = backend.target\n",
        "basis_gates = list(target.operation_names)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "b8dfccd9-30c9-48dc-88bc-50af3256f187",
      "metadata": {},
      "source": [
        "Erstellen Sie als Beispiel eine Schaltung `efficient_su2` . Transpilieren Sie zunächst die Schaltung in das Backend, da dynamische Entkopplungsimpulse hinzugefügt werden müssen, nachdem die Schaltung transpiliert und terminiert worden ist. Die dynamische Entkopplung funktioniert oft am besten, wenn es in den Quantenschaltkreisen viel Leerlaufzeit gibt - das heißt, es gibt Qubits, die nicht benutzt werden, während andere aktiv sind. Dies ist in dieser Schaltung der Fall, da die Zwei-Qubit-Gatter `ecr` in diesem Ansatz nacheinander angewendet werden.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 2,
      "id": "9479a60c-d5d0-45c7-a93e-a2a488ba8985",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "<Image src=\"/docs/images/guides/dynamical-decoupling-pass-manager/extracted-outputs/9479a60c-d5d0-45c7-a93e-a2a488ba8985-0.svg\" alt=\"Output of the previous code cell\" />"
            ]
          },
          "execution_count": 2,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "from qiskit.transpiler import generate_preset_pass_manager\n",
        "from qiskit.circuit.library import efficient_su2\n",
        "\n",
        "qc = efficient_su2(12, entanglement=\"circular\", reps=1)\n",
        "pm = generate_preset_pass_manager(1, target=target, seed_transpiler=12345)\n",
        "qc_t = pm.run(qc)\n",
        "qc_t.draw(\"mpl\", fold=-1, idle_wires=False)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "d3ab848d-2782-431c-b028-69a46cf94360",
      "metadata": {},
      "source": [
        "Eine dynamische Entkopplungssequenz ist eine Reihe von Gattern, die sich zur Identität zusammensetzen und in einem regelmäßigen zeitlichen Abstand angeordnet sind. Beginnen Sie beispielsweise mit der Erstellung einer einfachen Sequenz namens XY4, die aus vier Gattern besteht.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 3,
      "id": "368df772-aee7-4b59-b096-a47e5bc94577",
      "metadata": {},
      "outputs": [],
      "source": [
        "from qiskit.circuit.library import XGate, YGate\n",
        "\n",
        "X = XGate()\n",
        "Y = YGate()\n",
        "\n",
        "dd_sequence = [X, Y, X, Y]"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "d5eafd85-6fea-42ac-8bcb-0abf15635456",
      "metadata": {},
      "source": [
        "Aufgrund des regelmäßigen Zeitpunkts dynamischer Entkopplungssequenzen müssen `YGate` Informationen über das zum hinzugefügt werden, `target` da es sich *nicht* um ein Basisgatter handelt, während das ein `XGate` Basisgatter ist. Wir wissen *a priori*, dass das die gleiche Dauer und `YGate` den gleichen Fehler wie das hat `XGate`, daher können wir diese Eigenschaften einfach aus dem abrufen `target` und sie für die `YGate` Objekte wieder hinzufügen. Aus diesem Grund wurden auch `basis_gates` die separat gespeichert, da wir die `YGate` Anweisung zum hinzufügen `target` , obwohl es sich nicht um ein tatsächliches Basisgatter von handelt `ibm_fez`.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 4,
      "id": "cabac6ca-c845-4c05-8c7d-2940717b3120",
      "metadata": {},
      "outputs": [],
      "source": [
        "from qiskit.transpiler import InstructionProperties\n",
        "\n",
        "y_gate_properties = {}\n",
        "for qubit in range(target.num_qubits):\n",
        "    y_gate_properties.update(\n",
        "        {\n",
        "            (qubit,): InstructionProperties(\n",
        "                duration=target[\"x\"][(qubit,)].duration,\n",
        "                error=target[\"x\"][(qubit,)].error,\n",
        "            )\n",
        "        }\n",
        "    )\n",
        "\n",
        "target.add_instruction(YGate(), y_gate_properties)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "d33f64d6-c4e3-4881-a924-f30dfce35106",
      "metadata": {},
      "source": [
        "Ansatzschaltungen wie `efficient_su2` sind parametrisiert, d. h. sie müssen mit einem Wert versehen werden, bevor sie an das Backend gesendet werden. Weisen Sie hier zufällige Parameter zu.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 5,
      "id": "788839cc-9378-4c9d-95fd-df0ec6bc2d64",
      "metadata": {},
      "outputs": [],
      "source": [
        "import numpy as np\n",
        "\n",
        "rng = np.random.default_rng(1234)\n",
        "qc_t.assign_parameters(\n",
        "    rng.uniform(-np.pi, np.pi, qc_t.num_parameters), inplace=True\n",
        ")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "36d54ded-1786-41c0-9c8a-75f339dbd160",
      "metadata": {},
      "source": [
        "Führen Sie anschließend die benutzerdefinierten Übergänge aus. Richten Sie die `PassManager` mit `ALAPScheduleAnalysis` und `PadDynamicalDecoupling` ein.  Führen Sie zuerst `ALAPScheduleAnalysis` aus, um Zeitinformationen über den Quantenschaltkreis hinzuzufügen, bevor die dynamischen Entkopplungssequenzen in regelmäßigen Abständen hinzugefügt werden können. Diese Pässe werden auf der Strecke mit `.run()` gefahren.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 6,
      "id": "334796e7-fb37-42fa-be54-4135b485246b",
      "metadata": {},
      "outputs": [],
      "source": [
        "from qiskit.transpiler import PassManager\n",
        "from qiskit.transpiler.passes.scheduling import (\n",
        "    ALAPScheduleAnalysis,\n",
        "    PadDynamicalDecoupling,\n",
        ")\n",
        "\n",
        "dd_pm = PassManager(\n",
        "    [\n",
        "        ALAPScheduleAnalysis(target=target),\n",
        "        PadDynamicalDecoupling(target=target, dd_sequence=dd_sequence),\n",
        "    ]\n",
        ")\n",
        "qc_dd = dd_pm.run(qc_t)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "b0f68880-066c-4586-a27c-5d0f90d674f7",
      "metadata": {},
      "source": [
        "Verwenden Sie das Visualisierungstool, [`timeline_drawer`](/docs/api/qiskit/qiskit.visualization.timeline_drawer) um das Timing der Schaltung anzuzeigen und zu überprüfen, ob eine regelmäßig angeordnete Folge von `XGate` Objekten und `YGate` Objekten in der Schaltung erscheint.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 7,
      "id": "7a552621-a96f-4bb8-ae9b-4ab5a65bbb64",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "<Image src=\"/docs/images/guides/dynamical-decoupling-pass-manager/extracted-outputs/7a552621-a96f-4bb8-ae9b-4ab5a65bbb64-0.svg\" alt=\"Output of the previous code cell\" />"
            ]
          },
          "execution_count": 7,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "from qiskit.visualization import timeline_drawer\n",
        "\n",
        "timeline_drawer(qc_dd, idle_wires=False, target=target)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "836a4094-0e55-4028-9e2e-cdf561d27049",
      "metadata": {},
      "source": [
        "Da `YGate` kein tatsächliches Basis-Gate unseres Backends ist, müssen Sie den `BasisTranslator` -Pass manuell anwenden (dies ist ein Standard-Pass, der jedoch vor der Planung ausgeführt wird, so dass er erneut angewendet werden muss). Die Sitzungsäquivalenzbibliothek ist eine Bibliothek von Schaltkreisäquivalenzen, die es dem Transpiler ermöglicht, Schaltkreise in Basisgatter zu zerlegen, wie ebenfalls als Argument angegeben.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 8,
      "id": "f0f4b29d-1c95-47d2-a7ad-8e130eaff74a",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "<Image src=\"/docs/images/guides/dynamical-decoupling-pass-manager/extracted-outputs/f0f4b29d-1c95-47d2-a7ad-8e130eaff74a-0.svg\" alt=\"Output of the previous code cell\" />"
            ]
          },
          "execution_count": 8,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "from qiskit.circuit.equivalence_library import (\n",
        "    SessionEquivalenceLibrary as sel,\n",
        ")\n",
        "from qiskit.transpiler.passes import BasisTranslator\n",
        "\n",
        "qc_dd = BasisTranslator(sel, basis_gates)(qc_dd)\n",
        "qc_dd.draw(\"mpl\", fold=-1, idle_wires=False)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "fafca471-0042-41f8-964c-606b4ee0d5cd",
      "metadata": {},
      "source": [
        "Nun fehlen Objekte in unserem `YGate` Schaltkreis, und es gibt explizite Zeitinformationen in Form von `Delay` Gattern. Diese transpilierte Schaltung mit dynamischer Entkopplung kann nun an das Backend gesendet werden.\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "95fee5f9-9e7d-47db-83c2-309ca03d357a",
      "metadata": {},
      "source": [
        "<span id=\"next-steps\" />\n",
        "\n",
        "## Nächste Schritte\n",
        "\n",
        "<Admonition type=\"tip\" title=\"Empfehlungen\">\n",
        "  * Wenn Sie wissen möchten, wie Sie die Funktion `generate_preset_passmanager` verwenden können, anstatt Ihre eigenen Pässe zu schreiben, beginnen Sie mit dem Thema [Transpilations-Standardeinstellungen und Konfigurationsoptionen](defaults-and-configuration-options).\n",
        "  * Probieren Sie die Anleitung [zum Vergleichen der Transpiler-Einstellungen](/docs/guides/circuit-transpilation-settings#compare-transpiler-settings) aus.\n",
        "  * Siehe die [Transpile-API-Dokumentation](https://docs.quantum-computing.ibm.com/api/qiskit/transpiler).\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
}