{
  "cells": [
    {
      "attachments": {},
      "cell_type": "markdown",
      "id": "7dc25056-2c3c-435a-a827-1930f8bb768f",
      "metadata": {
        "gloss": {
          "ansatz": {
            "text": "Combination of a reference operator and a variational form, to describe the search space that we're exploring.",
            "title": "Ansatz"
          },
          "variational": {
            "text": "Layers of parameterized gates that are repeated a certain number of times, and the parameters of the gates are optimized during the algorithm to minimize the cost function.",
            "title": "Variational form"
          }
        }
      },
      "source": [
        "---\n",
        "title: \"Ansätze und Variationsformen\"\n",
        "description: \"In dieser Lektion wird erklärt, was ein Ansatz ist und wie er sich vom Referenzzustand unterscheidet. Es werden Beispiele für Ansätze gegeben.\"\n",
        "---\n",
        "\n",
        "{/* cspell:ignore ZZII IZZI ZIIZ IZIZ IIZZ ansä */}\n",
        "\n",
        "<span id=\"ansaetze-and-variational-forms\" />\n",
        "\n",
        "# Ansätze und Variationsformen\n",
        "\n",
        "Das Herzstück aller Variationsalgorithmen besteht in der Analyse der Unterschiede zwischen den Zuständen, die durch eine geeignete Abbildung (z. B. kontinuierlich, differenzierbar) aus einer Reihe von Parametern oder Variablen miteinander verbunden sind - daher der Name.\n",
        "\n",
        "Zunächst werden wir untersuchen, wie parametrisierte Schaltungen von Hand konstruiert werden können. Wir werden diese Schaltkreise verwenden, um eine <DefinitionTooltip definition=\"Schichten von parametrisierten Gattern, die eine bestimmte Anzahl von Malen wiederholt werden, und die Parameter der Gatter werden während des Algorithmus optimiert, um die Kostenfunktion zu minimieren.\">variationsform</DefinitionTooltip> zu definieren, die eine Sammlung von parametrisierten Zuständen darstellt, die unser Variationsalgorithmus untersuchen kann. Dann konstruieren wir unsere <DefinitionTooltip definition=\"Kombination aus einem Referenzoperator und einer Variationsform zur Beschreibung des Suchraums, den wir erkunden.\">ansatz</DefinitionTooltip>, indem wir diese Variationsform auf unseren Referenzzustand anwenden.\n",
        "\n",
        "Wir werden auch untersuchen, wie man bei der Erkundung dieses Suchraums zwischen Geschwindigkeit und Genauigkeit abwägen kann.\n",
        "\n",
        "![Ein Diagramm, das die wichtigsten Komponenten der Ansatzdiskussion zeigt, einschließlich heuristischer Ansätze und problemspezifischer Ansätze.](https://quantum.cloud.ibm.com/learning/images/courses/variational-algorithm-design/ansaetze-and-variational-forms/ansatz-workflow.svg)\n",
        "\n"
      ]
    },
    {
      "attachments": {},
      "cell_type": "markdown",
      "id": "5ebac8e8-6451-46e5-8a01-099f84296a17",
      "metadata": {},
      "source": [
        "<span id=\"parameterized-quantum-circuits\" />\n",
        "\n",
        "## Parametrisierte Quantenschaltungen\n",
        "\n",
        "Variationsalgorithmen arbeiten, indem sie eine Reihe von Quantenzuständen $|\\psi(\\vec{\\theta})\\rangle$ untersuchen und vergleichen, die von einer endlichen Reihe von $k$ Parametern $\\vec{\\theta} = (\\theta^0, \\ldots, \\theta^{k-1})$ abhängen. Diese Zustände können mithilfe eines parametrisierten Quantenschaltkreises vorbereitet werden, in dem Gatter mit abstimmbaren Parametern definiert sind. Es ist möglich, diese parametrisierte Schaltung zu erstellen, ohne bestimmte Winkel zu binden:\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 1,
      "id": "4c564fab-ed65-4949-b27f-658b0f1ed621",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "<Image src=\"/learning/images/courses/variational-algorithm-design/ansaetze-and-variational-forms/extracted-outputs/4c564fab-ed65-4949-b27f-658b0f1ed621-0.avif\" alt=\"Output of the previous code cell\" />"
            ]
          },
          "execution_count": 1,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "from qiskit.circuit import QuantumCircuit, Parameter\n",
        "\n",
        "theta = Parameter(\"θ\")\n",
        "\n",
        "qc = QuantumCircuit(3)\n",
        "qc.rx(theta, 0)\n",
        "qc.cx(0, 1)\n",
        "qc.x(2)\n",
        "\n",
        "qc.draw(\"mpl\")"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 2,
      "id": "4096d161-2916-472b-8abc-d4a6b78955cf",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "<Image src=\"/learning/images/courses/variational-algorithm-design/ansaetze-and-variational-forms/extracted-outputs/4096d161-2916-472b-8abc-d4a6b78955cf-0.avif\" alt=\"Output of the previous code cell\" />"
            ]
          },
          "metadata": {},
          "output_type": "display_data"
        },
        {
          "data": {
            "text/plain": [
              "<Image src=\"/learning/images/courses/variational-algorithm-design/ansaetze-and-variational-forms/extracted-outputs/4096d161-2916-472b-8abc-d4a6b78955cf-1.avif\" alt=\"Output of the previous code cell\" />"
            ]
          },
          "metadata": {},
          "output_type": "display_data"
        }
      ],
      "source": [
        "from math import pi\n",
        "\n",
        "angle_list = [pi / 3, pi / 2]\n",
        "circuits = [qc.assign_parameters({theta: angle}) for angle in angle_list]\n",
        "\n",
        "for circuit in circuits:\n",
        "    display(circuit.draw(\"mpl\"))"
      ]
    },
    {
      "attachments": {},
      "cell_type": "markdown",
      "id": "f01221c4-f7ee-496a-a664-4b3abc0748c2",
      "metadata": {},
      "source": [
        "<span id=\"variational-form-and-ansatz\" />\n",
        "\n",
        "## Variationsform und Ansatz\n",
        "\n",
        "Um iterativ von einem Referenzzustand $|\\rho\\rangle$ zu einem Zielzustand $|\\psi(\\vec\\theta)\\rangle$ zu optimieren, müssen wir eine Variationsform $U_V(\\vec{\\theta})$ definieren, die eine Sammlung von parametrisierten Zuständen darstellt, die unser Variationsalgorithmus untersuchen soll:\n",
        "\n",
        "$$\n",
        "\\begin{aligned}\n",
        "|0\\rangle \\xrightarrow{U_R} U_R|0\\rangle\n",
        "\n",
        "& = |\\rho\\rangle \\xrightarrow{U_V(\\vec{\\theta})} U_A(\\vec{\\theta})|0\\rangle \\\\[1mm]\n",
        "\n",
        "& = U_V(\\vec{\\theta})U_R|0\\rangle \\\\[1mm]\n",
        "\n",
        "& = U_V(\\vec{\\theta})|\\rho\\rangle \\\\[1mm]\n",
        "\n",
        "& = |\\psi(\\vec{\\theta})\\rangle \\\\[1mm]\n",
        "\n",
        "\\end{aligned}\n",
        "$$\n",
        "\n",
        "Man beachte, dass der parametrisierte Zustand sowohl vom Referenzzustand $|\\rho\\rangle$, der nicht von Parametern abhängt, als auch von der Variationsform $U_V(\\vec{\\theta})$, die immer von Parametern abhängt, abhängt. Wir bezeichnen die Kombination dieser beiden Hälften als Ansatz: $U_A(\\vec\\theta) := U_V(\\vec\\theta)U_R$.\n",
        "\n",
        "Während wir unseren Ansatz konstruieren, um eine Sammlung von parametrisierten Zuständen darzustellen, die unser Variationsalgorithmus untersuchen kann, erkennen wir ein wichtiges Problem: die Dimensionalität. Ein $n$ -Qubit-System (d.h. ein Hilbert-Raum) hat eine große Anzahl von unterschiedlichen Quantenzuständen im Konfigurationsraum. Wir bräuchten eine unüberschaubare Anzahl von Parametern, um sie vollständig zu erforschen. Quantitativ gesehen ist seine Dimensionalität $D = 2^{2n}$. Erschwerend kommt hinzu, dass die Laufzeitkomplexität von Suchalgorithmen und anderen Algorithmen mit dieser Dimensionalität exponentiell zunimmt, ein Phänomen, das in der Literatur häufig als Fluch der Dimensionalität bezeichnet wird.\n",
        "\n",
        "Um diesem Nachteil entgegenzuwirken, ist es üblich, der Variationsform einige vernünftige Beschränkungen aufzuerlegen, so dass nur die wichtigsten Zustände untersucht werden. Die Suche nach einem effizienten verkürzten Ansatz ist ein aktives Forschungsgebiet, aber wir werden uns mit zwei gängigen Designs befassen.\n",
        "\n"
      ]
    },
    {
      "attachments": {},
      "cell_type": "markdown",
      "id": "6d6caf9e-4eb0-4ae1-b9be-6fcfacd23b39",
      "metadata": {},
      "source": [
        "<span id=\"heuristic-ansaetze-and-trade-offs\" />\n",
        "\n",
        "## Heuristische Ansätze und Kompromisse\n",
        "\n",
        "Wenn Sie keine Informationen über Ihr spezielles Problem haben, die helfen können, die Dimensionalität einzuschränken, können Sie eine beliebige Familie von parametrisierten Schaltungen mit weniger als $2^{2n}$ Parametern versuchen. Allerdings gibt es einige Kompromisse zu beachten:\n",
        "\n",
        "* **Geschwindigkeit** : Durch die Verkleinerung des Suchraums kann der Algorithmus schneller laufen.\n",
        "* **Genauigkeit** : Bei einer Verkleinerung des Raums besteht die Gefahr, dass die eigentliche Lösung des Problems ausgeschlossen wird, was zu suboptimalen Lösungen führt.\n",
        "* **Rauschen** : Tiefere Schaltungen werden durch Rauschen beeinträchtigt, daher müssen wir mit der Konnektivität, den Gattern und der Gattertreue unseres Ansatzes experimentieren.\n",
        "\n",
        "Es besteht ein grundlegender Kompromiss zwischen Qualität (oder sogar Lösbarkeit) und Geschwindigkeit: je mehr Parameter, desto wahrscheinlicher ist es, dass Sie ein präzises Ergebnis finden, aber desto länger dauert es, den Algorithmus auszuführen.\n",
        "\n"
      ]
    },
    {
      "attachments": {},
      "cell_type": "markdown",
      "id": "136b5311-f52b-47a0-a7d2-3f1255b0270e",
      "metadata": {},
      "source": [
        "<span id=\"n-local-circuits\" />\n",
        "\n",
        "### N-lokale Schaltungen\n",
        "\n",
        "Eines der am weitesten verbreiteten Beispiele für heuristische Ansaetze sind die [N-lokalen Schaltungen](/docs/api/qiskit/qiskit.circuit.library.NLocal), und zwar aus mehreren Gründen:\n",
        "\n",
        "* **Effiziente Implementierung** : Der N-lokale Ansatz besteht typischerweise aus einfachen, lokalen Gattern, die auf einem Quantencomputer mit einer geringen Anzahl physikalischer Qubits effizient implementiert werden können. Dies erleichtert die Konstruktion und Optimierung von Quantenschaltungen.\n",
        "* **Erfasst wichtige Korrelationen** : Der N-lokale Ansatz kann wichtige Korrelationen zwischen den Qubits in einem Quantensystem erfassen, selbst bei einer geringen Anzahl von Gattern. Der Grund dafür ist, dass die lokalen Gatter auf benachbarte Qubits einwirken und eine Verschränkung zwischen ihnen erzeugen können, was für die Simulation komplexer Quantensysteme wichtig sein kann.\n",
        "\n",
        "Diese Schaltungen bestehen aus Rotations- und Verschränkungsschichten, die abwechselnd ein- oder mehrmals wie folgt wiederholt werden:\n",
        "\n",
        "* Jede Schicht besteht aus Gattern mit einer Größe von höchstens $N$, wobei $N$ kleiner sein muss als die Anzahl der Qubits.\n",
        "* Bei einer Rotationsschicht werden die Gates übereinander gestapelt. Wir können Standard-Rotationsoperationen verwenden, wie z. B [`RX`](/docs/api/qiskit/qiskit.circuit.library.RXGate) oder [`CRZ`](/docs/api/qiskit/qiskit.circuit.library.CRZGate).\n",
        "* Für eine Verschränkungsschicht können wir Gatter wie [`Toffoli` gates](/docs/api/qiskit/qiskit.circuit.library.CCXGate) oder [`CX`](/docs/api/qiskit/qiskit.circuit.library.CXGate) mit einer Verschränkungsstrategie verwenden.\n",
        "* Beide Arten von Ebenen können parametrisiert oder nicht parametrisiert sein, aber mindestens eine von ihnen muss Parameter enthalten. Denn ohne mindestens einen Parameter gäbe es keine Variationen!\n",
        "* Optional kann am Ende der Schaltung eine zusätzliche Rotationsschicht hinzugefügt werden.\n",
        "\n",
        "Erstellen wir zum Beispiel eine Fünf-Qubit-Schaltung [`NLocal`](/docs/api/qiskit/qiskit.circuit.library.NLocal) schaltung mit Rotationsblöcken, die durch [`RX`](/docs/api/qiskit/qiskit.circuit.library.RXGate) und [`CRZ`](/docs/api/qiskit/qiskit.circuit.library.CRZGate) gattern gebildeten Rotationsblöcken, von [`Toffoli` Gattern](/docs/api/qiskit/qiskit.circuit.library.CCXGate) gebildeten Verschränkungsblöcken, die auf die Qubits $[0,1,2]$, $[0,2,3]$, $[4,2,1]$ und $[3,1,0]$ und $2$ Wiederholungen jeder Schicht wirken.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 3,
      "id": "c28d7b53-fbd7-42f5-a619-5a6b0b44e9fc",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "<Image src=\"/learning/images/courses/variational-algorithm-design/ansaetze-and-variational-forms/extracted-outputs/c28d7b53-fbd7-42f5-a619-5a6b0b44e9fc-0.avif\" alt=\"Output of the previous code cell\" />"
            ]
          },
          "execution_count": 3,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "from qiskit.circuit.library import NLocal, CCXGate, CRZGate, RXGate\n",
        "from qiskit.circuit import Parameter\n",
        "\n",
        "theta = Parameter(\"θ\")\n",
        "ansatz = NLocal(\n",
        "    num_qubits=5,\n",
        "    rotation_blocks=[RXGate(theta), CRZGate(theta)],\n",
        "    entanglement_blocks=CCXGate(),\n",
        "    entanglement=[[0, 1, 2], [0, 2, 3], [4, 2, 1], [3, 1, 0]],\n",
        "    reps=2,\n",
        "    insert_barriers=True,\n",
        ")\n",
        "ansatz.decompose().draw(\"mpl\")"
      ]
    },
    {
      "attachments": {},
      "cell_type": "markdown",
      "id": "d293b8cc-1512-4a65-a3f7-94a979d1736b",
      "metadata": {},
      "source": [
        "Im obigen Beispiel ist das größte Gatter das Toffoli-Gatter, das auf drei Qubits wirkt, wodurch die Schaltung $3$ -lokal wird. Die am häufigsten verwendete Art von $N$ -lokalen Schaltungen sind [$2$ -lokale Schaltungen mit Ein-Qubit-Rotationsgattern und](/docs/api/qiskit/qiskit.circuit.library.TwoLocal) $2$ -Qubit-Verschränkungsgattern.\n",
        "\n",
        "Erstellen wir eine $2$ -lokale Schaltung unter Verwendung der Qiskit [`TwoLocal`](/docs/api/qiskit/qiskit.circuit.library.TwoLocal) klasse. Die Syntax ist die gleiche wie die von `NLocal`. Es gibt jedoch einige Unterschiede. Zum Beispiel können die meisten Gates, wie `RX`, `RZ` und `CNOT`, als Strings übergeben werden, ohne dass die Gates importiert oder eine `Parameter` Instanz erstellt werden muss.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 4,
      "id": "c48521ee-db12-449e-af9f-7d8ec0fa7890",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "<Image src=\"/learning/images/courses/variational-algorithm-design/ansaetze-and-variational-forms/extracted-outputs/c48521ee-db12-449e-af9f-7d8ec0fa7890-0.avif\" alt=\"Output of the previous code cell\" />"
            ]
          },
          "execution_count": 4,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "from qiskit.circuit.library import TwoLocal\n",
        "\n",
        "ansatz = TwoLocal(\n",
        "    num_qubits=5,\n",
        "    rotation_blocks=[\"rx\", \"rz\"],\n",
        "    entanglement_blocks=\"cx\",\n",
        "    entanglement=\"linear\",\n",
        "    reps=2,\n",
        "    insert_barriers=True,\n",
        ")\n",
        "ansatz.decompose().draw(\"mpl\")"
      ]
    },
    {
      "attachments": {},
      "cell_type": "markdown",
      "id": "a6e80571-9bb4-4e33-9581-2c48cad1a566",
      "metadata": {},
      "source": [
        "In diesem Fall haben wir die lineare Verschränkungsverteilung verwendet, bei der jedes Qubit mit dem nächsten verschränkt ist. Informationen über andere Strategien finden Sie in der [Dokumentation `TwoLocal` ](/docs/api/qiskit/qiskit.circuit.library.TwoLocal).\n",
        "\n"
      ]
    },
    {
      "attachments": {},
      "cell_type": "markdown",
      "id": "65d39e58-e54b-4ea3-95bf-ee68d9b89832",
      "metadata": {},
      "source": [
        "<span id=\"efficient-su2\" />\n",
        "\n",
        "### Effizienz SU2\n",
        "\n",
        "[`efficient_su2`](/docs/api/qiskit/qiskit.circuit.library.EfficientSU2) ist eine hardware-effiziente Schaltung, die aus Schichten von Ein-Qubit-Operationen besteht, die SU(2) und `CX` Verschränkungen umfassen. Dies ist ein heuristisches Muster, das zur Vorbereitung von Versuchswellenfunktionen für variierende Quantenalgorithmen oder als Klassifizierungsschaltung für das maschinelle Lernen verwendet werden kann.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "5abc6f15-d7f5-466a-9659-78a11a2c5270",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "<Image src=\"/learning/images/courses/variational-algorithm-design/ansaetze-and-variational-forms/extracted-outputs/5abc6f15-d7f5-466a-9659-78a11a2c5270-0.avif\" alt=\"Output of the previous code cell\" />"
            ]
          },
          "execution_count": 5,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "from qiskit.circuit.library import efficient_su2\n",
        "\n",
        "ansatz = efficient_su2(4, su2_gates=[\"rx\", \"y\"], entanglement=\"linear\", reps=1)\n",
        "ansatz.decompose().draw(\"mpl\")"
      ]
    },
    {
      "attachments": {},
      "cell_type": "markdown",
      "id": "14d01a25-2e2a-47e5-9c50-910599c59502",
      "metadata": {},
      "source": [
        "<span id=\"problem-specific-ansaetze\" />\n",
        "\n",
        "## Problemspezifische Ansätze\n",
        "\n",
        "Während heuristische und hardware-effiziente Ansaetze uns helfen, ein Problem auf naive Weise zu lösen, können wir problemspezifisches Wissen nutzen, um unseren Schaltungssuchraum auf einen bestimmten Typ zu beschränken. Auf diese Weise können wir die Geschwindigkeit erhöhen, ohne dass wir bei der Suche an Genauigkeit verlieren.\n",
        "\n"
      ]
    },
    {
      "attachments": {},
      "cell_type": "markdown",
      "id": "ae376a5f-004c-44af-a6ba-4e4419e350c3",
      "metadata": {},
      "source": [
        "<span id=\"optimization\" />\n",
        "\n",
        "### Optimierung\n",
        "\n",
        "Bei einem Max-Cut-Problem geht es darum, die Knoten eines Graphen so zu partitionieren, dass die Anzahl der Kanten zwischen Knoten in unterschiedlichen Gruppen maximiert wird. Die gewünschte Max-Cut-Partition für den untenstehenden Graphen ist klar: Der 0. Knoten auf der linken Seite sollte von den restlichen Knoten auf der rechten Seite durch einen Cut getrennt werden.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 6,
      "id": "ef9a5e1d-f70a-4f59-9112-2d8f71b253ba",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "<Image src=\"/learning/images/courses/variational-algorithm-design/ansaetze-and-variational-forms/extracted-outputs/ef9a5e1d-f70a-4f59-9112-2d8f71b253ba-0.avif\" alt=\"Output of the previous code cell\" />"
            ]
          },
          "metadata": {},
          "output_type": "display_data"
        }
      ],
      "source": [
        "import rustworkx as rx\n",
        "from rustworkx.visualization import mpl_draw\n",
        "\n",
        "n = 4\n",
        "G = rx.PyGraph()\n",
        "G.add_nodes_from(range(n))\n",
        "# The edge syntax is (start, end, weight)\n",
        "edges = [(0, 1, 1.0), (0, 2, 1.0), (0, 3, 1.0), (1, 2, 1.0), (2, 3, 1.0)]\n",
        "G.add_edges_from(edges)\n",
        "\n",
        "mpl_draw(\n",
        "    G, pos=rx.shell_layout(G), with_labels=True, edge_labels=str, node_color=\"#1192E8\"\n",
        ")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "65d72527-77b1-4eb4-93e5-762a5f55b838",
      "metadata": {},
      "source": [
        "Um den QAOA-Algorithmus für ein Max-Cut-Problem einzusetzen, benötigen wir einen Pauli-Hamiltonian, der die Kosten so kodiert, dass der minimale Erwartungswert des Operators der maximalen Anzahl von Kanten zwischen den Knoten in zwei verschiedenen Gruppen entspricht.\n",
        "\n",
        "In diesem einfachen Beispiel ist der Operator eine Linearkombination von Termen mit Z-Operatoren auf Knoten, die durch eine Kante verbunden sind (das 0. Qubit ist am weitesten rechts): $ZZII + IZZI + ZIIZ + IZIZ + IIZZ$. Sobald der Operator konstruiert ist, kann der Ansatz für den QAOA-Algorithmus leicht mit Hilfe der `QAOAAnsatz` -Schaltung aus der Qiskit-Schaltungsbibliothek erstellt werden.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 7,
      "id": "69599589-689e-4e0f-8135-937aedd9430d",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "<Image src=\"/learning/images/courses/variational-algorithm-design/ansaetze-and-variational-forms/extracted-outputs/69599589-689e-4e0f-8135-937aedd9430d-0.avif\" alt=\"Output of the previous code cell\" />"
            ]
          },
          "execution_count": 7,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "# Pre-defined ansatz circuit, operator class and visualization tools\n",
        "from qiskit.circuit.library import QAOAAnsatz\n",
        "from qiskit.quantum_info import SparsePauliOp\n",
        "\n",
        "# Problem to Hamiltonian operator\n",
        "hamiltonian = SparsePauliOp.from_list(\n",
        "    [(\"ZZII\", 1), (\"IZZI\", 1), (\"ZIIZ\", 1), (\"IZIZ\", 1), (\"IIZZ\", 1)]\n",
        ")\n",
        "# QAOA ansatz circuit\n",
        "ansatz = QAOAAnsatz(hamiltonian, reps=2)\n",
        "# Draw\n",
        "ansatz.decompose(reps=3).draw(\"mpl\")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "23728bd9-ac92-4e3a-a886-2238fc5287ad",
      "metadata": {},
      "source": [
        "In der vorstehenden Abbildung ist der Ansatz zur Verdeutlichung in einfachen Gattern dargestellt. Sie kann jedoch in mehreren Zerlegungsstufen ausgedrückt werden, indem man das Argument `reps` ändert oder die Schaltung ohne die Zerlegungsmethode zeichnet. Die folgende Darstellung zeigt zum Beispiel direkt die QAOA-Struktur mit dem Standardwert für die Wiederholungen, der `reps=1` lautet.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 8,
      "id": "9724a36b-aae6-4d98-aad2-1090f0e1a941",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "<Image src=\"/learning/images/courses/variational-algorithm-design/ansaetze-and-variational-forms/extracted-outputs/9724a36b-aae6-4d98-aad2-1090f0e1a941-0.avif\" alt=\"Output of the previous code cell\" />"
            ]
          },
          "execution_count": 8,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "ansatz.decompose(reps=2).draw(\"mpl\")"
      ]
    },
    {
      "attachments": {},
      "cell_type": "markdown",
      "id": "6a8aa7fc-3f80-46b2-b520-b6006d75a404",
      "metadata": {},
      "source": [
        "<span id=\"quantum-machine-learning\" />\n",
        "\n",
        "### Quantum Machine Learning\n",
        "\n",
        "Beim maschinellen Lernen ist eine häufige Anwendung die Klassifizierung von Daten in zwei oder mehr Kategorien. Dabei wird ein Datenpunkt in eine Merkmalskarte kodiert, die klassische Merkmalsvektoren auf den Quanten-Hilbert-Raum abbildet. Die Konstruktion von Quantenmerkmalen auf der Grundlage parametrisierter Quantenschaltungen, die klassisch nur schwer zu simulieren sind, ist ein wichtiger Schritt zur Erlangung eines potenziellen Vorteils gegenüber klassischen Ansätzen des maschinellen Lernens und ein aktiver Bereich der aktuellen Forschung.\n",
        "\n",
        "Die `zz_feature_map` kann zur Erstellung einer parametrisierten Schaltung verwendet werden. Wir können unsere Datenpunkte an die Feature-Map übergeben ( $x$ ) und eine separate Variationsform zur Übergabe von Gewichten als Parameter ( $\\theta$ ).\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "9d3a813b-40cf-4399-b912-714893987c30",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "<Image src=\"/learning/images/courses/variational-algorithm-design/ansaetze-and-variational-forms/extracted-outputs/9d3a813b-40cf-4399-b912-714893987c30-0.avif\" alt=\"Output of the previous code cell\" />"
            ]
          },
          "execution_count": 9,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "from qiskit.circuit.library import zz_feature_map, TwoLocal\n",
        "\n",
        "data = [0.1, 0.2]\n",
        "\n",
        "zz_feature_map_reference = zz_feature_map(feature_dimension=2, reps=2)\n",
        "zz_feature_map_reference = zz_feature_map_reference.assign_parameters(data)\n",
        "\n",
        "variation_form = TwoLocal(2, [\"ry\", \"rz\"], \"cz\", reps=2)\n",
        "vqc_ansatz = zz_feature_map_reference.compose(variation_form)\n",
        "vqc_ansatz.decompose().draw(\"mpl\")"
      ]
    },
    {
      "attachments": {},
      "cell_type": "markdown",
      "id": "4a1b37bd-8de9-479b-8453-1d8942492731",
      "metadata": {},
      "source": [
        "<span id=\"summary\" />\n",
        "\n",
        "## Zusammenfassung\n",
        "\n",
        "In dieser Lektion haben Sie gelernt, wie Sie Ihren Suchraum mit einer Variationsform definieren können:\n",
        "\n",
        "* Vorbereitung von Zuständen mit einer *parametrisierten* Quantenschaltung, bei der Gatter mit abstimmbaren Parametern definiert sind\n",
        "* Wie man Ansaetze konstruiert, die einen Kompromiss zwischen Geschwindigkeit und Genauigkeit darstellen\n",
        "* Heuristische Ansaetze\n",
        "* Problemspezifische Ansaetze\n",
        "\n",
        "Unser High-Level-Variations-Workload sieht wie folgt aus:\n",
        "\n",
        "![Ein Schaltplan mit zwei Einheiten: eine zur Vorbereitung des Referenzzustands und eine andere zur Vorbereitung des Ansatzes.](https://quantum.cloud.ibm.com/learning/images/courses/variational-algorithm-design/ansaetze-and-variational-forms/ansatz-circuit.svg)\n",
        "\n",
        "Für jeden Variationsparameter $\\vec\\theta$ wird ein anderer Quantenzustand erzeugt. Um die optimalen Parameter zu finden, müssen wir eine problemspezifische *Kostenfunktion* definieren, um die Parameter unseres Ansatzes iterativ zu aktualisieren.\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": 2
}