{
  "cells": [
    {
      "cell_type": "markdown",
      "id": "b3e994de-6477-421d-8a9a-6b20d45260ae",
      "metadata": {},
      "source": [
        "---\n",
        "title: \"Erstellen Sie eine Qiskit-Funktionsvorlage für die Hamilton-Simulation\"\n",
        "description: \"So erstellen Sie ein paralleles Transpilierungsprogramm und stellen es auf IBM Quantum Platform bereit, um es als wiederverwendbaren Remote-Dienst zu verwenden.\"\n",
        "---\n",
        "\n",
        "<span id=\"build-a-qiskit-function-template-for-hamiltonian-simulation\" />\n",
        "\n",
        "# Erstellen Sie eine Qiskit-Funktionsvorlage für die Hamilton-Simulation\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "31aee42c-1834-4fae-a05f-f78d8e5db7c0",
      "metadata": {
        "tags": [
          "version-info"
        ]
      },
      "source": [
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "b51e81bf-0bbf-4f64-af1e-87fcb443d997",
      "metadata": {},
      "source": [
        "Diese Vorlage kapselt einen Workflow zur Simulation der zeitlichen Entwicklung eines Anfangszustands gegenüber einem benutzerdefinierten spinbasierten Hamilton-Operator und gibt mithilfe des [AQC-Tensor](https://qiskit.github.io/qiskit-addon-aqc-tensor/) -Qiskit-Add-ons eine Reihe von festgelegten Erwartungswerten zurück.\n",
        "\n",
        "Diese Vorlage ist wie ein Qiskit-Muster mit den folgenden Schritten aufgebaut:\n",
        "\n",
        "<span id=\"1-collecting-input-and-mapping-the-problem\" />\n",
        "\n",
        "#### 1. Sammeln von Input und Erfassen des Problems\n",
        "\n",
        "Dieser Abschnitt nimmt als Eingabe den zu simulierenden Hamiltonian, einen Anfangszustand in Form einer `QuantumCircuit`, einen Satz von Beobachtungswerten zur Schätzung von Erwartungswerten und eine Spezifikation von Optionen für das AQC-Addon. In diesem Schritt wird überprüft, ob alle erforderlichen Eingabedaten vorhanden sind und ob sie das richtige Format haben.\n",
        "\n",
        "Die Eingangsargumente werden dann verwendet, um die entsprechenden Quantenschaltungen und Operatoren für den Arbeitsablauf zu konstruieren. Es wird eine Zielschaltung erstellt und mit Hilfe des AQC-Addons eine Matrixprodukt-Zustandsdarstellung dieser Schaltung gefunden. Anschließend wird ein Ansatzschaltkreis erzeugt und mit Hilfe von Tensornetzmethoden optimiert, so dass ein endgültiger Schaltkreis entsteht, der den Rest der Zeitentwicklung ausführt.\n",
        "\n",
        "<span id=\"2-prepare-the-generated-circuits-for-execution\" />\n",
        "\n",
        "#### 2. Bereiten Sie die generierten Schaltungen für die Ausführung vor\n",
        "\n",
        "Die vom AQC-Addon generierten Schaltkreise werden dann zur Ausführung auf einem ausgewählten Backend transpiliert. Eine [`EstimatorV2`](../api/qiskit-ibm-runtime/estimator-v2) instanz wird mit einem Standardsatz von Optionen zur Fehlerbegrenzung erstellt, um die Ausführung der Schaltung zu verwalten.\n",
        "\n",
        "<span id=\"3-execution\" />\n",
        "\n",
        "#### 3. Ausführung\n",
        "\n",
        "Schließlich wird der Ansatzschaltkreis transpiliert und auf einer QPU ausgeführt und sammelt Schätzungen für alle angegebenen Erwartungswerte, die in einem serialisierbaren Format für den Zugriff durch den Benutzer zurückgegeben werden.\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "e451f954-1d8f-4687-a7e9-e4b0dfa170f3",
      "metadata": {},
      "source": [
        "<span id=\"write-the-function-template\" />\n",
        "\n",
        "## Schreiben Sie die Funktionsvorlage\n",
        "\n",
        "Schreiben Sie zunächst eine Funktionsvorlage für die Hamilton-Simulation, die das [AQC-Tensor-Qiskit-Add-on](https://qiskit.github.io/qiskit-addon-aqc-tensor/) verwendet, um die Problemdarstellung auf einen Schaltkreis mit reduzierter Tiefe für die Ausführung auf Hardware abzubilden.\n",
        "\n",
        "Wenn Sie diese Seite herunterladen und lokal in einem Notizbuch-Editor anzeigen, werden Sie feststellen, dass einige der Codezellen den [Befehl „magic“](https://ipython.readthedocs.io/en/stable/interactive/magics.html#cellmagic-writefile) enthalten `%%writefile`. Dieser magische Befehl speichert den Code in `./source_files/template_hamiltonian_simulation.py`, einer Funktionsvorlage, die Sie auf hochladen und über Qiskit Serverless remote ausführen können.\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "115c14aa-5028-46f9-ab19-b49d47519636",
      "metadata": {},
      "source": [
        "<span id=\"collect-and-validate-the-inputs\" />\n",
        "\n",
        "### Die Eingaben sammeln und validieren\n",
        "\n",
        "Beginnen Sie damit, die Eingaben für die Vorlage zu erhalten. Dieses Beispiel verfügt über domänenspezifische Eingaben, die für die Hamilton-Simulation relevant sind (z. B. Hamiltonian und Observable), sowie über fähigkeitsspezifische Optionen (z. B. wie stark Sie die anfänglichen Schichten des Trotter-Schaltkreises mit AQC-Tensor komprimieren möchten, oder erweiterte Optionen für die Feinabstimmung der Fehlerunterdrückung und -minderung, die über die Standardeinstellungen in diesem Beispiel hinausgehen).\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "5e1e974b-feaa-47ce-abd1-65d442e8176e",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "Writing ./source_files/template_hamiltonian_simulation.py\n"
          ]
        }
      ],
      "source": [
        "%%writefile ./source_files/template_hamiltonian_simulation.py\n",
        "\n",
        "from qiskit import QuantumCircuit\n",
        "from qiskit_serverless import get_arguments, save_result\n",
        "\n",
        "\n",
        "# Extract parameters from arguments\n",
        "#\n",
        "# Do this at the top of the program so it fails early if any required arguments\n",
        "# are missing or invalid.\n",
        "\n",
        "arguments = get_arguments()\n",
        "\n",
        "dry_run = arguments.get(\"dry_run\", False)\n",
        "backend_name = arguments[\"backend_name\"]\n",
        "\n",
        "aqc_evolution_time = arguments[\"aqc_evolution_time\"]\n",
        "aqc_ansatz_num_trotter_steps = arguments[\"aqc_ansatz_num_trotter_steps\"]\n",
        "aqc_target_num_trotter_steps = arguments[\"aqc_target_num_trotter_steps\"]\n",
        "\n",
        "remainder_evolution_time = arguments[\"remainder_evolution_time\"]\n",
        "remainder_num_trotter_steps = arguments[\"remainder_num_trotter_steps\"]\n",
        "\n",
        "# Stop if this fidelity is achieved\n",
        "aqc_stopping_fidelity = arguments.get(\"aqc_stopping_fidelity\", 1.0)\n",
        "# Stop after this number of iterations, even if stopping fidelity is not achieved\n",
        "aqc_max_iterations = arguments.get(\"aqc_max_iterations\", 500)\n",
        "\n",
        "hamiltonian = arguments[\"hamiltonian\"]\n",
        "observable = arguments[\"observable\"]\n",
        "initial_state = arguments.get(\"initial_state\",\n",
        "    QuantumCircuit(hamiltonian.num_qubits))"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "3f2629d5-5183-432a-8802-115a3b2f6ff7",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "Appending to ./source_files/template_hamiltonian_simulation.py\n"
          ]
        }
      ],
      "source": [
        "%%writefile --append ./source_files/template_hamiltonian_simulation.py\n",
        "\n",
        "import numpy as np\n",
        "import json\n",
        "from mergedeep import merge\n",
        "\n",
        "\n",
        "# Configure `EstimatorOptions`, to control the parameters\n",
        "# of the hardware experiment\n",
        "#\n",
        "# Set default options\n",
        "estimator_default_options = {\n",
        "    \"resilience\": {\n",
        "        \"measure_mitigation\": True,\n",
        "        \"zne_mitigation\": True,\n",
        "        \"zne\": {\n",
        "            \"amplifier\": \"gate_folding\",\n",
        "            \"noise_factors\": [1, 2, 3],\n",
        "            \"extrapolated_noise_factors\": list(np.linspace(0, 3, 31)),\n",
        "            \"extrapolator\": [\"exponential\", \"linear\", \"fallback\"],\n",
        "        },\n",
        "        \"measure_noise_learning\": {\n",
        "            \"num_randomizations\": 512,\n",
        "            \"shots_per_randomization\": 512,\n",
        "        },\n",
        "    },\n",
        "    \"twirling\": {\n",
        "        \"enable_gates\": True,\n",
        "        \"enable_measure\": True,\n",
        "        \"num_randomizations\": 300,\n",
        "        \"shots_per_randomization\": 100,\n",
        "        \"strategy\": \"active\",\n",
        "    },\n",
        "}\n",
        "# Merge with user-provided options\n",
        "estimator_options = merge(\n",
        "    arguments.get(\"estimator_options\", {}), estimator_default_options\n",
        ")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "ac4e21bf-ccec-459e-984b-dc6a13ea56c8",
      "metadata": {},
      "source": [
        "Wenn die Funktionsschablone läuft, ist es hilfreich, Informationen in den Protokollen mit Hilfe von Druckanweisungen zurückzugeben, so daß Sie den Fortschritt der Arbeitslast besser beurteilen können. Nachfolgend finden Sie ein einfaches Beispiel für das Drucken von `estimator_options` , um die tatsächlich verwendeten Estimator-Optionen zu dokumentieren. Es gibt noch viele weitere ähnliche Beispiele im gesamten Programm, um den Fortschritt während der Ausführung zu melden, einschließlich des Wertes der Zielfunktion während der iterativen Komponente von AQC-Tensor und der Zwei-Qubit-Tiefe der endgültigen ISA-Schaltung, die für die Ausführung auf Hardware vorgesehen ist.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 4,
      "id": "be933b77-fb13-4875-9734-4226067bc8d2",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "Appending to ./source_files/template_hamiltonian_simulation.py\n"
          ]
        }
      ],
      "source": [
        "%%writefile --append ./source_files/template_hamiltonian_simulation.py\n",
        "\n",
        "print(\"estimator_options =\", json.dumps(estimator_options, indent=4))"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "fb65718c-8837-4610-87b7-59e6dc7abb80",
      "metadata": {},
      "source": [
        "<span id=\"validate-the-inputs\" />\n",
        "\n",
        "#### Überprüfen Sie die Eingaben\n",
        "\n",
        "Ein wichtiger Aspekt, um sicherzustellen, dass die Vorlage für eine Reihe von Eingaben wiederverwendet werden kann, ist die Eingabevalidierung. Der folgende Code ist ein Beispiel dafür, wie überprüft werden kann, ob die Anhaltetreue bei AQC-Tensor richtig angegeben wurde, und wenn nicht, eine informative Fehlermeldung zurückgegeben wird, wie der Fehler behoben werden kann.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "0af1aee2-5771-4ae1-82dc-3ec08943de54",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "Appending to ./source_files/template_hamiltonian_simulation.py\n"
          ]
        }
      ],
      "source": [
        "%%writefile --append ./source_files/template_hamiltonian_simulation.py\n",
        "\n",
        "# Perform parameter validation\n",
        "\n",
        "if not 0.0 < aqc_stopping_fidelity <= 1.0:\n",
        "    raise ValueError(\n",
        "        f\"Invalid stopping fidelity: {aqc_stopping_fidelity}.  \"\n",
        "        f\"It must be a positive float no greater than 1.\"\n",
        "    )"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "0e5495ee-82e2-43dc-bca7-f8e81f8b6302",
      "metadata": {},
      "source": [
        "<span id=\"prepare-the-function-outputs\" />\n",
        "\n",
        "#### Bereiten Sie die Funktionsausgänge vor\n",
        "\n",
        "Bereiten Sie zunächst ein Wörterbuch vor, das alle Ausgaben der Funktionsvorlagen enthält. Diesem Wörterbuch werden während des gesamten Arbeitsablaufs Schlüssel hinzugefügt, und es wird am Ende des Programms zurückgegeben.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 6,
      "id": "1677fa7c-3b4a-4a24-b1e4-e03d9b3c49da",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "Appending to ./source_files/template_hamiltonian_simulation.py\n"
          ]
        }
      ],
      "source": [
        "%%writefile --append ./source_files/template_hamiltonian_simulation.py\n",
        "\n",
        "output = {}"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "3acd5522-a880-4de7-9251-2d68efc261ad",
      "metadata": {},
      "source": [
        "<span id=\"map-the-problem-and-pre-process-the-circuit-with-aqc\" />\n",
        "\n",
        "### Das Problem abbilden und die Schaltung mit AQC vorverarbeiten\n",
        "\n",
        "Die AQC-Tensor-Optimierung erfolgt in Schritt 1 eines Qiskit-Musters.  Zunächst wird ein Zielzustand konstruiert.  In diesem Beispiel wird er aus einer Zielschaltung konstruiert, die denselben Hamiltonian für denselben Zeitraum entwickelt wie der AQC-Teil.  Anschließend wird ein Ersatzschaltbild mit weniger Trotter-Schritten erstellt.  Im Hauptteil des AQC-Algorithmus wird dieser Ansatz iterativ an den Zielzustand herangeführt.  Schließlich wird das Ergebnis mit den verbleibenden Trotter-Schritten kombiniert, die erforderlich sind, um die gewünschte Entwicklungszeit zu erreichen.\n",
        "\n",
        "Beachten Sie die zusätzlichen Beispiele für die Protokollierung, die im folgenden Code enthalten sind.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "92b59882-2844-4312-a09b-3da02c63f60b",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "Appending to ./source_files/template_hamiltonian_simulation.py\n"
          ]
        }
      ],
      "source": [
        "%%writefile --append ./source_files/template_hamiltonian_simulation.py\n",
        "\n",
        "import os\n",
        "os.environ[\"NUMBA_CACHE_DIR\"] = \"/data\"\n",
        "\n",
        "import datetime\n",
        "import quimb.tensor\n",
        "from scipy.optimize import OptimizeResult, minimize\n",
        "from qiskit.synthesis import SuzukiTrotter\n",
        "from qiskit_addon_utils.problem_generators import generate_time_evolution_circuit\n",
        "from qiskit_addon_aqc_tensor.ansatz_generation import (\n",
        "    generate_ansatz_from_circuit,\n",
        "    AnsatzBlock,\n",
        ")\n",
        "from qiskit_addon_aqc_tensor.simulation import (\n",
        "    tensornetwork_from_circuit,\n",
        "    compute_overlap,\n",
        ")\n",
        "from qiskit_addon_aqc_tensor.simulation.quimb import QuimbSimulator\n",
        "from qiskit_addon_aqc_tensor.objective import OneMinusFidelity\n",
        "\n",
        "print(\"Hamiltonian:\", hamiltonian)\n",
        "print(\"Observable:\", observable)\n",
        "simulator_settings = QuimbSimulator(quimb.tensor.CircuitMPS, autodiff_backend=\"jax\")\n",
        "\n",
        "# Construct the AQC target circuit\n",
        "aqc_target_circuit = initial_state.copy()\n",
        "if aqc_evolution_time:\n",
        "    aqc_target_circuit.compose(\n",
        "        generate_time_evolution_circuit(\n",
        "            hamiltonian,\n",
        "            synthesis=SuzukiTrotter(reps=aqc_target_num_trotter_steps),\n",
        "            time=aqc_evolution_time,\n",
        "        ),\n",
        "        inplace=True,\n",
        "    )\n",
        "\n",
        "# Construct matrix-product state representation of the AQC target state\n",
        "aqc_target_mps = tensornetwork_from_circuit(aqc_target_circuit, simulator_settings)\n",
        "print(\"Target MPS maximum bond dimension:\", aqc_target_mps.psi.max_bond())\n",
        "output[\"target_bond_dimension\"] = aqc_target_mps.psi.max_bond()\n",
        "\n",
        "# Generate an ansatz and initial parameters from a Trotter circuit with fewer steps\n",
        "aqc_good_circuit = initial_state.copy()\n",
        "if aqc_evolution_time:\n",
        "    aqc_good_circuit.compose(\n",
        "        generate_time_evolution_circuit(\n",
        "            hamiltonian,\n",
        "            synthesis=SuzukiTrotter(reps=aqc_ansatz_num_trotter_steps),\n",
        "            time=aqc_evolution_time,\n",
        "        ),\n",
        "        inplace=True,\n",
        "    )\n",
        "aqc_ansatz, aqc_initial_parameters = generate_ansatz_from_circuit(aqc_good_circuit)\n",
        "print(\"Number of AQC parameters:\", len(aqc_initial_parameters))\n",
        "output[\"num_aqc_parameters\"] = len(aqc_initial_parameters)\n",
        "\n",
        "# Calculate the fidelity of ansatz circuit vs. the target state, before optimization\n",
        "good_mps = tensornetwork_from_circuit(aqc_good_circuit, simulator_settings)\n",
        "starting_fidelity = abs(compute_overlap(good_mps, aqc_target_mps)) ** 2\n",
        "print(\"Starting fidelity of AQC portion:\", starting_fidelity)\n",
        "output[\"aqc_starting_fidelity\"] = starting_fidelity\n",
        "\n",
        "# Optimize the ansatz parameters by using MPS calculations\n",
        "def callback(intermediate_result: OptimizeResult):\n",
        "    fidelity = 1 - intermediate_result.fun\n",
        "    print(f\"{datetime.datetime.now()} Intermediate result: Fidelity {fidelity:.8f}\")\n",
        "    if intermediate_result.fun < stopping_point:\n",
        "        raise StopIteration\n",
        "\n",
        "\n",
        "objective = OneMinusFidelity(aqc_target_mps, aqc_ansatz, simulator_settings)\n",
        "stopping_point = 1.0 - aqc_stopping_fidelity\n",
        "\n",
        "result = minimize(\n",
        "    objective,\n",
        "    aqc_initial_parameters,\n",
        "    method=\"L-BFGS-B\",\n",
        "    jac=True,\n",
        "    options={\"maxiter\": aqc_max_iterations},\n",
        "    callback=callback,\n",
        ")\n",
        "if result.status not in (\n",
        "    0,\n",
        "    1,\n",
        "    99,\n",
        "):  # 0 => success; 1 => max iterations reached;\n",
        "    # 99 => early termination via StopIteration\n",
        "    raise RuntimeError(\n",
        "        f\"Optimization failed: {result.message} (status={result.status})\"\n",
        "    )\n",
        "print(f\"Done after {result.nit} iterations.\")\n",
        "output[\"num_iterations\"] = result.nit\n",
        "aqc_final_parameters = result.x\n",
        "output[\"aqc_final_parameters\"] = list(aqc_final_parameters)\n",
        "\n",
        "# Construct an optimized circuit for initial portion of time evolution\n",
        "aqc_final_circuit = aqc_ansatz.assign_parameters(aqc_final_parameters)\n",
        "\n",
        "# Calculate fidelity after optimization\n",
        "aqc_final_mps = tensornetwork_from_circuit(aqc_final_circuit, simulator_settings)\n",
        "aqc_fidelity = abs(compute_overlap(aqc_final_mps, aqc_target_mps)) ** 2\n",
        "print(\"Fidelity of AQC portion:\", aqc_fidelity)\n",
        "output[\"aqc_fidelity\"] = aqc_fidelity\n",
        "\n",
        "# Construct final circuit, with remainder of time evolution\n",
        "final_circuit = aqc_final_circuit.copy()\n",
        "if remainder_evolution_time:\n",
        "    remainder_circuit = generate_time_evolution_circuit(\n",
        "        hamiltonian,\n",
        "        synthesis=SuzukiTrotter(reps=remainder_num_trotter_steps),\n",
        "        time=remainder_evolution_time,\n",
        "    )\n",
        "    final_circuit.compose(remainder_circuit, inplace=True)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "ae8e53a6-2106-4753-ad1a-ebc146cd44ab",
      "metadata": {},
      "source": [
        "<span id=\"optimize-the-final-circuit-for-execution\" />\n",
        "\n",
        "### Optimieren Sie den endgültigen Schaltkreis für die Ausführung\n",
        "\n",
        "Nach dem AQC-Teil des Workflows wird die `final_circuit` wie gewohnt [auf die Hardware übertragen](/docs/guides/transpile#instruction-set-architecture).\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "1db2749f-1285-48c6-8ec3-bc9f422686e2",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "Appending to ./source_files/template_hamiltonian_simulation.py\n"
          ]
        }
      ],
      "source": [
        "%%writefile --append ./source_files/template_hamiltonian_simulation.py\n",
        "\n",
        "from qiskit_serverless import get_runtime_service\n",
        "from qiskit.transpiler import generate_preset_pass_manager\n",
        "\n",
        "service = get_runtime_service()\n",
        "backend = service.backend(backend_name)\n",
        "\n",
        "# Transpile PUBs (circuits and observables) to match ISA\n",
        "pass_manager = generate_preset_pass_manager(backend=backend, optimization_level=3)\n",
        "isa_circuit = pass_manager.run(final_circuit)\n",
        "isa_observable = observable.apply_layout(isa_circuit.layout)\n",
        "\n",
        "isa_2qubit_depth = isa_circuit.depth(lambda x: x.operation.num_qubits == 2)\n",
        "print(\"ISA circuit two-qubit depth:\", isa_2qubit_depth)\n",
        "output[\"twoqubit_depth\"] = isa_2qubit_depth"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "c41b9c0e-1f00-454c-acff-c194cc16e03e",
      "metadata": {},
      "source": [
        "<span id=\"exit-early-if-using-dry-run-mode\" />\n",
        "\n",
        "#### Bei Verwendung des Trockenlaufmodus frühzeitig beenden\n",
        "\n",
        "Wenn der Trockenlaufmodus gewählt wurde, wird das Programm angehalten, bevor es auf der Hardware ausgeführt wird. Dies kann nützlich sein, wenn Sie beispielsweise zunächst die Zwei-Qubit-Tiefe der ISA-Schaltung prüfen wollen, bevor Sie sich für die Ausführung in Hardware entscheiden.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 9,
      "id": "e7c6c770-0453-4ad7-9a3e-20a47208768a",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "Appending to ./source_files/template_hamiltonian_simulation.py\n"
          ]
        }
      ],
      "source": [
        "%%writefile --append ./source_files/template_hamiltonian_simulation.py\n",
        "\n",
        "# Exit now if dry run; don't execute on hardware\n",
        "if dry_run:\n",
        "    import sys\n",
        "\n",
        "    print(\"Exiting before hardware execution since `dry_run` is True.\")\n",
        "    save_result(output)\n",
        "    sys.exit(0)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "3a603817-abaf-4403-beea-cca838a59577",
      "metadata": {},
      "source": [
        "<span id=\"execute-the-circuit-on-hardware\" />\n",
        "\n",
        "#### Führen Sie den Schaltkreis auf der Hardware aus\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "b7525014-a473-4d9d-b7cb-9c590f2364ae",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "Appending to ./source_files/template_hamiltonian_simulation.py\n"
          ]
        }
      ],
      "source": [
        "%%writefile --append ./source_files/template_hamiltonian_simulation.py\n",
        "\n",
        "# ## Step 3: Execute quantum experiments on backend\n",
        "from qiskit_ibm_runtime import EstimatorV2 as Estimator\n",
        "\n",
        "\n",
        "estimator = Estimator(backend, options=estimator_options)\n",
        "\n",
        "# Submit the underlying Estimator job. Note that this is not the\n",
        "# actual function job.\n",
        "job = estimator.run([(isa_circuit, isa_observable)])\n",
        "print(\"Job ID:\", job.job_id())\n",
        "output[\"job_id\"] = job.job_id()\n",
        "\n",
        "# Wait until job is complete\n",
        "hw_results = job.result()\n",
        "hw_results_dicts = [pub_result.data.__dict__ for pub_result in hw_results]\n",
        "\n",
        "# Save hardware results to serverless output dictionary\n",
        "output[\"hw_results\"] = hw_results_dicts\n",
        "\n",
        "# Reorganize expectation values\n",
        "hw_expvals = [pub_result_data[\"evs\"].tolist()\n",
        "    for pub_result_data in hw_results_dicts]\n",
        "\n",
        "# Save expectation values to Qiskit Serverless\n",
        "print(\"Hardware expectation values\", hw_expvals)\n",
        "output[\"hw_expvals\"] = hw_expvals[0]"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "12df35c4-4f1c-48cb-a323-d0cf33422fab",
      "metadata": {},
      "source": [
        "<span id=\"save-the-output\" />\n",
        "\n",
        "#### Die Ausgabe speichern\n",
        "\n",
        "Diese Funktionsvorlage liefert die relevanten Ausgaben auf Domänenebene für diesen Hamilton-Simulations-Workflow (Erwartungswerte) sowie wichtige Metadaten, die auf dem Weg generiert wurden.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 11,
      "id": "bfb8ab87-c42d-4993-92bd-8b38364dc443",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "Appending to ./source_files/template_hamiltonian_simulation.py\n"
          ]
        }
      ],
      "source": [
        "%%writefile --append ./source_files/template_hamiltonian_simulation.py\n",
        "\n",
        "save_result(output)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "220f8bc8-4f04-41d3-86f1-15e9c2f45a56",
      "metadata": {},
      "source": [
        "<span id=\"deploy-the-function-to-ibm-quantum-platform\" />\n",
        "\n",
        "## Stellen Sie die Funktion auf IBM Quantum Platform bereit\n",
        "\n",
        "Im vorigen Abschnitt wurde ein Programm erstellt, das aus der Ferne ausgeführt werden soll. Mit dem Code in diesem Abschnitt wird das Programm auf Qiskit Serverless hochgeladen.\n",
        "\n",
        "Verwenden Sie `qiskit-ibm-catalog` , um sich auf `QiskitServerless` mit Ihrem API-Schlüssel zu authentifizieren, den Sie auf dem Dashboard der [Quantum-Plattform IBM]() finden, und laden Sie das Programm hoch.\n",
        "\n",
        "Sie können optional verwenden, `save_account()` um Ihre Anmeldedaten zu speichern (siehe Anleitung [zum Einrichten Ihres IBM Cloud -Kontos](/docs/guides/cloud-setup#cloud-save) ). Beachten Sie, dass Ihre Anmeldedaten in dieselbe Datei wie [`QiskitRuntimeService.save_account()`](/docs/api/qiskit-ibm-runtime/qiskit-runtime-service#save_account). geschrieben werden.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "313bd03b-bf9b-4e6c-aa05-1fe8def3868d",
      "metadata": {},
      "outputs": [],
      "source": [
        "from qiskit_ibm_catalog import QiskitServerless, QiskitFunction\n",
        "\n",
        "# Authenticate to the remote cluster and submit the pattern\n",
        "# for remote execution\n",
        "serverless = QiskitServerless()"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "e9c495d4-cdab-4329-b65d-d111029aee64",
      "metadata": {},
      "source": [
        "Dieses Programm hat eigene `pip` Abhängigkeiten.  Fügen Sie sie bei der Erstellung der Instanz `QiskitFunction` zu einem Array `dependencies` hinzu:\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 13,
      "id": "ca386323-d92d-4c41-908b-1670324e1264",
      "metadata": {},
      "outputs": [],
      "source": [
        "template = QiskitFunction(\n",
        "    title=\"template_hamiltonian_simulation\",\n",
        "    entrypoint=\"template_hamiltonian_simulation.py\",\n",
        "    working_dir=\"./source_files/\",\n",
        "    dependencies=[\n",
        "        \"qiskit-addon-utils~=0.1.0\",\n",
        "        \"qiskit-addon-aqc-tensor[quimb-jax]~=0.1.2\",\n",
        "        \"mergedeep==1.3.4\",\n",
        "    ],\n",
        ")"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 14,
      "id": "80a2c6b5-1f1e-4e90-9b1f-75907caf1df3",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "QiskitFunction(template_hamiltonian_simulation)"
            ]
          },
          "execution_count": 14,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "serverless.upload(template)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "06677105-627a-4948-aac7-071f44327a0b",
      "metadata": {},
      "source": [
        "Prüfen Sie schließlich, ob das Programm erfolgreich hochgeladen wurde, indem Sie `serverless.list()` verwenden:\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 15,
      "id": "11f14088-8eca-4a99-a291-3f37a61b0d26",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              " QiskitFunction(template_hamiltonian_simulation),\n"
            ]
          },
          "execution_count": 15,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "serverless.list()"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "385bda3e-73de-413c-8e45-cf7047303219",
      "metadata": {},
      "source": [
        "<span id=\"run-the-function-template-remotely\" />\n",
        "\n",
        "## Führen Sie die Funktionsvorlage remote aus\n",
        "\n",
        "Die Funktionsvorlage wurde hochgeladen, sodass Sie sie mit Qiskit Serverless aus der Ferne ausführen können. Laden Sie zunächst die Vorlage nach ihrem Namen:\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 16,
      "id": "d4ff8dea-95ab-4cc9-92b9-e28e277e76f2",
      "metadata": {},
      "outputs": [],
      "source": [
        "template = serverless.load(\"template_hamiltonian_simulation\")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "57964962-87e9-4c0b-a717-cb620019960e",
      "metadata": {},
      "source": [
        "Führen Sie anschließend die Vorlage mit den Eingaben auf Domänenebene für die Hamilton-Simulation aus. Dieses Beispiel spezifiziert ein 50-Qubit-XXZ-Modell mit zufälligen Kopplungen, einem Anfangszustand und einer Beobachtungsgröße.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 17,
      "id": "e5d1555c-9abb-4fef-b8a2-f8d1b723df01",
      "metadata": {},
      "outputs": [],
      "source": [
        "from itertools import chain\n",
        "import numpy as np\n",
        "from qiskit.quantum_info import SparsePauliOp\n",
        "\n",
        "L = 50\n",
        "\n",
        "# Generate the edge list for this spin-chain\n",
        "edges = [(i, i + 1) for i in range(L - 1)]\n",
        "# Generate an edge-coloring so we can make hw-efficient circuits\n",
        "edges = edges[::2] + edges[1::2]\n",
        "\n",
        "# Generate random coefficients for our XXZ Hamiltonian\n",
        "np.random.seed(0)\n",
        "Js = np.random.rand(L - 1) + 0.5 * np.ones(L - 1)\n",
        "\n",
        "hamiltonian = SparsePauliOp.from_sparse_list(\n",
        "    chain.from_iterable(\n",
        "        [\n",
        "            [\n",
        "                (\"XX\", (i, j), Js[i] / 2),\n",
        "                (\"YY\", (i, j), Js[i] / 2),\n",
        "                (\"ZZ\", (i, j), Js[i]),\n",
        "            ]\n",
        "            for i, j in edges\n",
        "        ]\n",
        "    ),\n",
        "    num_qubits=L,\n",
        ")\n",
        "observable = SparsePauliOp.from_sparse_list(\n",
        "    [(\"ZZ\", (L // 2 - 1, L // 2), 1.0)], num_qubits=L\n",
        ")"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 18,
      "id": "7ec5ab02-280c-4c04-8e63-e5354eb8ebb9",
      "metadata": {},
      "outputs": [],
      "source": [
        "from qiskit import QuantumCircuit\n",
        "\n",
        "initial_state = QuantumCircuit(L)\n",
        "for i in range(L):\n",
        "    if i % 2:\n",
        "        initial_state.x(i)"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 19,
      "id": "ac8d8fec-0290-4d6b-a18c-afd02acfa850",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "853b0edb-d63f-4629-be71-398b6dcf33cb\n"
          ]
        }
      ],
      "source": [
        "job = template.run(\n",
        "    dry_run=True,\n",
        "    initial_state=initial_state,\n",
        "    hamiltonian=hamiltonian,\n",
        "    observable=observable,\n",
        "    backend_name=\"ibm_fez\",\n",
        "    estimator_options={},\n",
        "    aqc_evolution_time=0.2,\n",
        "    aqc_ansatz_num_trotter_steps=1,\n",
        "    aqc_target_num_trotter_steps=32,\n",
        "    remainder_evolution_time=0.2,\n",
        "    remainder_num_trotter_steps=4,\n",
        "    aqc_max_iterations=300,\n",
        ")\n",
        "print(job.job_id)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "2249cabc-6821-4d84-b4d8-e519c2d94a5c",
      "metadata": {},
      "source": [
        "Überprüfen Sie den Status des Auftrags:\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 20,
      "id": "ed3b744d-cb00-43e0-907c-34dfebe2fa9b",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "'QUEUED'"
            ]
          },
          "execution_count": 20,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "job.status()"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "83751f45-ab37-4037-bc77-d1aef91ed46c",
      "metadata": {},
      "source": [
        "Nachdem der Auftrag ausgeführt wurde, können Sie die Protokolle abrufen, die von den `print()` Ausgaben erstellt wurden. Diese können verwertbare Informationen über den Fortschritt des Hamilton-Simulationsablaufs liefern. Zum Beispiel der Wert der Zielfunktion während der iterativen Komponente von AQC oder die Zwei-Qubit-Tiefe des endgültigen ISA-Schaltkreises, der für die Ausführung in Hardware vorgesehen ist.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 21,
      "id": "3be62464-18b0-4598-b386-0ac0cc9cccb6",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "No logs yet.\n"
          ]
        }
      ],
      "source": [
        "print(job.logs())"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "a8384509-2a9d-44e6-a729-40464ff52bea",
      "metadata": {},
      "source": [
        "Blockieren Sie den Rest des Programms, bis ein Ergebnis vorliegt. Nach Abschluss der Arbeit können Sie die Ergebnisse abrufen. Dazu gehören die Ergebnisse der Hamilton-Simulation auf Domänenebene (Erwartungswert) und nützliche Metadaten.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 22,
      "id": "fc678bcd-539d-4970-86e0-9a69f0a367ef",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "{'target_bond_dimension': 5,\n",
              " 'num_aqc_parameters': 816,\n",
              " 'aqc_starting_fidelity': 0.9914382555614002,\n",
              " 'num_iterations': 72,\n",
              " 'aqc_fidelity': 0.9998108844412502,\n",
              " 'twoqubit_depth': 33}"
            ]
          },
          "execution_count": 22,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "result = job.result()\n",
        "\n",
        "del result[\n",
        "    \"aqc_final_parameters\"\n",
        "]  # the list is too long to conveniently display here\n",
        "result"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "12b0ccfe-325a-4939-81e7-58d94557990d",
      "metadata": {},
      "source": [
        "Nach Beendigung des Auftrags steht die gesamte Protokollierung zur Verfügung.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 23,
      "id": "cb722373-cbfb-45a7-a2b5-d7a97e18ee6c",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "2024-12-17 14:50:15,580\tINFO job_manager.py:531 -- Runtime env is setting up.\n",
            "estimator_options = {\n",
            "    \"resilience\": {\n",
            "        \"measure_mitigation\": true,\n",
            "        \"zne_mitigation\": true,\n",
            "        \"zne\": {\n",
            "            \"amplifier\": \"gate_folding\",\n",
            "            \"noise_factors\": [\n",
            "                1,\n",
            "                2,\n",
            "                3\n",
            "            ],\n",
            "            \"extrapolated_noise_factors\": [\n",
            "                0.0,\n",
            "                0.1,\n",
            "                0.2,\n",
            "                0.30000000000000004,\n",
            "                0.4,\n",
            "                0.5,\n",
            "                0.6000000000000001,\n",
            "                0.7000000000000001,\n",
            "                0.8,\n",
            "                0.9,\n",
            "                1.0,\n",
            "                1.1,\n",
            "                1.2000000000000002,\n",
            "                1.3,\n",
            "                1.4000000000000001,\n",
            "                1.5,\n",
            "                1.6,\n",
            "                1.7000000000000002,\n",
            "                1.8,\n",
            "                1.9000000000000001,\n",
            "                2.0,\n",
            "                2.1,\n",
            "                2.2,\n",
            "                2.3000000000000003,\n",
            "                2.4000000000000004,\n",
            "                2.5,\n",
            "                2.6,\n",
            "                2.7,\n",
            "                2.8000000000000003,\n",
            "                2.9000000000000004,\n",
            "                3.0\n",
            "            ],\n",
            "            \"extrapolator\": [\n",
            "                \"exponential\",\n",
            "                \"linear\",\n",
            "                \"fallback\"\n",
            "            ]\n",
            "        },\n",
            "        \"measure_noise_learning\": {\n",
            "            \"num_randomizations\": 512,\n",
            "            \"shots_per_randomization\": 512\n",
            "        }\n",
            "    },\n",
            "    \"twirling\": {\n",
            "        \"enable_gates\": true,\n",
            "        \"enable_measure\": true,\n",
            "        \"num_randomizations\": 300,\n",
            "        \"shots_per_randomization\": 100,\n",
            "        \"strategy\": \"active\"\n",
            "    }\n",
            "}\n",
            "Hamiltonian: SparsePauliOp(['IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIXX', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIYY', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZZ', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIXXII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIYYII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZZII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIXXIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIYYIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZZIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIXXIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIYYIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZZIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIXXIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIYYIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZZIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIXXIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIYYIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZZIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIXXIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIYYIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZZIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIXXIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIYYIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZZIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIXXIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIYYIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZZIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIXXIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIYYIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZZIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIXXIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIYYIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIZZIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIXXIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIYYIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIZZIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIXXIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIYYIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIZZIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIXXIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIYYIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIZZIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIXXIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIYYIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIZZIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIXXIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIYYIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIZZIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIXXIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIYYIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIZZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIXXIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIYYIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIZZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIXXIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIYYIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIZZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIXXIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIYYIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIZZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIXXIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIYYIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIZZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIXXIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIYYIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIZZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIXXIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIYYIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIZZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIXXIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIYYIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIZZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'XXIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'YYIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'ZZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIXXI', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIYYI', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZZI', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIXXIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIYYIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZZIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIXXIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIYYIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZZIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIXXIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIYYIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZZIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIXXIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIYYIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZZIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIXXIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIYYIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZZIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIXXIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIYYIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZZIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIXXIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIYYIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZZIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIXXIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIYYIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZZIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIXXIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIYYIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIZZIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIXXIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIYYIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIZZIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIXXIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIYYIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIZZIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIXXIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIYYIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIZZIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIXXIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIYYIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIZZIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIXXIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIYYIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIZZIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIXXIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIYYIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIZZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIXXIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIYYIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIZZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIXXIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIYYIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIZZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIXXIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIYYIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIZZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIXXIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIYYIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIZZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIXXIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIYYIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIZZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIXXIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIYYIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIZZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIXXIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIYYIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIZZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IXXIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IYYIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IZZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII'],\n",
            "              coeffs=[0.52440675+0.j, 0.52440675+0.j, 1.0488135 +0.j, 0.55138169+0.j,\n",
            " 0.55138169+0.j, 1.10276338+0.j, 0.4618274 +0.j, 0.4618274 +0.j,\n",
            " 0.9236548 +0.j, 0.46879361+0.j, 0.46879361+0.j, 0.93758721+0.j,\n",
            " 0.73183138+0.j, 0.73183138+0.j, 1.46366276+0.j, 0.64586252+0.j,\n",
            " 0.64586252+0.j, 1.29172504+0.j, 0.53402228+0.j, 0.53402228+0.j,\n",
            " 1.06804456+0.j, 0.28551803+0.j, 0.28551803+0.j, 0.57103606+0.j,\n",
            " 0.2601092 +0.j, 0.2601092 +0.j, 0.5202184 +0.j, 0.63907838+0.j,\n",
            " 0.63907838+0.j, 1.27815675+0.j, 0.73930917+0.j, 0.73930917+0.j,\n",
            " 1.47861834+0.j, 0.48073968+0.j, 0.48073968+0.j, 0.96147936+0.j,\n",
            " 0.30913721+0.j, 0.30913721+0.j, 0.61827443+0.j, 0.32167664+0.j,\n",
            " 0.32167664+0.j, 0.64335329+0.j, 0.51092416+0.j, 0.51092416+0.j,\n",
            " 1.02184832+0.j, 0.38227781+0.j, 0.38227781+0.j, 0.76455561+0.j,\n",
            " 0.47807517+0.j, 0.47807517+0.j, 0.95615033+0.j, 0.2593949 +0.j,\n",
            " 0.2593949 +0.j, 0.5187898 +0.j, 0.55604786+0.j, 0.55604786+0.j,\n",
            " 1.11209572+0.j, 0.72187404+0.j, 0.72187404+0.j, 1.44374808+0.j,\n",
            " 0.42975395+0.j, 0.42975395+0.j, 0.8595079 +0.j, 0.5988156 +0.j,\n",
            " 0.5988156 +0.j, 1.1976312 +0.j, 0.58338336+0.j, 0.58338336+0.j,\n",
            " 1.16676672+0.j, 0.35519128+0.j, 0.35519128+0.j, 0.71038256+0.j,\n",
            " 0.40771418+0.j, 0.40771418+0.j, 0.81542835+0.j, 0.60759468+0.j,\n",
            " 0.60759468+0.j, 1.21518937+0.j, 0.52244159+0.j, 0.52244159+0.j,\n",
            " 1.04488318+0.j, 0.57294706+0.j, 0.57294706+0.j, 1.14589411+0.j,\n",
            " 0.6958865 +0.j, 0.6958865 +0.j, 1.391773  +0.j, 0.44172076+0.j,\n",
            " 0.44172076+0.j, 0.88344152+0.j, 0.51444746+0.j, 0.51444746+0.j,\n",
            " 1.02889492+0.j, 0.71279832+0.j, 0.71279832+0.j, 1.42559664+0.j,\n",
            " 0.29356465+0.j, 0.29356465+0.j, 0.5871293 +0.j, 0.66630992+0.j,\n",
            " 0.66630992+0.j, 1.33261985+0.j, 0.68500607+0.j, 0.68500607+0.j,\n",
            " 1.37001215+0.j, 0.64957928+0.j, 0.64957928+0.j, 1.29915856+0.j,\n",
            " 0.64026459+0.j, 0.64026459+0.j, 1.28052918+0.j, 0.56996051+0.j,\n",
            " 0.56996051+0.j, 1.13992102+0.j, 0.72233446+0.j, 0.72233446+0.j,\n",
            " 1.44466892+0.j, 0.45733097+0.j, 0.45733097+0.j, 0.91466194+0.j,\n",
            " 0.63711684+0.j, 0.63711684+0.j, 1.27423369+0.j, 0.53421697+0.j,\n",
            " 0.53421697+0.j, 1.06843395+0.j, 0.55881775+0.j, 0.55881775+0.j,\n",
            " 1.1176355 +0.j, 0.558467  +0.j, 0.558467  +0.j, 1.116934  +0.j,\n",
            " 0.59091015+0.j, 0.59091015+0.j, 1.1818203 +0.j, 0.46851598+0.j,\n",
            " 0.46851598+0.j, 0.93703195+0.j, 0.28011274+0.j, 0.28011274+0.j,\n",
            " 0.56022547+0.j, 0.58531893+0.j, 0.58531893+0.j, 1.17063787+0.j,\n",
            " 0.31446315+0.j, 0.31446315+0.j, 0.6289263 +0.j])\n",
            "Observable: SparsePauliOp(['IIIIIIIIIIIIIIIIIIIIIIIIZZIIIIIIIIIIIIIIIIIIIIIIII'],\n",
            "              coeffs=[1.+0.j])\n",
            "Target MPS maximum bond dimension: 5\n",
            "Number of AQC parameters: 816\n",
            "Starting fidelity of AQC portion: 0.9914382555614002\n",
            "2024-12-17 14:52:23.400028 Intermediate result: Fidelity 0.99764093\n",
            "2024-12-17 14:52:23.429669 Intermediate result: Fidelity 0.99788003\n",
            "2024-12-17 14:52:23.459674 Intermediate result: Fidelity 0.99795970\n",
            "2024-12-17 14:52:23.489666 Intermediate result: Fidelity 0.99799067\n",
            "2024-12-17 14:52:23.518545 Intermediate result: Fidelity 0.99803401\n",
            "2024-12-17 14:52:23.546952 Intermediate result: Fidelity 0.99809821\n",
            "2024-12-17 14:52:23.575271 Intermediate result: Fidelity 0.99824660\n",
            "2024-12-17 14:52:23.604049 Intermediate result: Fidelity 0.99845326\n",
            "2024-12-17 14:52:23.632709 Intermediate result: Fidelity 0.99870497\n",
            "2024-12-17 14:52:23.660527 Intermediate result: Fidelity 0.99891442\n",
            "2024-12-17 14:52:23.688273 Intermediate result: Fidelity 0.99904488\n",
            "2024-12-17 14:52:23.716105 Intermediate result: Fidelity 0.99914438\n",
            "2024-12-17 14:52:23.744336 Intermediate result: Fidelity 0.99922827\n",
            "2024-12-17 14:52:23.773399 Intermediate result: Fidelity 0.99929071\n",
            "2024-12-17 14:52:23.801482 Intermediate result: Fidelity 0.99932432\n",
            "2024-12-17 14:52:23.830466 Intermediate result: Fidelity 0.99936460\n",
            "2024-12-17 14:52:23.860738 Intermediate result: Fidelity 0.99938891\n",
            "2024-12-17 14:52:23.889958 Intermediate result: Fidelity 0.99940607\n",
            "2024-12-17 14:52:23.918703 Intermediate result: Fidelity 0.99941965\n",
            "2024-12-17 14:52:23.949744 Intermediate result: Fidelity 0.99944337\n",
            "2024-12-17 14:52:23.980871 Intermediate result: Fidelity 0.99946875\n",
            "2024-12-17 14:52:24.012124 Intermediate result: Fidelity 0.99949009\n",
            "2024-12-17 14:52:24.044359 Intermediate result: Fidelity 0.99952191\n",
            "2024-12-17 14:52:24.075840 Intermediate result: Fidelity 0.99953669\n",
            "2024-12-17 14:52:24.106303 Intermediate result: Fidelity 0.99955242\n",
            "2024-12-17 14:52:24.139329 Intermediate result: Fidelity 0.99958412\n",
            "2024-12-17 14:52:24.169725 Intermediate result: Fidelity 0.99960176\n",
            "2024-12-17 14:52:24.198749 Intermediate result: Fidelity 0.99961606\n",
            "2024-12-17 14:52:24.227874 Intermediate result: Fidelity 0.99963811\n",
            "2024-12-17 14:52:24.256818 Intermediate result: Fidelity 0.99964383\n",
            "2024-12-17 14:52:24.285889 Intermediate result: Fidelity 0.99964717\n",
            "2024-12-17 14:52:24.315228 Intermediate result: Fidelity 0.99966064\n",
            "2024-12-17 14:52:24.345322 Intermediate result: Fidelity 0.99966517\n",
            "2024-12-17 14:52:24.374921 Intermediate result: Fidelity 0.99967089\n",
            "2024-12-17 14:52:24.404309 Intermediate result: Fidelity 0.99968305\n",
            "2024-12-17 14:52:24.432664 Intermediate result: Fidelity 0.99968889\n",
            "2024-12-17 14:52:24.461639 Intermediate result: Fidelity 0.99969997\n",
            "2024-12-17 14:52:24.491244 Intermediate result: Fidelity 0.99971666\n",
            "2024-12-17 14:52:24.520354 Intermediate result: Fidelity 0.99972441\n",
            "2024-12-17 14:52:24.549965 Intermediate result: Fidelity 0.99973561\n",
            "2024-12-17 14:52:24.583464 Intermediate result: Fidelity 0.99973811\n",
            "2024-12-17 14:52:24.617537 Intermediate result: Fidelity 0.99974074\n",
            "2024-12-17 14:52:24.652247 Intermediate result: Fidelity 0.99974467\n",
            "2024-12-17 14:52:24.686831 Intermediate result: Fidelity 0.99974991\n",
            "2024-12-17 14:52:24.725476 Intermediate result: Fidelity 0.99975230\n",
            "2024-12-17 14:52:24.764637 Intermediate result: Fidelity 0.99975373\n",
            "2024-12-17 14:52:24.802499 Intermediate result: Fidelity 0.99975552\n",
            "2024-12-17 14:52:24.839960 Intermediate result: Fidelity 0.99975885\n",
            "2024-12-17 14:52:24.877472 Intermediate result: Fidelity 0.99976469\n",
            "2024-12-17 14:52:24.916233 Intermediate result: Fidelity 0.99976517\n",
            "2024-12-17 14:52:24.993750 Intermediate result: Fidelity 0.99976875\n",
            "2024-12-17 14:52:25.034953 Intermediate result: Fidelity 0.99976887\n",
            "2024-12-17 14:52:25.076197 Intermediate result: Fidelity 0.99977244\n",
            "2024-12-17 14:52:25.112340 Intermediate result: Fidelity 0.99977638\n",
            "2024-12-17 14:52:25.149947 Intermediate result: Fidelity 0.99977828\n",
            "2024-12-17 14:52:25.190049 Intermediate result: Fidelity 0.99978174\n",
            "2024-12-17 14:52:25.310903 Intermediate result: Fidelity 0.99978222\n",
            "2024-12-17 14:52:25.347512 Intermediate result: Fidelity 0.99978508\n",
            "2024-12-17 14:52:25.385201 Intermediate result: Fidelity 0.99978543\n",
            "2024-12-17 14:52:25.457436 Intermediate result: Fidelity 0.99978770\n",
            "2024-12-17 14:52:25.497133 Intermediate result: Fidelity 0.99978818\n",
            "2024-12-17 14:52:25.541179 Intermediate result: Fidelity 0.99978913\n",
            "2024-12-17 14:52:25.584791 Intermediate result: Fidelity 0.99978937\n",
            "2024-12-17 14:52:25.621484 Intermediate result: Fidelity 0.99979068\n",
            "2024-12-17 14:52:25.655847 Intermediate result: Fidelity 0.99979211\n",
            "2024-12-17 14:52:25.691710 Intermediate result: Fidelity 0.99979700\n",
            "2024-12-17 14:52:25.767711 Intermediate result: Fidelity 0.99979759\n",
            "2024-12-17 14:52:25.804517 Intermediate result: Fidelity 0.99979807\n",
            "2024-12-17 14:52:25.839394 Intermediate result: Fidelity 0.99980236\n",
            "2024-12-17 14:52:25.874438 Intermediate result: Fidelity 0.99980296\n",
            "2024-12-17 14:52:25.909900 Intermediate result: Fidelity 0.99980320\n",
            "2024-12-17 14:52:26.713044 Intermediate result: Fidelity 0.99980320\n",
            "Done after 72 iterations.\n",
            "Fidelity of AQC portion: 0.9998108844412502\n",
            "ISA circuit two-qubit depth: 33\n",
            "Exiting before hardware execution since `dry_run` is True.\n",
            "\n"
          ]
        }
      ],
      "source": [
        "print(job.logs())"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "196d6261-e26b-4057-ae55-19f003fdc10a",
      "metadata": {},
      "source": [
        "<span id=\"next-steps\" />\n",
        "\n",
        "## Nächste Schritte\n",
        "\n",
        "<Admonition type=\"info\" title=\"Empfehlungen\">\n",
        "  Für einen tieferen Einblick in das AQC-Tensor Qiskit Addon, schauen Sie sich das [Improved Trotterized Time Evolution with Approximate Quantum Compilation](/docs/tutorials/approximate-quantum-compilation-for-time-evolution) Tutorial oder das [qiskit-addon-aqc-tensor Repository](https://github.com/Qiskit/qiskit-addon-aqc-tensor) an.\n",
        "</Admonition>\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "20502fe4-7940-40fa-a978-64cc3ff6c1b1",
      "metadata": {
        "tags": [
          "id-full-source"
        ]
      },
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "Overwriting ./source_files/template_hamiltonian_simulation_full.py\n"
          ]
        }
      ],
      "source": [
        "%%writefile ./source_files/template_hamiltonian_simulation_full.py\n",
        "\n",
        "from qiskit import QuantumCircuit\n",
        "from qiskit_serverless import get_arguments, save_result\n",
        "\n",
        "\n",
        "# Extract parameters from arguments\n",
        "#\n",
        "# Do this at the top of the program so it fails early\n",
        "# if any required arguments are missing or invalid.\n",
        "\n",
        "arguments = get_arguments()\n",
        "\n",
        "dry_run = arguments.get(\"dry_run\", False)\n",
        "backend_name = arguments[\"backend_name\"]\n",
        "\n",
        "aqc_evolution_time = arguments[\"aqc_evolution_time\"]\n",
        "aqc_ansatz_num_trotter_steps = arguments[\"aqc_ansatz_num_trotter_steps\"]\n",
        "aqc_target_num_trotter_steps = arguments[\"aqc_target_num_trotter_steps\"]\n",
        "\n",
        "remainder_evolution_time = arguments[\"remainder_evolution_time\"]\n",
        "remainder_num_trotter_steps = arguments[\"remainder_num_trotter_steps\"]\n",
        "\n",
        "# Stop if this fidelity is achieved\n",
        "aqc_stopping_fidelity = arguments.get(\"aqc_stopping_fidelity\", 1.0)\n",
        "# Stop after this number of iterations, even if stopping fidelity is not achieved\n",
        "aqc_max_iterations = arguments.get(\"aqc_max_iterations\", 500)\n",
        "\n",
        "hamiltonian = arguments[\"hamiltonian\"]\n",
        "observable = arguments[\"observable\"]\n",
        "initial_state = arguments.get(\"initial_state\", QuantumCircuit(hamiltonian.num_qubits))\n",
        "\n",
        "import numpy as np\n",
        "import json\n",
        "from mergedeep import merge\n",
        "\n",
        "\n",
        "# Configure `EstimatorOptions` to control the hardware experiment's parameters\n",
        "#\n",
        "# Set default options\n",
        "estimator_default_options = {\n",
        "    \"resilience\": {\n",
        "        \"measure_mitigation\": True,\n",
        "        \"zne_mitigation\": True,\n",
        "        \"zne\": {\n",
        "            \"amplifier\": \"gate_folding\",\n",
        "            \"noise_factors\": [1, 2, 3],\n",
        "            \"extrapolated_noise_factors\": list(np.linspace(0, 3, 31)),\n",
        "            \"extrapolator\": [\"exponential\", \"linear\", \"fallback\"],\n",
        "        },\n",
        "        \"measure_noise_learning\": {\n",
        "            \"num_randomizations\": 512,\n",
        "            \"shots_per_randomization\": 512,\n",
        "        },\n",
        "    },\n",
        "    \"twirling\": {\n",
        "        \"enable_gates\": True,\n",
        "        \"enable_measure\": True,\n",
        "        \"num_randomizations\": 300,\n",
        "        \"shots_per_randomization\": 100,\n",
        "        \"strategy\": \"active\",\n",
        "    },\n",
        "}\n",
        "# Merge with user-provided options\n",
        "estimator_options = merge(\n",
        "    arguments.get(\"estimator_options\", {}), estimator_default_options\n",
        ")\n",
        "\n",
        "print(\"estimator_options =\", json.dumps(estimator_options, indent=4))\n",
        "\n",
        "# Perform parameter validation\n",
        "\n",
        "if not 0.0 < aqc_stopping_fidelity <= 1.0:\n",
        "    raise ValueError(\n",
        "        f\"Invalid stopping fidelity: {aqc_stopping_fidelity}.  \"\n",
        "        It must be a positive float no greater than 1.\"\n",
        "    )\n",
        "\n",
        "output = {}\n",
        "\n",
        "import os\n",
        "os.environ[\"NUMBA_CACHE_DIR\"] = \"/data\"\n",
        "\n",
        "import datetime\n",
        "import quimb.tensor\n",
        "from scipy.optimize import OptimizeResult, minimize\n",
        "from qiskit.synthesis import SuzukiTrotter\n",
        "from qiskit_addon_utils.problem_generators import generate_time_evolution_circuit\n",
        "from qiskit_addon_aqc_tensor.ansatz_generation import (\n",
        "    generate_ansatz_from_circuit,\n",
        "    AnsatzBlock,\n",
        ")\n",
        "from qiskit_addon_aqc_tensor.simulation import (\n",
        "    tensornetwork_from_circuit,\n",
        "    compute_overlap,\n",
        ")\n",
        "from qiskit_addon_aqc_tensor.simulation.quimb import QuimbSimulator\n",
        "from qiskit_addon_aqc_tensor.objective import OneMinusFidelity\n",
        "\n",
        "print(\"Hamiltonian:\", hamiltonian)\n",
        "print(\"Observable:\", observable)\n",
        "simulator_settings = QuimbSimulator(quimb.tensor.CircuitMPS, autodiff_backend=\"jax\")\n",
        "\n",
        "# Construct the AQC target circuit\n",
        "aqc_target_circuit = initial_state.copy()\n",
        "if aqc_evolution_time:\n",
        "    aqc_target_circuit.compose(\n",
        "        generate_time_evolution_circuit(\n",
        "            hamiltonian,\n",
        "            synthesis=SuzukiTrotter(reps=aqc_target_num_trotter_steps),\n",
        "            time=aqc_evolution_time,\n",
        "        ),\n",
        "        inplace=True,\n",
        "    )\n",
        "\n",
        "# Construct matrix-product state representation of the AQC target state\n",
        "aqc_target_mps = tensornetwork_from_circuit(aqc_target_circuit, simulator_settings)\n",
        "print(\"Target MPS maximum bond dimension:\", aqc_target_mps.psi.max_bond())\n",
        "output[\"target_bond_dimension\"] = aqc_target_mps.psi.max_bond()\n",
        "\n",
        "# Generate an ansatz and initial parameters from a Trotter circuit with fewer steps\n",
        "aqc_good_circuit = initial_state.copy()\n",
        "if aqc_evolution_time:\n",
        "    aqc_good_circuit.compose(\n",
        "        generate_time_evolution_circuit(\n",
        "            hamiltonian,\n",
        "            synthesis=SuzukiTrotter(reps=aqc_ansatz_num_trotter_steps),\n",
        "            time=aqc_evolution_time,\n",
        "        ),\n",
        "        inplace=True,\n",
        "    )\n",
        "aqc_ansatz, aqc_initial_parameters = generate_ansatz_from_circuit(aqc_good_circuit)\n",
        "print(\"Number of AQC parameters:\", len(aqc_initial_parameters))\n",
        "output[\"num_aqc_parameters\"] = len(aqc_initial_parameters)\n",
        "\n",
        "# Calculate the fidelity of ansatz circuit vs. the target state, before optimization\n",
        "good_mps = tensornetwork_from_circuit(aqc_good_circuit, simulator_settings)\n",
        "starting_fidelity = abs(compute_overlap(good_mps, aqc_target_mps)) ** 2\n",
        "print(\"Starting fidelity of AQC portion:\", starting_fidelity)\n",
        "output[\"aqc_starting_fidelity\"] = starting_fidelity\n",
        "\n",
        "# Optimize the ansatz parameters by using MPS calculations\n",
        "def callback(intermediate_result: OptimizeResult):\n",
        "    fidelity = 1 - intermediate_result.fun\n",
        "    print(f\"{datetime.datetime.now()} Intermediate result: Fidelity {fidelity:.8f}\")\n",
        "    if intermediate_result.fun < stopping_point:\n",
        "        raise StopIteration\n",
        "\n",
        "\n",
        "objective = OneMinusFidelity(aqc_target_mps, aqc_ansatz, simulator_settings)\n",
        "stopping_point = 1.0 - aqc_stopping_fidelity\n",
        "\n",
        "result = minimize(\n",
        "    objective,\n",
        "    aqc_initial_parameters,\n",
        "    method=\"L-BFGS-B\",\n",
        "    jac=True,\n",
        "    options={\"maxiter\": aqc_max_iterations},\n",
        "    callback=callback,\n",
        ")\n",
        "if result.status not in (\n",
        "    0,\n",
        "    1,\n",
        "    99,\n",
        "):  # 0 => success; 1 => max iterations reached; 99 => early termination via StopIteration\n",
        "    raise RuntimeError(\n",
        "        f\"Optimization failed: {result.message} (status={result.status})\"\n",
        "    )\n",
        "print(f\"Done after {result.nit} iterations.\")\n",
        "output[\"num_iterations\"] = result.nit\n",
        "aqc_final_parameters = result.x\n",
        "output[\"aqc_final_parameters\"] = list(aqc_final_parameters)\n",
        "\n",
        "# Construct an optimized circuit for initial portion of time evolution\n",
        "aqc_final_circuit = aqc_ansatz.assign_parameters(aqc_final_parameters)\n",
        "\n",
        "# Calculate fidelity after optimization\n",
        "aqc_final_mps = tensornetwork_from_circuit(aqc_final_circuit, simulator_settings)\n",
        "aqc_fidelity = abs(compute_overlap(aqc_final_mps, aqc_target_mps)) ** 2\n",
        "print(\"Fidelity of AQC portion:\", aqc_fidelity)\n",
        "output[\"aqc_fidelity\"] = aqc_fidelity\n",
        "\n",
        "# Construct final circuit, with remainder of time evolution\n",
        "final_circuit = aqc_final_circuit.copy()\n",
        "if remainder_evolution_time:\n",
        "    remainder_circuit = generate_time_evolution_circuit(\n",
        "        hamiltonian,\n",
        "        synthesis=SuzukiTrotter(reps=remainder_num_trotter_steps),\n",
        "        time=remainder_evolution_time,\n",
        "    )\n",
        "    final_circuit.compose(remainder_circuit, inplace=True)\n",
        "\n",
        "from qiskit.transpiler import generate_preset_pass_manager\n",
        "from qiskit_ibm_catalog import QiskitFunctionsCatalog\n",
        "from qiskit_serverless import get_runtime_service\n",
        "\n",
        "service = get_runtime_service()\n",
        "backend = service.backend(backend_name)\n",
        "\n",
        "# Transpile PUBs (circuits and observables) to match ISA\n",
        "pass_manager = generate_preset_pass_manager(backend=backend, optimization_level=3)\n",
        "isa_circuit = pass_manager.run(final_circuit)\n",
        "isa_observable = observable.apply_layout(isa_circuit.layout)\n",
        "\n",
        "isa_2qubit_depth = isa_circuit.depth(lambda x: x.operation.num_qubits == 2)\n",
        "print(\"ISA circuit two-qubit depth:\", isa_2qubit_depth)\n",
        "output[\"twoqubit_depth\"] = isa_2qubit_depth\n",
        "\n",
        "# Exit now if dry run; don't execute on hardware\n",
        "if dry_run:\n",
        "    import sys\n",
        "\n",
        "    print(\"Exiting before hardware execution since `dry_run` is True.\")\n",
        "    save_result(output)\n",
        "    sys.exit(0)\n",
        "\n",
        "# ## Step 3: Execute quantum experiments on backend\n",
        "from qiskit_ibm_runtime import EstimatorV2 as Estimator\n",
        "\n",
        "\n",
        "estimator = Estimator(backend, options=estimator_options)\n",
        "\n",
        "# Submit the underlying Estimator job. Note that this is not the\n",
        "# actual function job.\n",
        "job = estimator.run([(isa_circuit, isa_observable)])\n",
        "print(\"Job ID:\", job.job_id())\n",
        "output[\"job_id\"] = job.job_id()\n",
        "\n",
        "# Wait until job is complete\n",
        "hw_results = job.result()\n",
        "hw_results_dicts = [pub_result.data.__dict__ for pub_result in hw_results]\n",
        "\n",
        "# Save hardware results to serverless output dictionary\n",
        "output[\"hw_results\"] = hw_results_dicts\n",
        "\n",
        "# Reorganize expectation values\n",
        "hw_expvals = [pub_result_data[\"evs\"].tolist()\n",
        "    for pub_result_data in hw_results_dicts]\n",
        "\n",
        "# Save expectation values to Qiskit Serverless\n",
        "output[\"hw_expvals\"] = hw_expvals[0]\n",
        "\n",
        "save_result(output)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "d7f1776a-a8f6-43a3-85b7-33975c4eeec0",
      "metadata": {},
      "source": [
        "<Accordion>\n",
        "  <AccordionItem title=\"**Vollständiger Programmquellcode**\">\n",
        "    Hier ist der gesamte Quelltext von `./source_files/template_hamiltonian_simulation.py` als ein Codeblock.\n",
        "\n",
        "    <CodeCellPlaceholder tag=\"id-full-source\" />\n",
        "  </AccordionItem>\n",
        "</Accordion>\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
}