{
  "cells": [
    {
      "cell_type": "markdown",
      "id": "d0e7f54f-e951-44d4-8cd8-5b539cf5c91c",
      "metadata": {},
      "source": [
        "---\n",
        "title: \"Beispiele für Testamentsvollstrecker\"\n",
        "description: \"Praktische Beispiele für die Verwendung der „Executor“-Primitive in qiskit-ibm-runtime.\"\n",
        "---\n",
        "\n",
        "<span id=\"executor-examples\" />\n",
        "\n",
        "# Beispiele für Testamentsvollstrecker\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "a53ccd93-5bca-4dfb-a8a0-fcf4ed046fa7",
      "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, diese Versionen oder neuere zu verwenden.\n",
        "\n",
        "    ```\n",
        "    qiskit[all]~=2.5.2\n",
        "    qiskit-ibm-runtime~=0.47.0\n",
        "    samplomatic~=0.21.0\n",
        "    ```\n",
        "  </AccordionItem>\n",
        "</Accordion>\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "fed832ee-87a7-4261-874d-84002f3863b5",
      "metadata": {},
      "source": [
        "Die Beispiele in diesem Abschnitt veranschaulichen einige gängige Anwendungsmöglichkeiten der Executor-Primitive. Bevor Sie diese Beispiele ausführen, befolgen Sie bitte die Anweisungen unter „[Qiskit](/docs/guides/install-qiskit) und [Executor installieren – Schnellstart](/docs/guides/directed-execution-model) “.\n",
        "\n",
        "<span id=\"before-you-begin\" />\n",
        "\n",
        "## Vorbereitende Schritte\n",
        "\n",
        "Einige der Code-Beispiele auf dieser Seite verwenden `samplex`, das zum Samplomatic-Paket gehört.  Bevor Sie diese Code-Blöcke ausführen, müssen Sie daher Samplomatic installieren, wie im folgenden Code-Block gezeigt.  Weitere Informationen finden Sie in der [Samplomatic-Dokumentation](https://qiskit.github.io/samplomatic).\n",
        "\n",
        "```python\n",
        "pip install samplomatic\n",
        "\n",
        "# For visualization support, include the visualization dependencies.\n",
        "# pip install samplomatic[vis]\n",
        "```\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "19549d62-4095-458d-a691-00b9bc456ed5",
      "metadata": {},
      "source": [
        "<span id=\"example-parameterized-circuit\" />\n",
        "\n",
        "## Beispiel: Parametrisierte Schaltung\n",
        "\n",
        "Dieses Beispiel zeigt, wie man Schaltkreiselemente mit Parametern sowie Samplex-Elemente hinzufügt. Es umfasst folgende Schritte:\n",
        "\n",
        "1. Schaltung einrichten: Erstellen und transpilieren Sie die Zielschaltung.\n",
        "2. Erstellen Sie ein Samplex: Gruppieren Sie Gatter und Messungen in beschrifteten Feldern und generieren Sie die Schaltungsvorlage sowie das Samplex-Paar.\n",
        "3. Ausführen: Fügen Sie ein Schaltkreis-Element und ein Samplex-Element zu einem `QuantumProgram` Job hinzu und führen Sie beide in einem einzigen Job aus.\n",
        "\n",
        "<span id=\"set-up-the-circuit\" />\n",
        "\n",
        "### Schalte den Schaltkreis zusammen\n",
        "\n",
        "Bereite einen GHZ-Zustand mit drei Qubits vor, drehe die Qubits um die Pauli-Z-Achse und miss die Qubits in der Rechenbasis.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 1,
      "id": "caf43d3e-ed55-4805-8d19-6c0980eeb1dc",
      "metadata": {},
      "outputs": [],
      "source": [
        "from qiskit.circuit import Parameter, QuantumCircuit\n",
        "from qiskit_ibm_runtime import QiskitRuntimeService, Executor\n",
        "from qiskit_ibm_runtime.quantum_program import QuantumProgram\n",
        "from qiskit.transpiler import generate_preset_pass_manager\n",
        "import numpy as np\n",
        "from samplomatic import build\n",
        "from samplomatic.transpiler import generate_boxing_pass_manager\n",
        "\n",
        "# Generate the circuit\n",
        "circuit = QuantumCircuit(3)\n",
        "circuit.h(0)\n",
        "circuit.h(1)\n",
        "circuit.cz(0, 1)\n",
        "circuit.h(1)\n",
        "circuit.h(2)\n",
        "circuit.cz(1, 2)\n",
        "circuit.h(2)\n",
        "circuit.rz(Parameter(\"theta\"), 0)\n",
        "circuit.rz(Parameter(\"phi\"), 1)\n",
        "circuit.rz(Parameter(\"lam\"), 2)\n",
        "circuit.measure_all()"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "f95bc53d-ed01-4b94-988b-1e497916d0fa",
      "metadata": {},
      "source": [
        "Geben Sie das Backend an und transpilieren Sie die Schaltung so, dass ausschließlich von der QPU unterstützte Befehle verwendet werden (sogenannte ISA-Schaltung).\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 2,
      "id": "bf633f01-372f-4519-b89d-ab4075255bd9",
      "metadata": {},
      "outputs": [],
      "source": [
        "# Initialize the service and choose a backend\n",
        "service = QiskitRuntimeService()\n",
        "backend = service.least_busy(operational=True, simulator=False)\n",
        "\n",
        "# Transpile the circuit to ISA\n",
        "preset_pass_manager = generate_preset_pass_manager(\n",
        "    backend=backend, optimization_level=3\n",
        ")\n",
        "isa_circuit = preset_pass_manager.run(circuit)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "fbecf32d-d1b9-4e12-ab56-0a1ede7ebf04",
      "metadata": {},
      "source": [
        "<span id=\"prepare-the-samplex\" />\n",
        "\n",
        "### Bereiten Sie den Samplex vor\n",
        "\n",
        "Verwenden Sie die `generate_boxing_pass_manager` Komfortfunktion und ihre Twirling-Parameter, um Zwei-Qubit-Gatter und Messungen in Boxen zu gruppieren und Twirling-Annotationen hinzuzufügen.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 3,
      "id": "8d6d64ad-12ee-4c0c-a683-d1178600d3c7",
      "metadata": {},
      "outputs": [],
      "source": [
        "boxing_pm = generate_boxing_pass_manager(\n",
        "    # Add gate twirling\n",
        "    enable_gates=True,\n",
        "    # Add measurement twirling\n",
        "    enable_measures=True,\n",
        ")\n",
        "\n",
        "boxed_circuit = boxing_pm.run(isa_circuit)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "2e8fb1f9-4b15-4161-9f8f-1c24d64b0045",
      "metadata": {},
      "source": [
        "Verwenden Sie die `build` Methode, um die Schaltungsvorlage und das Samplex zu generieren.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 4,
      "id": "90e21ca1-7f39-4636-b65e-28685b610a3c",
      "metadata": {},
      "outputs": [],
      "source": [
        "# Build the template circuit and the samplex\n",
        "template_circuit, samplex = build(boxed_circuit)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "521a7263-8d2f-46fd-a261-c23ae56aa5b5",
      "metadata": {},
      "source": [
        "<span id=\"execute-the-circuits\" />\n",
        "\n",
        "### Führen Sie die Zirkeltrainings durch\n",
        "\n",
        "Der Executor führt `QuantumProgram` Objekte aus. Jedes `QuantumProgram` kann mehrere Elemente enthalten. In diesem Beispiel werden ein Schaltkreis-Element und ein Samplex-Element zur Ausführung hinzugefügt. Ausführliche Informationen finden Sie unter „[Executor-Ein- und -Ausgabe](/docs/guides/executor-input-output) “.\n",
        "\n",
        "Der erste Schritt besteht darin, ein leeres Programm zu initialisieren, das für jede Konfiguration jedes Elements Aufnahmen anfordert `1024` .\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 5,
      "id": "85d7d9ef-a74c-42e4-a758-0f490e29275d",
      "metadata": {},
      "outputs": [],
      "source": [
        "# Generate a quantum program\n",
        "program = QuantumProgram(shots=1024)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "8869d18d-cc0e-4556-a195-cd6b590bcef7",
      "metadata": {},
      "source": [
        "Füge das Schaltkreiselement an das `QuantumProgram`. an. Dieser Schaltungsartikel besteht aus zwei Teilen – der ISA-Schaltung und 10 Sätzen ihrer Parameterwerte.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 6,
      "id": "19963674-3e72-473c-b24a-228316946dc5",
      "metadata": {},
      "outputs": [],
      "source": [
        "# Append the circuit and the parameter values to the program\n",
        "program.append_circuit_item(\n",
        "    isa_circuit,\n",
        "    circuit_arguments=np.random.rand(10, 3),  # 10 sets of parameter values\n",
        ")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "41505f83-a7a6-4ea8-a7fc-a3fb45a2992a",
      "metadata": {},
      "source": [
        "Füge das Samplex-Element mit diesen Argumenten an das `QuantumProgram` an:\n",
        "\n",
        "* Die Schaltungsvorlage und der von der `build` Funktion erzeugte Samplex\n",
        "* Zehn Sätze von Parameterwerten für die ursprüngliche Schaltung\n",
        "* Die Anzahl der durchzuführenden Randomisierungen\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 7,
      "id": "d6b07700-5834-4baa-a08a-434516f5bc07",
      "metadata": {},
      "outputs": [],
      "source": [
        "# Append the template circuit and samplex as a samplex item\n",
        "program.append_samplex_item(\n",
        "    template_circuit,\n",
        "    samplex=samplex,\n",
        "    samplex_arguments={\n",
        "        \"parameter_values\": np.random.rand(\n",
        "            10, 3\n",
        "        ),  # 10 sets of parameter values\n",
        "    },\n",
        "    shape=(2, 14, 10),\n",
        ")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "f39e3e78-5953-4801-b521-dd48ae487acf",
      "metadata": {},
      "source": [
        "<span id=\"run-the-executor-job\" />\n",
        "\n",
        "### Executor-Job ausführen\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 8,
      "id": "149addb2-e76f-427c-bac4-54b6a83ddb0a",
      "metadata": {},
      "outputs": [],
      "source": [
        "# initialize an Executor with default options\n",
        "executor = Executor(mode=backend)\n",
        "\n",
        "# Submit the job\n",
        "job = executor.run(program)\n",
        "\n",
        "# Retrieve the result\n",
        "result = job.result()"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "93698fec-cff7-4153-8cbb-f7e39c972d9a",
      "metadata": {},
      "source": [
        "Rufe das Ergebnis für jede Aufgabe ab.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 9,
      "id": "77235bf8-bcac-43fb-89b0-9ba74b976053",
      "metadata": {},
      "outputs": [],
      "source": [
        "# Access the results of the classical register of task #0, the CircuitItem\n",
        "result_0 = result[0][\"meas\"]\n",
        "\n",
        "# Access the results of the classical register of task #1, the SamplexItem\n",
        "result_1 = result[1][\"meas\"]"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "64063941-87b5-4c5d-bbf9-8920c24a216f",
      "metadata": {},
      "source": [
        "<span id=\"example-perform-pec\" />\n",
        "\n",
        "## Beispiel: PEC durchführen\n",
        "\n",
        "Dieses Beispiel zeigt, wie man mit einem Samplex-Element eine probabilistische Fehlerkompensation ( [PEC](/docs/guides/error-mitigation-and-suppression-techniques#pec) ) zur Fehlerminderung durchführt.\n",
        "\n",
        "Betrachten wir eine gespiegelte Version einer Schaltung mit zehn Qubits und zwei unterschiedlichen Schichten von CX-Gattern. Dies sind die wichtigsten Aufgaben:\n",
        "\n",
        "* Führe die Übung mit Drehbewegungen aus.\n",
        "* Führen Sie die Schaltung mit PEC-Kompensation aus, wie in der Veröffentlichung [„Probabilistic error cancellation with sparse Pauli-Lindblad models on noisy quantum processors“](https://arxiv.org/abs/2201.09866) beschrieben.\n",
        "\n",
        "Die Pipeline umfasst folgende Schritte:\n",
        "\n",
        "1. Vorgehensweise: Erstellen Sie die Zielschaltung und fassen Sie deren Operationen in Blöcken zusammen.\n",
        "2. Lernen: Ermitteln Sie das Rauschen der Befehle, das wir mit PEC unterdrücken wollen.\n",
        "3. Ausführen: Den Schaltkreis auf einem Backend ausführen.\n",
        "4. Auswerten: Die Ergebnisse nachbearbeiten und auswerten.\n",
        "\n",
        "Zum Vergleich werden wir diese gespiegelte Schaltung zweimal ausführen. Einmal nur mit Pauli-Twist und einmal mit PEC-Minderung.\n",
        "\n",
        "<Admonition type=\"note\">\n",
        "  Die Ausführungszeit für dieses Beispiel beträgt auf einem Heron-Prozessor ( r2 ) etwa 10 Minuten.\n",
        "</Admonition>\n",
        "\n",
        "<span id=\"set-up-the-circuit\" />\n",
        "\n",
        "### Schalte den Schaltkreis zusammen\n",
        "\n",
        "Wählen Sie ein Backend aus und erstellen Sie eine Schaltung mit 10 Qubits.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 10,
      "id": "f9e93b2c-154a-4d09-872d-f770bcc669c4",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "<Image src=\"/docs/images/guides/executor-examples/extracted-outputs/f9e93b2c-154a-4d09-872d-f770bcc669c4-0.svg\" alt=\"Output of the previous code cell\" />"
            ]
          },
          "execution_count": 10,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "from qiskit_ibm_runtime import QiskitRuntimeService, Executor\n",
        "from qiskit_ibm_runtime.quantum_program import QuantumProgram\n",
        "from qiskit.circuit import QuantumCircuit, Parameter\n",
        "from qiskit.transpiler import generate_preset_pass_manager\n",
        "from samplomatic.transpiler import generate_boxing_pass_manager\n",
        "from samplomatic import build\n",
        "\n",
        "# Initialize the service and choose a backend\n",
        "service = QiskitRuntimeService()\n",
        "backend = service.least_busy(operational=True, simulator=False)\n",
        "\n",
        "# Prepare a circuit\n",
        "\n",
        "num_qubits = 10\n",
        "num_layers = 10\n",
        "\n",
        "qubits = list(range(num_qubits))\n",
        "circuit = QuantumCircuit(num_qubits)\n",
        "\n",
        "for layer_idx in range(num_layers):\n",
        "    circuit.rx(Parameter(f\"theta_{layer_idx}\"), qubits)\n",
        "    for i in range(num_qubits // 2):\n",
        "        circuit.cz(qubits[2 * i], qubits[2 * i + 1])\n",
        "\n",
        "    circuit.rx(Parameter(f\"phi_{layer_idx}\"), qubits)\n",
        "    for i in range(num_qubits // 2 - 1):\n",
        "        circuit.cz(qubits[2 * i] + 1, qubits[2 * i + 1] + 1)\n",
        "\n",
        "circuit.draw(\"mpl\", scale=0.35, fold=100)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "2d76f4f5-48b7-4123-8b6b-32eeaa06527d",
      "metadata": {},
      "source": [
        "Kombiniere die Schaltung mit ihrer Umkehrschaltung, um eine Spiegelschaltung zu bilden.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 11,
      "id": "f8ac3f75-88ca-40f9-8382-6a427303bb8e",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "<Image src=\"/docs/images/guides/executor-examples/extracted-outputs/f8ac3f75-88ca-40f9-8382-6a427303bb8e-0.svg\" alt=\"Output of the previous code cell\" />"
            ]
          },
          "execution_count": 11,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "mirror_circuit = circuit.compose(circuit.inverse())\n",
        "mirror_circuit.measure_all()\n",
        "\n",
        "mirror_circuit.draw(\"mpl\", scale=0.35, fold=100)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "2bb0692c-3d4f-4a74-807e-6b93ef4ea8d2",
      "metadata": {},
      "source": [
        "Lege einige Parameterwerte fest:\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 12,
      "id": "c1974bff-c738-43a8-8e27-b85059e2428a",
      "metadata": {},
      "outputs": [],
      "source": [
        "import numpy as np\n",
        "\n",
        "parameter_values = np.random.rand(mirror_circuit.num_parameters)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "0ca9f203-008b-4190-9e86-affefb303938",
      "metadata": {},
      "source": [
        "Verwenden Sie den Pass-Manager, um die Schaltung in eine ISA-Schaltung zu transpilieren.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 13,
      "id": "224e0d6d-9238-4fae-aad8-f051c7e34938",
      "metadata": {},
      "outputs": [],
      "source": [
        "preset_pass_manager = generate_preset_pass_manager(\n",
        "    backend=backend,\n",
        "    optimization_level=3,\n",
        ")\n",
        "\n",
        "isa_circuit = preset_pass_manager.run(mirror_circuit)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "9dd71644-df3d-4cf3-9e4b-9c7624b54961",
      "metadata": {},
      "source": [
        "Gruppieren Sie anschließend die Gatter und Messungen in beschrifteten Feldern. Sie können dies manuell tun oder der Einfachheit halber die `generate_boxing_pass_manager` Funktion von Samplomatic verwenden. Auf den ersten Schaltkreis wird lediglich eine Drehung angewendet, daher ist lediglich die `Twirl` Anmerkung erforderlich. Der zweite Durchlauf wird mit vollständiger PEC-Abmilderung durchgeführt und erfordert sowohl `Twirl` als auch `InjectNoise` Anmerkungen.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 14,
      "id": "4afb22f1-b41f-40ed-87f7-c2d0b0f6730c",
      "metadata": {},
      "outputs": [],
      "source": [
        "# Pass manager used to create twirled-annotated boxes.\n",
        "boxing_pm = generate_boxing_pass_manager(\n",
        "    enable_gates=True,\n",
        "    enable_measures=True,\n",
        ")\n",
        "\n",
        "mirror_circuit_twirl = boxing_pm.run(isa_circuit)\n",
        "\n",
        "# Pass manager used to create a new boxed circuit with\n",
        "# both Twirl and InjectNoise annotations.\n",
        "boxing_pm = generate_boxing_pass_manager(\n",
        "    enable_gates=True,\n",
        "    enable_measures=True,\n",
        "    inject_noise_targets=\"gates\",  # no measurement mitigation\n",
        "    inject_noise_strategy=\"uniform_modification\",\n",
        ")\n",
        "\n",
        "mirror_circuit_pec = boxing_pm.run(isa_circuit)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "bd0c7cc5-48ba-47ab-84bc-41f832af3d8d",
      "metadata": {},
      "source": [
        "<span id=\"learn-the-noise\" />\n",
        "\n",
        "### Lerne den Klang kennen\n",
        "\n",
        "`InjectNoise`Um die Anzahl der Experimente zum Rauschlernen zu minimieren, identifizieren Sie die eindeutigen Anweisungen im zweiten Schaltkreis (dem mit den mit gekennzeichneten Kästchen). Bei der Definition der Eindeutigkeit gelten zwei Box-Anweisungen als gleich, wenn beide der folgenden Bedingungen erfüllt sind:\n",
        "\n",
        "* Ihr Inhalt ist identisch, bis hin zu Einzelqubit-Gattern.\n",
        "* Ihre `Twirl` Anmerkung ist identisch (alle anderen Anmerkungen werden ignoriert).\n",
        "\n",
        "Daraus ergeben sich drei spezifische Anweisungen, nämlich die Boxen für ungerade und gerade Werte sowie die Box für die abschließende Messung.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 15,
      "id": "2f8b325a-ffa4-447a-bf32-8b26b7404b0a",
      "metadata": {},
      "outputs": [],
      "source": [
        "from samplomatic.utils import find_unique_box_instructions\n",
        "\n",
        "unique_box_instructions = find_unique_box_instructions(\n",
        "    mirror_circuit_pec.data\n",
        ")\n",
        "assert len(unique_box_instructions) == 3"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "7d496c90-fb07-49e6-a233-451ad4306102",
      "metadata": {},
      "source": [
        "`NoiseLearnerV3`Initialisieren Sie ein Modell, wählen Sie die Lernparameter durch Einstellen der entsprechenden Optionen aus und führen Sie einen Lernvorgang für Rauschdaten durch.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 16,
      "id": "d69204bb-4beb-4b31-b9dd-e8923889685e",
      "metadata": {},
      "outputs": [],
      "source": [
        "from qiskit_ibm_runtime.noise_learner_v3 import NoiseLearnerV3\n",
        "\n",
        "learner = NoiseLearnerV3(backend)\n",
        "\n",
        "learner.options.shots_per_randomization = 128\n",
        "learner.options.num_randomizations = 32\n",
        "learner.options.layer_pair_depths = [0, 1, 2, 4, 16, 32]\n",
        "\n",
        "learner_job = learner.run(unique_box_instructions)\n",
        "\n",
        "learner_job.job_id()\n",
        "learner_result = learner_job.result()"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "efe80acb-f12d-4051-84ed-d61a5a93ca23",
      "metadata": {},
      "source": [
        "Konvertieren `result` Sie das Objekt mithilfe der `result.to_dict` Methode in das vom Samplex benötigte Format.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 17,
      "id": "fd63ad99-01ad-492b-9232-91f2377f97f6",
      "metadata": {},
      "outputs": [],
      "source": [
        "noise_maps = learner_result.to_dict(\n",
        "    instructions=unique_box_instructions, require_refs=False\n",
        ")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "89dd2022-db07-46f6-8737-644aa070dcdb",
      "metadata": {},
      "source": [
        "<span id=\"execute-the-circuits\" />\n",
        "\n",
        "### Führen Sie die Zirkeltrainings durch\n",
        "\n",
        "`Executor` führt `QuantumProgram` Objekte aus. Jedes `QuantumProgram` kann mehrere *Elemente* enthalten, die dem Programm angehängt werden. Jeder Eintrag stellt eine Aufgabe dar, die das Programm ausführen soll.\n",
        "\n",
        "Starte ein leeres Programm, das für jede Konfiguration jedes Elements Aufnahmen anfordert `1000` .\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 18,
      "id": "b48b038e-6e7d-4a6a-8f9a-df1389b644fa",
      "metadata": {},
      "outputs": [],
      "source": [
        "from qiskit_ibm_runtime.quantum_program import QuantumProgram\n",
        "\n",
        "# Initialize an empty QuantumProgram\n",
        "program = QuantumProgram(shots=1000)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "845a9fdb-6837-4bda-925c-8795613bb708",
      "metadata": {},
      "source": [
        "Erstelle als Nächstes die Schaltungsvorlage und den Samplex für `mirror_circuit_twirl` und füge sie dem Programm hinzu. Fordere `900` außerdem Zufallsauswahlen aus dem Samplex an. Das bedeutet, dass der Samplex Parametersätze generiert `900` und jeder Satz Mal (die Anzahl der Durchläufe) in der QPU ausgeführt `1000` wird.\n",
        "\n",
        "Dies ist die erste Aufgabe des Programms (Ergebnis 0).\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 19,
      "id": "38942fab-f68d-44ed-b613-362b38a1ca02",
      "metadata": {},
      "outputs": [],
      "source": [
        "template_twirl, samplex_twirl = build(mirror_circuit_twirl)\n",
        "\n",
        "program.append_samplex_item(\n",
        "    template_twirl,\n",
        "    samplex=samplex_twirl,\n",
        "    samplex_arguments={\"parameter_values\": parameter_values},\n",
        "    shape=(900,),\n",
        ")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "a30d1536-5339-4f19-b351-1c26891a4817",
      "metadata": {},
      "source": [
        "`mirror_circuit_pec`Füge ebenfalls die für erstellte Schaltungsvorlage und den Samplex hinzu und fordere `900` dabei Randomisierungen an.  Dies ist die zweite Aufgabe des Programms (Ergebnis 1).\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 20,
      "id": "16bbb410-b0b7-4011-b4d0-62ffbad30f41",
      "metadata": {},
      "outputs": [],
      "source": [
        "template_pec, samplex_pec = build(mirror_circuit_pec)\n",
        "\n",
        "program.append_samplex_item(\n",
        "    template_pec,\n",
        "    samplex=samplex_pec,\n",
        "    samplex_arguments={\n",
        "        \"parameter_values\": parameter_values,\n",
        "        \"pauli_lindblad_maps\": noise_maps,\n",
        "        \"noise_scales\": {\n",
        "            ref: -1.0 for ref in noise_maps\n",
        "        },  # Set the scales to -1 for PEC\n",
        "    },\n",
        "    shape=(900,),\n",
        ")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "abf9d679-0262-4447-b889-9b06ad3cd77d",
      "metadata": {},
      "source": [
        "Einen Auftrag importieren `Executor` und übermitteln.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 21,
      "id": "6231e441-87f4-480a-886a-5fdd83631e60",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "Twirl result keys:\n",
            " ['meas', 'measurement_flips.meas']\n",
            "\n",
            "Shape of results: (900, 1000, 10)\n",
            "PEC result keys:\n",
            " ['meas', 'measurement_flips.meas', 'pauli_signs']\n",
            "\n",
            "Shape of results: (900, 1000, 10)\n"
          ]
        }
      ],
      "source": [
        "from qiskit_ibm_runtime.executor import Executor\n",
        "\n",
        "executor = Executor(backend)\n",
        "executor_job = executor.run(program)\n",
        "\n",
        "executor_job.job_id()\n",
        "\n",
        "executor_results = executor_job.result()\n",
        "executor_results\n",
        "\n",
        "twirl_result = executor_results[0]\n",
        "\n",
        "print(f\"Twirl result keys:\\n {list(twirl_result.keys())}\\n\")\n",
        "print(f\"Shape of results: {twirl_result['meas'].shape}\")\n",
        "\n",
        "pec_result = executor_results[1]\n",
        "\n",
        "print(f\"PEC result keys:\\n {list(pec_result.keys())}\\n\")\n",
        "print(f\"Shape of results: {pec_result['meas'].shape}\")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "021b944c-5119-4554-b4e9-2af1cfc906d8",
      "metadata": {},
      "source": [
        "<span id=\"analyze-results\" />\n",
        "\n",
        "### Ergebnisse analysieren\n",
        "\n",
        "Schließlich werden die Ergebnisse nachbearbeitet, um die Erwartungswerte der auf jedes der zehn aktiven Qubits wirkenden Pauli-Z-Operatoren für einzelne Qubits zu schätzen (Erwartungswert: `1.0`).\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 22,
      "id": "a24c1dd9-7f29-40b0-87ad-25c2a03e0431",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "Qubit 0 -> 0.71\n",
            "Qubit 1 -> 0.72\n",
            "Qubit 2 -> 0.7\n",
            "Qubit 3 -> 0.68\n",
            "Qubit 4 -> 0.65\n",
            "Qubit 5 -> 0.64\n",
            "Qubit 6 -> 0.62\n",
            "Qubit 7 -> 0.66\n",
            "Qubit 8 -> 0.69\n",
            "Qubit 9 -> 0.75\n"
          ]
        }
      ],
      "source": [
        "# Undo measurement twirling\n",
        "twirl_result_unflipped = (\n",
        "    twirl_result[\"meas\"] ^ twirl_result[\"measurement_flips.meas\"]\n",
        ")\n",
        "\n",
        "# Calculate the expectation values of single-qubit Z operators\n",
        "exp_vals = 1 - 2 * twirl_result_unflipped.mean(axis=1).mean(axis=0)\n",
        "\n",
        "for qubit, val in enumerate(exp_vals):\n",
        "    print(f\"Qubit {qubit} -> {np.round(val, 2)}\")"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 23,
      "id": "8aa25d47-c4fd-4b20-a36f-fa69d7bd0971",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "Qubit 0 -> 0.98\n",
            "Qubit 1 -> 1.0\n",
            "Qubit 2 -> 0.99\n",
            "Qubit 3 -> 0.97\n",
            "Qubit 4 -> 0.97\n",
            "Qubit 5 -> 0.97\n",
            "Qubit 6 -> 0.96\n",
            "Qubit 7 -> 0.97\n",
            "Qubit 8 -> 0.97\n",
            "Qubit 9 -> 0.98\n"
          ]
        }
      ],
      "source": [
        "# Undo measurement twirling\n",
        "pec_result_unflipped = (\n",
        "    pec_result[\"meas\"] ^ pec_result[\"measurement_flips.meas\"]\n",
        ")\n",
        "\n",
        "# Calculate the signs for PEC mitigation\n",
        "signs = np.prod((-1) ** pec_result[\"pauli_signs\"], axis=-1)\n",
        "signs = signs.reshape((signs.shape[0], 1))\n",
        "\n",
        "# Calculate the expectation values of single-qubit Z operators as required by\n",
        "# PEC mitigation\n",
        "exp_vals = 1 - (2 * pec_result_unflipped.mean(axis=1) * signs).mean(axis=0)\n",
        "\n",
        "for qubit, val in enumerate(exp_vals):\n",
        "    print(f\"Qubit {qubit} -> {np.round(val, 2)}\")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "cf25d17a-5e90-4e24-a3bf-c86f5bc3444b",
      "metadata": {},
      "source": [
        "<span id=\"next-steps\" />\n",
        "\n",
        "## Nächste Schritte\n",
        "\n",
        "<Admonition type=\"tip\" title=\"Empfehlungen\">\n",
        "  * Sehen Sie sich die Übersicht [über die Sendungen](/docs/guides/primitive-input-output#broadcasting) an.\n",
        "  * Erfahren Sie, wie Sie [die Executor-Optionen](/docs/guides/executor-options) nutzen können.\n",
        "  * [Das Modell der](/docs/guides/directed-execution-model) gerichteten Ausführung verstehen.\n",
        "  * Lesen Sie die [Samplomatic-Dokumentation](/docs/addons/samplomatic/) durch.\n",
        "  * Erfahren Sie im Tutorial „[Probabilistische Fehlerkorrektur mit schattierten Lichtkegeln](https://qiskit.github.io/qiskit-addon-slc/tutorials/01_getting_started.html) “, wie Sie verschiedene Techniken zur Fehlerminderung kombinieren können, wenn Sie das Modell der gerichteten Ausführung verwenden.\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
}