{
  "cells": [
    {
      "cell_type": "markdown",
      "id": "frontmatter",
      "metadata": {},
      "source": [
        "---\n",
        "title: \"Begrenzung der Dimension des Unterraums\"\n",
        "description: \"Einschätzung der Dimension des Unterraums für die neueste Version der samplebasierten Quantendiagonalisierung (SQD)\"\n",
        "---\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "9e40af77-7f0f-4dd6-ab0a-420cf396050e",
      "metadata": {},
      "source": [
        "<span id=\"bounding-the-subspace-dimension\" />\n",
        "\n",
        "# Begrenzung der Dimension des Unterraums\n",
        "\n",
        "In dieser Anleitung werden wir die Auswirkungen der Unterraumdimension bei der [Technik zur](https://arxiv.org/abs/2405.05068) selbstkonsistenten Konfigurationswiederherstellung veranschaulichen.\n",
        "\n",
        "*A priori* wissen wir nicht, welche Unterraumdimension erforderlich ist, um ein angestrebtes Genauigkeitsniveau zu erreichen. Wir wissen jedoch, dass eine Erhöhung der Unterraumdimension die Genauigkeit der Methode verbessert. Daher können wir die Genauigkeit der Vorhersagen in Abhängigkeit von der Dimension des Unterraums untersuchen.\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "a6755afb-ca1e-4473-974b-ba89acc8abce",
      "metadata": {},
      "source": [
        "Geben Sie das Molekül und seine Eigenschaften an.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 1,
      "id": "677f54ac-b4ed-47e3-b5ba-5366d3a520f9",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "converged SCF energy = -108.835236570775\n",
            "CASCI E = -109.046671778080  E(CI) = -32.8155692383188  S^2 = 0.0000000\n"
          ]
        }
      ],
      "source": [
        "import warnings\n",
        "\n",
        "import pyscf\n",
        "import pyscf.cc\n",
        "import pyscf.mcscf\n",
        "\n",
        "warnings.filterwarnings(\"ignore\")\n",
        "\n",
        "# Specify molecule properties\n",
        "open_shell = False\n",
        "spin_sq = 0\n",
        "\n",
        "# Build N2 molecule\n",
        "mol = pyscf.gto.Mole()\n",
        "mol.build(\n",
        "    atom=[[\"N\", (0, 0, 0)], [\"N\", (1.0, 0, 0)]],\n",
        "    basis=\"6-31g\",\n",
        "    symmetry=\"Dooh\",\n",
        ")\n",
        "\n",
        "# Define active space\n",
        "n_frozen = 2\n",
        "active_space = range(n_frozen, mol.nao_nr())\n",
        "\n",
        "# Get molecular integrals\n",
        "scf = pyscf.scf.RHF(mol).run()\n",
        "num_orbitals = len(active_space)\n",
        "n_electrons = int(sum(scf.mo_occ[active_space]))\n",
        "num_elec_a = (n_electrons + mol.spin) // 2\n",
        "num_elec_b = (n_electrons - mol.spin) // 2\n",
        "cas = pyscf.mcscf.CASCI(scf, num_orbitals, (num_elec_a, num_elec_b))\n",
        "mo = cas.sort_mo(active_space, base=0)\n",
        "hcore, nuclear_repulsion_energy = cas.get_h1cas(mo)\n",
        "eri = pyscf.ao2mo.restore(1, cas.get_h2cas(mo), num_orbitals)\n",
        "\n",
        "# Compute exact energy\n",
        "exact_energy = cas.run().e_tot"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "c58e988c-a109-44cd-a975-9df43250c318",
      "metadata": {},
      "source": [
        "Erzeuge einige zufällige Bitfolgen, um QPU-Samples zu simulieren.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 2,
      "id": "e9506e0b-ed64-48bb-a97a-ef851b604af1",
      "metadata": {},
      "outputs": [],
      "source": [
        "import numpy as np\n",
        "from qiskit_addon_sqd.counts import generate_bit_array_uniform\n",
        "\n",
        "# Create a seed to control randomness throughout this workflow\n",
        "rng = np.random.default_rng(24)\n",
        "\n",
        "# Generate random samples\n",
        "bit_array = generate_bit_array_uniform(\n",
        "    10_000, num_orbitals * 2, rand_seed=rng\n",
        ")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "82b062a3-d4ca-41e2-9b00-4a394f83cbdd",
      "metadata": {},
      "source": [
        "Rufen Sie SQD bei steigenden Losgrößen auf.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 3,
      "id": "e0847f28",
      "metadata": {},
      "outputs": [],
      "source": [
        "from qiskit_addon_sqd.fermion import diagonalize_fermionic_hamiltonian\n",
        "\n",
        "list_samples_per_batch = [50, 200, 400, 600]\n",
        "\n",
        "# SQD options\n",
        "max_iterations = 5\n",
        "\n",
        "# Eigenstate solver options\n",
        "num_batches = 10\n",
        "max_davidson_cycles = 200\n",
        "\n",
        "energies = []\n",
        "subspace_dimensions = []\n",
        "\n",
        "for samples_per_batch in list_samples_per_batch:\n",
        "    result = diagonalize_fermionic_hamiltonian(\n",
        "        hcore,\n",
        "        eri,\n",
        "        bit_array,\n",
        "        samples_per_batch=samples_per_batch,\n",
        "        norb=num_orbitals,\n",
        "        nelec=(num_elec_a, num_elec_b),\n",
        "        num_batches=num_batches,\n",
        "        max_iterations=max_iterations,\n",
        "        symmetrize_spin=True,\n",
        "        seed=rng,\n",
        "    )\n",
        "    energies.append(result.energy)\n",
        "    subspace_dimensions.append(np.prod(result.sci_state.amplitudes.shape))"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "9d78906b-4759-4506-9c69-85d4e67766b3",
      "metadata": {},
      "source": [
        "Diese Grafik zeigt, dass eine Erhöhung der Unterraumdimension zu genaueren Ergebnissen führt.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 4,
      "id": "caffd888-e89c-4aa9-8bae-4d1bb723b35e",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "<Image src=\"/docs/images/addons/qiskit-addon-sqd/guides/choose-subspace-dimension/extracted-outputs/caffd888-e89c-4aa9-8bae-4d1bb723b35e-0.avif\" alt=\"Output of the previous code cell\" />"
            ]
          },
          "metadata": {},
          "output_type": "display_data"
        }
      ],
      "source": [
        "import matplotlib.pyplot as plt\n",
        "\n",
        "# Data for energies plot\n",
        "x1 = subspace_dimensions\n",
        "y1 = np.array(energies) + nuclear_repulsion_energy\n",
        "\n",
        "fig, axs = plt.subplots(1, 1, figsize=(12, 6))\n",
        "\n",
        "# Plot energies\n",
        "axs.plot(x1, y1, marker=\".\", markersize=20, label=\"Estimated\")\n",
        "axs.set_xticks(x1)\n",
        "axs.set_xticklabels(x1)\n",
        "axs.axhline(y=exact_energy, color=\"red\", linestyle=\"--\", label=\"Exact\")\n",
        "axs.set_title(\"Approximated Ground State Energy vs subspace dimension\")\n",
        "axs.set_xlabel(\"Subspace dimension\")\n",
        "axs.set_ylabel(\"Energy (Ha)\")\n",
        "axs.legend()\n",
        "\n",
        "\n",
        "plt.tight_layout()\n",
        "plt.show()"
      ]
    },
    {
      "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": 5
}