{
  "cells": [
    {
      "cell_type": "markdown",
      "id": "552b1077",
      "metadata": {},
      "source": [
        "---\n",
        "title: \"Führen Sie Ihren ersten Schaltkreis auf Hardware aus\"\n",
        "description: \"Beginnen Sie mit Qiskit und der Hardware „ IBM Quantum “ in diesem Hello World-Beispiel\"\n",
        "---\n",
        "\n",
        "<span id=\"run-your-first-circuit-on-hardware\" />\n",
        "\n",
        "# Führen Sie Ihren ersten Schaltkreis auf Hardware aus\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "7cc19a86-a234-4220-bb4f-d66d3834e0c3",
      "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": "1a3c196d-545d-417f-b34e-fa422aa9a394",
      "metadata": {},
      "source": [
        "Dieses Beispiel besteht aus zwei Teilen. Zunächst erstellen Sie ein einfaches „Hello World“-Quantenprogramm und führen es auf einer Quantenprozessoreinheit (QPU) aus.  Da die tatsächliche Quantenforschung wesentlich robustere Programme erfordert, werden Sie im zweiten Abschnitt ( [Skalierung auf eine große Anzahl von Qubits](#scale-to-large-numbers-of-qubits) ) das einfache Programm auf ein nutzbares Niveau skalieren.\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "7b65f7e0",
      "metadata": {},
      "source": [
        "<span id=\"install-and-authenticate\" />\n",
        "\n",
        "## Installieren und authentifizieren\n",
        "\n",
        "1. Wenn Sie Qiskit noch nicht installiert haben, finden Sie Anweisungen dazu im [Schnellstart](/docs/guides/quick-start) -Handbuch.\n",
        "\n",
        "   * Installieren Sie den „ IBM Quantum “-Compute-Client, um Jobs auf Quantenhardware auszuführen:\n",
        "\n",
        "     ```bash\n",
        "     pip install qiskit-ibm-runtime\n",
        "     ```\n",
        "\n",
        "   * Richten Sie eine Umgebung ein, um Jupyter-Notebooks lokal auszuführen:\n",
        "\n",
        "     ```bash\n",
        "     pip install jupyter\n",
        "     ```\n",
        "\n",
        "2. Richten Sie Ihre Authentifizierung für den Zugriff auf Quantenhardware über den kostenlosen [Open Plan](/docs/guides/plans-overview#open-plan) ein.\n",
        "\n",
        "   (Wenn Sie eine E-Mail-Einladung zum Beitritt zu einem Konto erhalten haben, befolgen Sie stattdessen die [Schritte für eingeladene Benutzer](/docs/guides/cloud-setup-invited).)\n",
        "\n",
        "   * Gehen Sie zu, [IBM Quantum Platform](/) um sich anzumelden oder ein Konto zu erstellen.\n",
        "     <Admonition type=\"note\" title=\"Wichtig\">\n",
        "       Wenn Sie die Verbindung über einen Proxy-Server herstellen, müssen Sie v0.44.0`qiskit-ibm-runtime` oder eine neuere Version verwenden.\n",
        "     </Admonition>\n",
        "\n",
        "   * Generieren Sie Ihren API-Schlüssel (auch *API-Token* genannt) im [Dashboard](/) und kopieren Sie ihn an einen sicheren Ort.\n",
        "\n",
        "   * Gehen Sie zur Seite [„Instanzen“](/instances) und suchen Sie die Instanz, die Sie verwenden möchten. Bewegen Sie den Mauszeiger über die CRN und klicken Sie, um sie zu kopieren.\n",
        "\n",
        "   * Speichern Sie Ihre Anmeldedaten lokal mit diesem Code:\n",
        "\n",
        "     ```python\n",
        "     from qiskit_ibm_runtime import QiskitRuntimeService\n",
        "\n",
        "     QiskitRuntimeService.save_account(\n",
        "         # For `token`, use the 44-character API_KEY you created\n",
        "         # and saved from the IBM Quantum Platform Home dashboard\n",
        "         token=\"<your-api-key>\",\n",
        "         instance=\"<CRN>\", # Optional\n",
        "     )\n",
        "     ```\n",
        "\n",
        "3. Jetzt können Sie diesen Code „ Python “ jederzeit verwenden, wenn Sie sich beim Compute-Service unter IBM Quantum authentifizieren möchten:\n",
        "   ```python\n",
        "   from qiskit_ibm_runtime import QiskitRuntimeService\n",
        "\n",
        "   # Run every time you need the service\n",
        "   service = QiskitRuntimeService()\n",
        "   ```\n",
        "\n",
        "<Admonition type=\"info\" title=\"Sie verwenden keine vertrauenswürdige Python Umgebung?\">\n",
        "  Wenn Sie einen öffentlichen Computer oder eine andere ungesicherte Umgebung verwenden, befolgen Sie stattdessen die [Anweisungen zur manuellen Authentifizierung,](/docs/guides/cloud-setup-untrusted) um Ihre Anmeldedaten zu schützen.\n",
        "</Admonition>\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "80471a0a",
      "metadata": {},
      "source": [
        "<span id=\"create-and-run-a-simple-quantum-program\" />\n",
        "\n",
        "## Erstellen und Ausführen eines einfachen Quantenprogramms\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "85fe979e",
      "metadata": {
        "raw_mimetype": "text/restructuredtext"
      },
      "source": [
        "Die vier Schritte zum Schreiben eines Quantenprogramms mit Qiskit-Mustern sind:\n",
        "\n",
        "1. Das Problem in ein quantenbasiertes Format übertragen.\n",
        "\n",
        "2. Optimieren Sie die Schaltkreise und Operatoren.\n",
        "\n",
        "3. Ausführen mit einer Quantenprimitivfunktion.\n",
        "\n",
        "4. Analysieren Sie die Ergebnisse.\n",
        "\n",
        "<span id=\"step-1-map-the-problem-to-a-quantum-native-format\" />\n",
        "\n",
        "### Schritt 1. Das Problem in ein quantennatives Format abbilden\n",
        "\n",
        "In einem Quantenprogramm sind *Quantenschaltungen* das native Format, in dem Quantenanweisungen dargestellt werden, und *Operatoren* stellen die zu messenden Observablen dar. Beim Erstellen einer Schaltung erstellen Sie in der Regel ein neues [`QuantumCircuit`](/docs/api/qiskit/qiskit.circuit.QuantumCircuit#quantumcircuit-class) Objekt und fügen dann nacheinander Anweisungen hinzu.\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "21f7a26c",
      "metadata": {},
      "source": [
        "Die folgende Codezelle erstellt einen Schaltkreis\\*,\\* der einen Bell-Zustand erzeugt, bei dem zwei Qubits vollständig miteinander verschränkt sind.\n",
        "\n",
        "<Admonition type=\"note\" title=\"Hinweis: Bit-Reihenfolge\">\n",
        "  Das Qiskit SDK verwendet die LSb 0-Bit-Nummerierung, wobei die $n^{th}$ Ziffer den Wert $1 \\ll n$ oder hat $2^n$. Weitere Informationen finden Sie [unter](/docs/guides/bit-ordering) „Bit-Reihenfolge” im Qiskit SDK Abschnitt.\n",
        "</Admonition>\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 2,
      "id": "930ca3b6",
      "metadata": {
        "tags": []
      },
      "outputs": [
        {
          "data": {
            "text/plain": [
              "<Image src=\"/docs/images/guides/hello-world/extracted-outputs/930ca3b6-0.svg\" alt=\"Output of the previous code cell\" />"
            ]
          },
          "execution_count": 2,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "from qiskit import QuantumCircuit\n",
        "from qiskit.quantum_info import SparsePauliOp\n",
        "from qiskit.transpiler import generate_preset_pass_manager\n",
        "from qiskit_ibm_runtime import QiskitRuntimeService\n",
        "from matplotlib import pyplot as plt\n",
        "\n",
        "# Legacy server-side primitive before qiskit-ibm-runtime 0.50.0\n",
        "# from qiskit_ibm_runtime import EstimatorOptions\n",
        "# from qiskit_ibm_runtime import Estimator\n",
        "\n",
        "# Client-side primitive introduced in qiskit-ibm-runtime 0.50.0\n",
        "from qiskit_ibm_runtime.options_models import EstimatorOptions\n",
        "from qiskit_ibm_runtime.executor_estimator import Estimator\n",
        "\n",
        "# Uncomment the next line if you want to use a simulator:\n",
        "# from qiskit_ibm_runtime.fake_provider import FakeBelemV2\n",
        "\n",
        "\n",
        "# Create a new circuit with two qubits\n",
        "qc = QuantumCircuit(2)\n",
        "\n",
        "# Add a Hadamard gate to qubit 0\n",
        "qc.h(0)\n",
        "\n",
        "# Perform a controlled-X gate on qubit 1, controlled by qubit 0\n",
        "qc.cx(0, 1)\n",
        "\n",
        "# Return a drawing of the circuit using MatPlotLib (\"mpl\").\n",
        "# These guides are written by using Jupyter notebooks, which\n",
        "# display the output of the last line of each cell.\n",
        "# If you're running this in a script, use `print(qc.draw())` to\n",
        "# print a text drawing.\n",
        "qc.draw(\"mpl\")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "0c957de9",
      "metadata": {
        "raw_mimetype": "text/restructuredtext"
      },
      "source": [
        "Siehe [`QuantumCircuit`](/docs/api/qiskit/qiskit.circuit.QuantumCircuit#quantumcircuit-class) in der Dokumentation für alle verfügbaren Operationen.\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "f3ef4248-7938-44c1-85f1-edc997f0edcd",
      "metadata": {},
      "source": [
        "Bei der Erstellung von Quantenschaltungen müssen Sie auch berücksichtigen, welche Art von Daten nach der Ausführung zurückgegeben werden sollen. Qiskit bietet zwei Möglichkeiten, Daten zurückzugeben: Sie können entweder Stichprobenausgaben für eine von Ihnen zur Messung ausgewählte Gruppe von Qubits abrufen oder den Erwartungswert einer Observablen ermitteln. Bereiten Sie Ihre Arbeitsumgebung so vor, dass Sie Ihre Schaltung auf eine der beiden folgenden Arten mithilfe von Primitiven messen können (ausführlich erläutert in [Schritt 3](#step-3-execute-using-the-quantum-primitives) ).\n",
        "\n",
        "Dieses Beispiel misst Erwartungswerte mithilfe des `qiskit.quantum_info` Submoduls, das durch Operatoren (mathematische Objekte, die eine Aktion oder einen Prozess darstellen, der einen Quantenzustand verändert) spezifiziert wird. Die folgende Codezelle erstellt sechs Zwei-Qubit-Pauli-Operatoren: `IZ`, `IX`, `ZI` `XI`, `ZZ`, und `XX`.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 3,
      "id": "c57b261c-b757-4432-beab-61b526c98a41",
      "metadata": {
        "tags": []
      },
      "outputs": [],
      "source": [
        "# Set up six different observables.\n",
        "\n",
        "observables_labels = [\"IZ\", \"IX\", \"ZI\", \"XI\", \"ZZ\", \"XX\"]\n",
        "observables = [SparsePauliOp(label) for label in observables_labels]"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "47150779",
      "metadata": {},
      "source": [
        "<Admonition type=\"note\" title=\"Operator-Notation\">\n",
        "  Hier ist etwas wie der `ZZ` Operator eine Kurzform für das Tensorprodukt $Z\\otimes Z$, was bedeutet, dass Z auf Qubit 1 und Z auf Qubit 0 zusammen gemessen werden und Informationen über die Korrelation zwischen Qubit 1 und Qubit 0 gewonnen werden. Erwartungswerte wie dieser werden in der Regel auch als geschrieben $\\langle Z_1 Z_0 \\rangle$.\n",
        "\n",
        "  Wenn der Zustand verschränkt ist, sollte die $\\langle Z_1 Z_0 \\rangle$ Messung von sich von der Messung von $\\langle I_1 \\otimes Z_0 \\rangle \\langle Z_1 \\otimes I_0 \\rangle$ unterscheiden. Für den spezifischen verschränkten Zustand, der durch unsere oben beschriebene Schaltung erzeugt wird, sollte die $\\langle Z_1 Z_0 \\rangle$ Messung von 1 und die Messung von Null ergeben $\\langle I_1 \\otimes Z_0 \\rangle \\langle Z_1 \\otimes I_0 \\rangle$.\n",
        "</Admonition>\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "83bf9151-3bc9-40d2-8615-31570238b08e",
      "metadata": {},
      "source": [
        "<span id=\"optimize\" />\n",
        "\n",
        "<span id=\"step-2-optimize-the-circuits-and-operators\" />\n",
        "\n",
        "### Schritt 2. Optimieren Sie die Schaltkreise und Operatoren\n",
        "\n",
        "Bei der Ausführung von Schaltkreisen auf einem Gerät ist es wichtig, den Befehlssatz des Schaltkreises zu optimieren und die Gesamttiefe (grob gesagt die Anzahl der Befehle) des Schaltkreises zu minimieren. Dadurch werden Fehler und Störgeräusche reduziert, sodass Sie die bestmöglichen Ergebnisse erzielen. Darüber hinaus müssen die Befehle der Schaltung mit [der Befehlssatzarchitektur (ISA)](/docs/guides/transpile#instruction-set-architecture) eines Backend-Geräts übereinstimmen und die Basisgatter und die Qubit-Konnektivität des Geräts berücksichtigen.\n",
        "\n",
        "Der folgende Code instanziiert ein reales Gerät, an das ein Auftrag gesendet werden soll, und transformiert die Schaltung und die Beobachtungsgrößen so, dass sie mit der ISA dieses Backends übereinstimmen. Es ist erforderlich, dass Sie [Ihre Anmeldedaten](/docs/guides/cloud-setup) bereits gespeichert haben\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 4,
      "id": "9a901271",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "<Image src=\"/docs/images/guides/hello-world/extracted-outputs/9a901271-0.svg\" alt=\"Output of the previous code cell\" />"
            ]
          },
          "execution_count": 4,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "service = QiskitRuntimeService()\n",
        "\n",
        "backend = service.least_busy(simulator=False, operational=True)\n",
        "\n",
        "# Convert to an ISA circuit and layout-mapped observables.\n",
        "pm = generate_preset_pass_manager(backend=backend, optimization_level=1)\n",
        "isa_circuit = pm.run(qc)\n",
        "\n",
        "isa_circuit.draw(\"mpl\", idle_wires=False)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "9acac1d4",
      "metadata": {},
      "source": [
        "<span id=\"step-3-execute-using-the-quantum-primitives\" />\n",
        "\n",
        "### Schritt 3. Ausführung unter Verwendung der Quantenprimitiven\n",
        "\n",
        "Quantencomputer können zufällige Ergebnisse liefern, daher sammelt man in der Regel eine Stichprobe der Ausgabewerte, indem man den Schaltkreis mehrfach durchläuft. Sie können den Wert der Observable mithilfe der `Estimator` Klasse schätzen. `Estimator` ist eine von zwei [Primitiven](/docs/guides/get-started-with-estimator); die andere ist `Sampler`, mit der Daten von einem Quantencomputer abgerufen werden können.  Diese Objekte verfügen über eine `run()` Methode, die die Auswahl von Schaltkreisen, Observablen und Parametern (sofern zutreffend) mithilfe eines [primitiven einheitlichen Blocks ( PUB )](/docs/guides/get-started-with-sampler) durchführt.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 5,
      "id": "62c4ca44",
      "metadata": {
        "tags": []
      },
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            ">>> Job ID: dab7lm9l216s739p6q10\n"
          ]
        }
      ],
      "source": [
        "# Construct the Estimator instance.\n",
        "\n",
        "estimator = Estimator(mode=backend)\n",
        "estimator.options.resilience_level = 1\n",
        "estimator.options.default_shots = 5000\n",
        "\n",
        "mapped_observables = [\n",
        "    observable.apply_layout(isa_circuit.layout) for observable in observables\n",
        "]\n",
        "\n",
        "# One pub, with one circuit to run against five different observables.\n",
        "job = estimator.run([(isa_circuit, mapped_observables)])\n",
        "\n",
        "# Use the job ID to retrieve your job data later\n",
        "print(f\">>> Job ID: {job.job_id()}\")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "47479e76",
      "metadata": {},
      "source": [
        "Nachdem ein Auftrag übermittelt wurde, können Sie entweder warten, bis der Auftrag in Ihrer aktuellen Python-Instanz abgeschlossen ist, oder die Daten zu einem späteren Zeitpunkt mit dem `job_id` abrufen.  (Weitere Informationen finden Sie im [Abschnitt zum Abrufen von Aufträgen](/docs/guides/monitor-job#retrieve-job-results-at-a-later-time).)\n",
        "\n",
        "Nachdem der Job abgeschlossen ist, überprüfen Sie dessen Ausgabe über das Attribut `result()` des Jobs.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 6,
      "id": "792d2f01",
      "metadata": {},
      "outputs": [],
      "source": [
        "# This is the result of the entire submission.  You submitted one Pub,\n",
        "# so this contains one inner result (and some metadata of its own).\n",
        "job_result = job.result()\n",
        "\n",
        "# This is the result from our single pub, which had six observables,\n",
        "# so contains information on all six.\n",
        "pub_result = job.result()[0]"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "48317a25",
      "metadata": {},
      "source": [
        "<Admonition type=\"note\" title=\"Alternative: Führen Sie das Beispiel mit einem Simulator aus\">\n",
        "  Wenn Sie Ihr Quantenprogramm auf einem realen Gerät ausführen, muss Ihre Arbeitslast zunächst in einer Warteschlange warten, bevor sie ausgeführt wird. Um Zeit zu sparen, können Sie stattdessen den folgenden Code verwenden, um diese kleine Arbeitslast im [`fake_provider`](/docs/api/qiskit-ibm-runtime/fake-provider) lokalen `qiskit-ibm-runtime` Testmodus auszuführen. Beachten Sie, dass dies nur bei einer kleinen Schaltung möglich ist. Wenn Sie im nächsten Abschnitt die Skalierung vornehmen, müssen Sie ein echtes Gerät verwenden.\n",
        "\n",
        "  ```python\n",
        "\n",
        "  # Use the following code instead if you want to run on a simulator:\n",
        "\n",
        "  from qiskit_ibm_runtime.fake_provider import FakeBelemV2\n",
        "  backend = FakeBelemV2()\n",
        "  estimator = Estimator(backend)\n",
        "\n",
        "  # Convert to an ISA circuit and layout-mapped observables.\n",
        "\n",
        "  pm = generate_preset_pass_manager(backend=backend, optimization_level=1)\n",
        "  isa_circuit = pm.run(qc)\n",
        "  mapped_observables = [\n",
        "      observable.apply_layout(isa_circuit.layout) for observable in observables\n",
        "  ]\n",
        "\n",
        "  job = estimator.run([(isa_circuit, mapped_observables)])\n",
        "  result = job.result()\n",
        "\n",
        "  # This is the result of the entire submission. You submitted one Pub,\n",
        "  # so this contains one inner result (and some metadata of its own).\n",
        "\n",
        "  job_result = job.result()\n",
        "\n",
        "  # This is the result from our single pub, which had five observables,\n",
        "  # so contains information on all five.\n",
        "\n",
        "  pub_result = job.result()[0]\n",
        "  ```\n",
        "</Admonition>\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "d200d1f8",
      "metadata": {},
      "source": [
        "<span id=\"step-4-analyze-the-results\" />\n",
        "\n",
        "### Schritt 4. Analysieren Sie die Ergebnisse\n",
        "\n",
        "Der Analyseschritt ist in der Regel der Schritt, in dem Sie Ihre Ergebnisse nachbearbeiten können, beispielsweise durch Messfehlerkorrektur oder Zero Noise Extrapolation (ZNE). Sie können diese Ergebnisse zur weiteren Analyse in einen anderen Workflow einspeisen oder eine Darstellung der Schlüsselwerte und Daten erstellen. Im Allgemeinen ist dieser Schritt spezifisch für Ihr Problem.  Zeichnen Sie für dieses Beispiel jeden der Erwartungswerte auf, die für unsere Schaltung gemessen wurden.\n",
        "\n",
        "Die Erwartungswerte und Standardabweichungen für die von Ihnen in Estimator angegebenen Observablen können über die Attribute und `PubResult.data.stds` des `PubResult.data.evs` Job-Ergebnisses abgerufen werden. Um die Ergebnisse von Sampler abzurufen, verwenden Sie die `PubResult.data.meas.get_counts()` Funktion, die ein `dict` Array mit Messwerten zurückgibt, wobei die Bitstrings als Schlüssel und die Zählwerte als entsprechende Werte dienen. Weitere Informationen finden Sie in der [Schnell](/docs/guides/get-started-with-sampler) startanleitung für den Sampler.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 8,
      "id": "87143fcc",
      "metadata": {
        "tags": []
      },
      "outputs": [
        {
          "data": {
            "text/plain": [
              "<Image src=\"/docs/images/guides/hello-world/extracted-outputs/87143fcc-0.svg\" alt=\"Output of the previous code cell\" />"
            ]
          },
          "metadata": {},
          "output_type": "display_data"
        }
      ],
      "source": [
        "# Plot the result\n",
        "\n",
        "values = pub_result.data.evs\n",
        "\n",
        "errors = pub_result.data.stds\n",
        "\n",
        "# plotting graph\n",
        "plt.plot(observables_labels, values, \"-o\")\n",
        "plt.xlabel(\"Observables\")\n",
        "plt.ylabel(\"Values\")\n",
        "plt.show()"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "e6a9ba84",
      "metadata": {},
      "source": [
        "Beachten Sie, dass für die Qubits 0 und 1 die unabhängigen Erwartungswerte von X und Z beide 0 sind, während die Korrelationen (`XX` und `ZZ`) 1 sind. Dies ist ein Kennzeichen der Quantenverschränkung.\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "0bc582d8",
      "metadata": {},
      "source": [
        "<span id=\"scale-to-large-numbers-of-qubits\" />\n",
        "\n",
        "## Skalierung auf eine große Anzahl von Qubits\n",
        "\n",
        "Im Bereich des Quantencomputings sind Arbeiten im Versorgungsmaßstab entscheidend für den Fortschritt auf diesem Gebiet. Solche Arbeiten erfordern Berechnungen in viel größerem Umfang, wobei Schaltkreise mit über 100 Qubits und über 1000 Gattern zum Einsatz kommen können. Dieses Beispiel zeigt, wie Sie mit IBM® QPUs Arbeiten im Versorgungsmaßstab durchführen können, indem Sie einen 100-Qubit-GHZ-Zustand erstellen und analysieren.  Es verwendet den Qiskit-Patterns-Workflow und misst am Ende den Erwartungswert $\\langle Z_0 Z_i \\rangle $ für jedes Qubit.\n",
        "\n",
        "<span id=\"step-1-map-the-problem\" />\n",
        "\n",
        "### Schritt 1. Das Problem abbilden\n",
        "\n",
        "Schreiben Sie eine Funktion, die einen `QuantumCircuit` zurückgibt, der einen $n$ -Qubit-GHZ-Zustand (im Wesentlichen einen erweiterten Bell-Zustand) vorbereitet, und verwenden Sie diese Funktion dann, um einen 100-Qubit-GHZ-Zustand vorzubereiten und die zu messenden Observablen zu sammeln.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 10,
      "id": "2ac02692",
      "metadata": {},
      "outputs": [],
      "source": [
        "def get_qc_for_n_qubit_GHZ_state(n: int) -> QuantumCircuit:\n",
        "    \"\"\"This function will create a qiskit.QuantumCircuit (qc)\n",
        "        for an n-qubit GHZ state.\n",
        "\n",
        "    Args:\n",
        "        n (int): Number of qubits in the n-qubit GHZ state\n",
        "\n",
        "    Returns:\n",
        "        QuantumCircuit: Quantum circuit that generate the n-qubit GHZ state,\n",
        "            assuming all qubits start in the 0 state\n",
        "    \"\"\"\n",
        "    if isinstance(n, int) and n >= 2:\n",
        "        qc = QuantumCircuit(n)\n",
        "        qc.h(0)\n",
        "        for i in range(n - 1):\n",
        "            qc.cx(i, i + 1)\n",
        "    else:\n",
        "        raise Exception(\"n is not a valid input\")\n",
        "    return qc\n",
        "\n",
        "\n",
        "# Create a new circuit with 100 qubits in the GHZ state\n",
        "n = 100\n",
        "qc = get_qc_for_n_qubit_GHZ_state(n)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "5b3d0d74",
      "metadata": {},
      "source": [
        "Als Nächstes ordnen Sie die relevanten Operatoren zu. In diesem Beispiel werden die `ZZ` Operatoren zwischen Qubits verwendet, um das Verhalten zu untersuchen, wenn sie sich weiter voneinander entfernen.  Zunehmend ungenaue (verfälschte) Erwartungswerte zwischen weit entfernten Qubits würden das Ausmaß des vorhandenen Rauschens offenbaren.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 11,
      "id": "863a4ec9",
      "metadata": {},
      "outputs": [],
      "source": [
        "# ZZII...II, ZIZI...II, ... , ZIII...IZ\n",
        "operator_strings = [\n",
        "    \"Z\" + \"I\" * i + \"Z\" + \"I\" * (n - 2 - i) for i in range(n - 1)\n",
        "]\n",
        "\n",
        "operators = [SparsePauliOp(operator) for operator in operator_strings]"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "a0b462ce",
      "metadata": {},
      "source": [
        "<span id=\"step-2-optimize-the-problem-for-execution-on-quantum-hardware\" />\n",
        "\n",
        "### Schritt 2. Optimieren Sie das Problem für die Ausführung auf Quantenhardware\n",
        "\n",
        "Der folgende Code transformiert die Schaltung und die Observablen, damit sie mit der ISA des Backends übereinstimmen. Es ist erforderlich, dass Sie [Ihre Anmeldedaten](/docs/guides/cloud-setup) bereits gespeichert haben\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 12,
      "id": "428f05e7",
      "metadata": {},
      "outputs": [],
      "source": [
        "service = QiskitRuntimeService()\n",
        "\n",
        "backend = service.least_busy(\n",
        "    simulator=False, operational=True, min_num_qubits=100\n",
        ")\n",
        "pm = generate_preset_pass_manager(optimization_level=1, backend=backend)\n",
        "\n",
        "isa_circuit = pm.run(qc)\n",
        "isa_operators_list = [op.apply_layout(isa_circuit.layout) for op in operators]"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "2d2b5065",
      "metadata": {},
      "source": [
        "<span id=\"step-3-execute-on-hardware\" />\n",
        "\n",
        "### Schritt 3. Auf Hardware ausführen\n",
        "\n",
        "Übermitteln Sie den Auftrag und aktivieren Sie die Fehlerunterdrückung mithilfe einer Technik zur Fehlerreduzierung, die als [„dynamische Entkopplung“](/docs/api/qiskit-ibm-runtime/options-models-dynamical-decoupling-options) bezeichnet wird. Der Resilienzgrad gibt an, in welchem Umfang eine Fehlertoleranz aufgebaut werden soll. Höhere Werte führen zu genaueren Ergebnissen, allerdings auf Kosten längerer Verarbeitungszeiten.  Weitere Erläuterungen zu den im folgenden Code festgelegten Optionen finden Sie unter „[Techniken zur Fehlerminderung und -unterdrückung](/docs/guides/error-mitigation-and-suppression-techniques) “.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 13,
      "id": "3aaa5025",
      "metadata": {},
      "outputs": [],
      "source": [
        "options = EstimatorOptions()\n",
        "options.resilience_level = 1\n",
        "options.dynamical_decoupling.enable = True\n",
        "options.dynamical_decoupling.sequence_type = \"XY4\"\n",
        "\n",
        "# Create an Estimator object\n",
        "estimator = Estimator(backend, options=options)"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 14,
      "id": "b4c3d3e7-0a0f-4023-8948-1082e225f46c",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "dab84omrrl7c7386h52g\n"
          ]
        }
      ],
      "source": [
        "# Submit the circuit to Estimator\n",
        "job = estimator.run([(isa_circuit, isa_operators_list)])\n",
        "job_id = job.job_id()\n",
        "print(job_id)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "0bc64091",
      "metadata": {},
      "source": [
        "<span id=\"step-4-post-process-results\" />\n",
        "\n",
        "### Schritt 4. Nachbearbeitungsergebnisse\n",
        "\n",
        "Nach Abschluss des Auftrags zeichnen Sie die Ergebnisse auf und stellen Sie fest, dass mit $i$ $\\langle Z_0 Z_i \\rangle$ steigendem abnimmt, obwohl in einer idealen Simulation alle 1 sein $\\langle Z_0 Z_i \\rangle$ sollten.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 15,
      "id": "de91ebd0",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "<Image src=\"/docs/images/guides/hello-world/extracted-outputs/de91ebd0-0.svg\" alt=\"Output of the previous code cell\" />"
            ]
          },
          "metadata": {},
          "output_type": "display_data"
        }
      ],
      "source": [
        "# data\n",
        "data = list(range(1, len(operators) + 1))  # Distance between the Z operators\n",
        "result = job.result()[0]\n",
        "values = result.data.evs  # Expectation value at each Z operator.\n",
        "values = [\n",
        "    v / values[0] for v in values\n",
        "]  # Normalize the expectation values to evaluate how they decay with distance.\n",
        "\n",
        "# plotting graph\n",
        "plt.plot(data, values, marker=\"o\", label=\"100-qubit GHZ state\")\n",
        "plt.xlabel(\"Distance between qubits $i$\")\n",
        "plt.ylabel(r\"$\\langle Z_i Z_0 \\rangle / \\langle Z_1 Z_0 \\rangle $\")\n",
        "plt.legend()\n",
        "plt.show()"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "0afc307c",
      "metadata": {},
      "source": [
        "Die vorherige Grafik zeigt, dass das Signal mit zunehmendem Abstand zwischen den Qubits aufgrund von Rauschen abklingt.\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "e7c24c81",
      "metadata": {},
      "source": [
        "<span id=\"next-steps\" />\n",
        "\n",
        "## Nächste Schritte\n",
        "\n",
        "<Admonition type=\"tip\" title=\"Empfehlungen\">\n",
        "  * Probieren Sie eines dieser Tutorials aus:\n",
        "    * [Grundzustandsenergie-Schätzung der Heisenberg-Kette mit VQE](/docs/tutorials/spin-chain-vqe)\n",
        "    * Optimierungsprobleme mit [QAOA](/docs/tutorials/quantum-approximate-optimization-algorithm) lösen\n",
        "    * [Quantenkernmodelle](/docs/tutorials/quantum-kernel-training) für maschinelle Lernaufgaben trainieren\n",
        "  * Ausführliche Installationsanweisungen finden Sie im Leitfaden „[Install Qiskit](/docs/guides/install-qiskit) “.\n",
        "  * Wenn Sie Qiskit nicht lokal installieren möchten, lesen Sie mehr über die Möglichkeiten, Qiskit in einer [Online-Entwicklungsumgebung](/docs/guides/online-lab-environments) zu verwenden.\n",
        "  * Um mehrere Kontoanmeldedaten zu speichern oder andere Kontooptionen festzulegen, lesen Sie die detaillierten Anweisungen im Leitfaden [zum Speichern Ihrer Anmeldedaten](/docs/guides/save-credentials#save-your-access-credentials).\n",
        "</Admonition>\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "id": "a1b8767d",
      "source": "© IBM Corp., 2017-2026"
    }
  ],
  "metadata": {
    "celltoolbar": "Raw Cell Format",
    "hours": 0.5,
    "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"
    },
    "widgets": {
      "application/vnd.jupyter.widget-state+json": {
        "state": {},
        "version_major": 2,
        "version_minor": 0
      }
    }
  },
  "nbformat": 4,
  "nbformat_minor": 5
}