{
  "cells": [
    {
      "cell_type": "markdown",
      "id": "frontmatter",
      "metadata": {},
      "source": [
        "---\n",
        "title: \"Die Unterschiede zwischen Optionen mit offener und geschlossener Schale sowie deren Auswirkungen auf die Konstruktion von Unterräumen verstehen\"\n",
        "description: \"Verstehen Sie den Unterschied zwischen Optionen mit offener und geschlossener Schale sowie deren Auswirkungen auf die Unterraumkonstruktion für die neueste Version der samplebasierten Quantendiagonalisierung (SQD)\"\n",
        "---\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "72420c62-2716-4f64-ad5b-73394b481cc1",
      "metadata": {},
      "source": [
        "<span id=\"understand-open-shell-versus-closed-shell-options-and-the-effect-on-subspace-construction\" />\n",
        "\n",
        "# Die Unterschiede zwischen Optionen mit offener und geschlossener Schale sowie deren Auswirkungen auf die Konstruktion von Unterräumen verstehen\n",
        "\n",
        "In dieser Anleitung zeigen wir, wie man im `qiskit_addon_sqd` Paket die Dimensionen des Unterraums auswählt, um Quantenproben mithilfe der [selbstkonsistenten Konfigurationswiederherstellungstechnik](https://arxiv.org/abs/2405.05068) nachzubearbeiten.\n",
        "\n",
        "Noch wichtiger ist, dass dieser Leitfaden auch einige Unterschiede im Verhalten bei der Unterraumkonstruktion hervorhebt, wenn diese im `open_shell = False` oder `open_shell = True` Modus ausgeführt wird:\n",
        "\n",
        "* `open_shell = False` funktioniert nur, wenn die Anzahl der Elektronen im Spin-up- und Spin-down-Zustand gleich ist.\n",
        "\n",
        "* `open_shell = True` muss verwendet werden, wenn die Anzahl der Elektronen im Spin-up- und Spin-down-Zustand unterschiedlich ist. Es kann auch angewendet werden, wenn die Anzahl der Elektronen im Spin-up- und im Spin-down-Zustand gleich ist. `open_shell = True`Im letztgenannten Fall besteht jedoch ein Unterschied in der Größe der zwischen `open_shell = False` und erzeugten Unterräume, wie in diesem Leitfaden erläutert wird.\n",
        "\n",
        "**HINWEIS:** Einige der in diesem Paket enthaltenen Manipulationen der elektronischen Konfiguration (Bitfolge) zielen darauf ab, die Gesamtspinsymmetrie $S^2$ zu bewahren. Standardmäßige SCI-Löser (Selected Configuration Interaction) können die Erhaltung von $S^2$ nicht exakt gewährleisten. Folglich tun sie dies im Wesentlichen mithilfe eines Lagrange-Multiplikators.\n",
        "\n",
        "Die Wahl der elektronischen Konfigurationen, die in den Eigenzustandslöser eingegeben werden, kann ebenfalls einen starken Einfluss auf die Spin-Erhaltung haben. Beispielsweise kann man in einem (2-Elektronen-, 2-Orbital-)System die Konfiguration $|1001\\rangle$ abtasten (mit einer einzelnen Spin-up-Anregung über dem RHF-Zustand $|0101\\rangle$ ), die eine Linearkombination der Singulett- bzw. Triplett-Zustände der offenen Schale ist $(|1001\\rangle ± |0110\\rangle) /\\sqrt{2}$. Wird die Konfiguration |0110⟩ nicht berücksichtigt, lässt sich keine Eigenfunktion des Gesamtspins konstruieren, was zu einer Spinverunreinigung oder Redundanz führt (die Konfiguration |1001⟩ ist zwar in einer CI-Berechnung enthalten, hat jedoch im CI-Vektor den Koeffizienten 0). Da im Quantencomputer ein einzelnes Beispiel $|1001\\rangle$ generiert wird, geht das `sqd` Paket wie folgt mit dieser Situation um:\n",
        "\n",
        "* `open_shell = False`:\n",
        "\n",
        "  1. Die Bitfolge „ $1001$ “ wird in zwei Hälften geteilt, die die Konfigurationen „Spin-up“ und „Spin-down“ darstellen: „ $10$ “ (up) und „ $01$ “ (down).\n",
        "\n",
        "  2. Die Liste der eindeutigen spinpolarisierten Konfigurationen wurde erstellt: $\\mathcal{U} = [01, 10]$.\n",
        "\n",
        "  3. Anschließend betrachten wir alle möglichen Kombinationen der Elemente „ $\\mathcal{U}$ “, um die Basis zu bilden: „ $\\left \\{ |0101\\rangle, |0110\\rangle , |1001\\rangle , |1010\\rangle \\right \\}$ “, die den Singulett- und den Triplettzustand enthält.\n",
        "\n",
        "* `open_shell = True`:\n",
        "\n",
        "  1. Im Gegensatz zu diesem `open_shell = False` Fall fügen wir die beiden Hälften der Bitfolge nicht zu einer Basis zusammen.\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "a6755afb-ca1e-4473-974b-ba89acc8abce",
      "metadata": {},
      "source": [
        "<span id=\"closed-shell\" />\n",
        "\n",
        "### Geschlossene Schale\n",
        "\n",
        "Dieses Beispiel veranschaulicht, wie die Bitfolgen in einem System mit zwei Elektronen und vier Orbitalen bearbeitet werden.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 1,
      "id": "677f54ac-b4ed-47e3-b5ba-5366d3a520f9",
      "metadata": {},
      "outputs": [],
      "source": [
        "# Specify molecule properties\n",
        "num_orbitals = 4\n",
        "num_elec_a = num_elec_b = 1\n",
        "open_shell = False"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "c58e988c-a109-44cd-a975-9df43250c318",
      "metadata": {},
      "source": [
        "Legen Sie manuell ein Verzeichnis der Messergebnisse fest:\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 2,
      "id": "e9506e0b-ed64-48bb-a97a-ef851b604af1",
      "metadata": {},
      "outputs": [],
      "source": [
        "counts_dict = {\n",
        "    \"00010010\": 1 / 2.0 - 0.01,\n",
        "    \"01001000\": 1 / 2.0 - 0.01,\n",
        "    \"00010001\": 0.02,\n",
        "}"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "851bc98e-9c08-4e78-9472-36301abc11d8",
      "metadata": {},
      "source": [
        "Wandeln Sie die Zählwerte `dict` zur weiteren Verarbeitung in eine Bitstring-Matrix und ein Wahrscheinlichkeits-Array um:\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 3,
      "id": "7a102a7f-aae6-4583-ab82-ae40fcb5496a",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "[[False False False  True False False  True False]\n",
            " [False  True False False  True False False False]\n",
            " [False False False  True False False False  True]]\n",
            "[0.49 0.49 0.02]\n"
          ]
        }
      ],
      "source": [
        "from qiskit_addon_sqd.counts import counts_to_arrays\n",
        "\n",
        "# Convert counts into bitstring and probability arrays\n",
        "bitstring_matrix_full, probs_arr_full = counts_to_arrays(counts_dict)\n",
        "print(bitstring_matrix_full)\n",
        "print(probs_arr_full)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "eb704101-0fe8-4d12-b572-b1d844e35a90",
      "metadata": {},
      "source": [
        "Entnehmen Sie eine Teilstichprobe aus einer einzelnen Charge der Größe zwei:\n",
        "\n",
        "* `n_batches = 1`: Anzahl der Konfigurationssätze, die von den verschiedenen Aufrufen des Eigenzustandslösers verwendet werden\n",
        "* `samples_per_batch = 2`: Anzahl der eindeutigen Konfigurationen, die in jeden Stapel aufgenommen werden sollen\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 4,
      "id": "fe60aee2",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "[[False False False  True False False  True False]\n",
            " [False  True False False  True False False False]]\n"
          ]
        }
      ],
      "source": [
        "from qiskit_addon_sqd.subsampling import postselect_and_subsample\n",
        "\n",
        "n_batches = 1\n",
        "samples_per_batch = 2\n",
        "\n",
        "# seed for random number generator\n",
        "rand_seed = 48\n",
        "\n",
        "# Generate the batches\n",
        "batches = postselect_and_subsample(\n",
        "    bitstring_matrix_full,\n",
        "    probs_arr_full,\n",
        "    hamming_right=num_elec_a,\n",
        "    hamming_left=num_elec_b,\n",
        "    samples_per_batch=samples_per_batch,\n",
        "    num_batches=n_batches,\n",
        "    rand_seed=rand_seed,\n",
        ")\n",
        "\n",
        "print(batches[0])"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "93a6d05a",
      "metadata": {},
      "source": [
        "Ermitteln Sie die Dezimaldarstellung der vom Eigenzustandslöser verwendeten Bitstrings für „Spin-up“ und „Spin-down“.\n",
        "\n",
        "Das erste Element des Tupels entspricht der Dezimaldarstellung der Spin-up-Konfigurationen, während das zweite Element des Tupels der Dezimaldarstellung der Spin-down-Konfigurationen entspricht:\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 5,
      "id": "ef90e039",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "(array([1, 2, 4, 8], dtype=int64), array([1, 2, 4, 8], dtype=int64))\n"
          ]
        }
      ],
      "source": [
        "from qiskit_addon_sqd.fermion import bitstring_matrix_to_ci_strs\n",
        "\n",
        "ci_strs = bitstring_matrix_to_ci_strs(batches[0], open_shell=open_shell)\n",
        "print(ci_strs)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "70d7883c",
      "metadata": {},
      "source": [
        "Beachten Sie, dass zwar die Anzahl der Stichproben pro Charge zwei beträgt und die erfassten Bitstrings wie folgt lauten: $00010010$ und $01001000$, pro Spin-Spezies jedoch vier elektronische Konfigurationen erzeugt werden. In diesem Fall ergibt sich die Menge der eindeutigen spinpolarisierten Konfigurationen wie folgt:\n",
        "\n",
        "$$\n",
        "\\mathcal{U} = \\{ 0001, 0010, 0100, 1000 \\}\n",
        "$$\n",
        "\n",
        "dessen Dezimaldarstellung base-10 lautet\n",
        "\n",
        "$$\n",
        "\\mathcal{U}_{10} = \\{ 1, 2, 4, 8 \\}\n",
        "$$\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "03b32ed5",
      "metadata": {},
      "source": [
        "Basis des Unterraums:\n",
        "\n",
        "Der Eigenzustandslöser berücksichtigt alle möglichen Paare von Bitstrings mit „Spin-up“ und „Spin-down“, um die Basis $\\mathcal{B}$ en des Unterraums zu bilden:\n",
        "\n",
        "* Element 1: $|00010001\\rangle$\n",
        "\n",
        "* Element 2: $|00010010\\rangle$\n",
        "\n",
        "* Element 3: $|00010100\\rangle$\n",
        "\n",
        "* Element 4: $|00011000\\rangle$\n",
        "\n",
        "* Element 5: $|00100001\\rangle$\n",
        "\n",
        "* Element 6: $|00100010\\rangle$\n",
        "\n",
        "* Element 7: $|00100100\\rangle$\n",
        "\n",
        "* Element 8: $|00101000\\rangle$\n",
        "\n",
        "* Element 9: $|01000001\\rangle$\n",
        "\n",
        "* Element 10: $|01000010\\rangle$\n",
        "\n",
        "* Element 11: $|01000100\\rangle$\n",
        "\n",
        "* Element 12: $|01001000\\rangle$\n",
        "\n",
        "* Element 13: $|10000001\\rangle$\n",
        "\n",
        "* Element 14: $|10000010\\rangle$\n",
        "\n",
        "* Element 15: $|10000100\\rangle$\n",
        "\n",
        "* Element 16: $|10001000\\rangle$\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 6,
      "id": "11c924ee",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "Basis elements of the subspace:\n",
            "|00010001>\n",
            "|00010010>\n",
            "|00010100>\n",
            "|00011000>\n",
            "|00100001>\n",
            "|00100010>\n",
            "|00100100>\n",
            "|00101000>\n",
            "|01000001>\n",
            "|01000010>\n",
            "|01000100>\n",
            "|01001000>\n",
            "|10000001>\n",
            "|10000010>\n",
            "|10000100>\n",
            "|10001000>\n"
          ]
        }
      ],
      "source": [
        "ci_strs_up, ci_strs_dn = ci_strs\n",
        "\n",
        "print(\"Basis elements of the subspace:\")\n",
        "\n",
        "for ci_str_up in ci_strs_up:\n",
        "    for ci_str_dn in ci_strs_dn:\n",
        "        format_name = \"{0:0\" + str(num_orbitals) + \"b}\"\n",
        "        print(\n",
        "            \"|\"\n",
        "            + format_name.format(ci_str_up)\n",
        "            + format_name.format(ci_str_dn)\n",
        "            + \">\"\n",
        "        )"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "aa43a4fc",
      "metadata": {},
      "source": [
        "**Die Dimension des Unterraums ist nach oben begrenzt durch** : $2 \\cdot$ (`samples_per_batch`) $^2$.\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "9412e52b",
      "metadata": {},
      "source": [
        "<span id=\"open-shell\" />\n",
        "\n",
        "### Offene Schale\n",
        "\n",
        "Dieses Beispiel veranschaulicht, wie die Bitfolgen in einem System mit zwei Elektronen und vier Orbitalen bearbeitet werden.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 7,
      "id": "9b515b8a",
      "metadata": {},
      "outputs": [],
      "source": [
        "# Specify molecule properties\n",
        "num_orbitals = 4\n",
        "num_elec_a = num_elec_b = 1\n",
        "open_shell = True"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "9ef78560",
      "metadata": {},
      "source": [
        "Legen Sie manuell ein Verzeichnis der Messergebnisse fest:\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 8,
      "id": "06b2185a",
      "metadata": {},
      "outputs": [],
      "source": [
        "counts_dict = {\n",
        "    \"00010010\": 1 / 2.0 - 0.01,\n",
        "    \"01001000\": 1 / 2.0 - 0.01,\n",
        "    \"00010001\": 0.02,\n",
        "}"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "08b32957",
      "metadata": {},
      "source": [
        "Wandeln Sie die Zählwerte `dict` zur weiteren Verarbeitung in eine Bitstring-Matrix und ein Wahrscheinlichkeits-Array um:\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 9,
      "id": "90561893",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "[[False False False  True False False  True False]\n",
            " [False  True False False  True False False False]\n",
            " [False False False  True False False False  True]]\n",
            "[0.49 0.49 0.02]\n"
          ]
        }
      ],
      "source": [
        "# Convert counts into bitstring and probability arrays\n",
        "bitstring_matrix_full, probs_arr_full = counts_to_arrays(counts_dict)\n",
        "print(bitstring_matrix_full)\n",
        "print(probs_arr_full)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "416bfb6c",
      "metadata": {},
      "source": [
        "Entnehmen Sie eine Teilstichprobe aus einer einzelnen Charge der Größe zwei:\n",
        "\n",
        "* `n_batches = 1`: Anzahl der Konfigurationssätze, die von den verschiedenen Aufrufen des Eigenzustandslösers verwendet werden\n",
        "* `samples_per_batch = 2`: Anzahl der eindeutigen Konfigurationen, die in jeden Stapel aufgenommen werden sollen\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 10,
      "id": "cf4fe11d",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "[[False False False  True False False  True False]\n",
            " [False  True False False  True False False False]]\n"
          ]
        }
      ],
      "source": [
        "n_batches = 1\n",
        "samples_per_batch = 2\n",
        "\n",
        "# seed for random number generator\n",
        "rand_seed = 48\n",
        "\n",
        "# Generate the batches\n",
        "batches = postselect_and_subsample(\n",
        "    bitstring_matrix_full,\n",
        "    probs_arr_full,\n",
        "    hamming_right=num_elec_a,\n",
        "    hamming_left=num_elec_b,\n",
        "    samples_per_batch=samples_per_batch,\n",
        "    num_batches=n_batches,\n",
        "    rand_seed=rand_seed,\n",
        ")\n",
        "\n",
        "print(batches[0])"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "54d699ca",
      "metadata": {},
      "source": [
        "Ermitteln Sie die Dezimaldarstellung der vom Eigenzustandslöser verwendeten Bitstrings für „Spin-up“ und „Spin-down“.\n",
        "\n",
        "Das erste Element des Tupels entspricht der Dezimaldarstellung der Spin-up-Konfigurationen, während das zweite Element des Tupels der Dezimaldarstellung der Spin-down-Konfigurationen entspricht:\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 11,
      "id": "b40b049b",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "(array([2, 8], dtype=int64), array([1, 4], dtype=int64))\n"
          ]
        }
      ],
      "source": [
        "ci_strs = bitstring_matrix_to_ci_strs(batches[0], open_shell=open_shell)\n",
        "print(ci_strs)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "28921e56",
      "metadata": {},
      "source": [
        "Wenn wir festlegen, dass `open_shell = True`, werden nicht alle eindeutigen Halbbitstrings als „Spin-up“- und „Spin-down“-Konfigurationen berücksichtigt, was zu einer kleineren Basis führt als bei der Festlegung von `open_shell = False`.\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "e1959b72",
      "metadata": {},
      "source": [
        "Basis des Unterraums:\n",
        "\n",
        "Der Eigenzustandslöser berücksichtigt alle möglichen Paare von Bitstrings mit „Spin-up“ und „Spin-down“, um die Basis $\\mathcal{B}$ en des Unterraums zu bilden:\n",
        "\n",
        "* Element 1: $|00010010\\rangle$\n",
        "\n",
        "* Element 2: $|00011000\\rangle$\n",
        "\n",
        "* Element 3: $|01000010\\rangle$\n",
        "\n",
        "* Element 4: $|01001000\\rangle$\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 12,
      "id": "a550aba2",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "Basis elements of the subspace:\n",
            "|00100001>\n",
            "|00100100>\n",
            "|10000001>\n",
            "|10000100>\n"
          ]
        }
      ],
      "source": [
        "ci_strs_up, ci_strs_dn = ci_strs\n",
        "\n",
        "print(\"Basis elements of the subspace:\")\n",
        "\n",
        "for ci_str_up in ci_strs_up:\n",
        "    for ci_str_dn in ci_strs_dn:\n",
        "        format_name = \"{0:0\" + str(num_orbitals) + \"b}\"\n",
        "        print(\n",
        "            \"|\"\n",
        "            + format_name.format(ci_str_up)\n",
        "            + format_name.format(ci_str_dn)\n",
        "            + \">\"\n",
        "        )"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "7317bc49",
      "metadata": {},
      "source": [
        "**Die Dimension des Unterraums ist nach oben begrenzt durch** : (`samples_per_batch`) $^2$.\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": 5
}