{ "cells": [ { "cell_type": "markdown", "id": "377f84b3-1d02-4d7e-a061-db7c9d3c643d", "metadata": {}, "source": [ "# Heisenberg spin model" ] }, { "cell_type": "code", "execution_count": null, "id": "0a64e811-4cb3-45fa-a117-c8fda21da412", "metadata": {}, "outputs": [], "source": [ "import numpy as np\n", "import scipy.sparse.linalg as spla\n", "from qiskit.transpiler import CouplingMap\n", "import fulqrum as fq" ] }, { "cell_type": "markdown", "id": "fded0c03-fb6f-4987-a450-18a2898c07e6", "metadata": {}, "source": [ "## Construct operator\n", "\n", "Here we construct a 16-qubit Heisenberg spin model over a square-grid using a Qiskit `CouplingMap` to define the grid" ] }, { "cell_type": "code", "execution_count": 23, "id": "ee42f198-4ded-405e-bbdf-fb5dc2aad1fa", "metadata": {}, "outputs": [], "source": [ "# Build 16-qubit coupling map\n", "cmap = CouplingMap.from_grid(4, 4)\n", "num_qubits = cmap.size()\n", "\n", "# Generate Hamiltonian\n", "H = fq.QubitOperator(num_qubits, [])\n", "touched_edges = set({})\n", "coeffs = [-1 / 2, -1 / 2, -1]\n", "for edge in cmap.get_edges():\n", " if edge[::-1] not in touched_edges: # Only add edge once to Hamiltonian\n", " touched_edges.add(edge)\n", " H += fq.QubitOperator(\n", " num_qubits,\n", " [(\"XX\", edge, coeffs[0]), (\"YY\", edge, coeffs[1]), (\"ZZ\", edge, coeffs[2])],\n", " )" ] }, { "cell_type": "markdown", "id": "67263766-eee7-44ea-bff7-60784edaf8d3", "metadata": {}, "source": [ "## Construct subspace\n", "\n", "In lieu of actually running on hardware or a simulator, here we generate a fake set of bit-strings:" ] }, { "cell_type": "code", "execution_count": 24, "id": "66207ada-5512-458a-86b0-880ca9c34437", "metadata": {}, "outputs": [], "source": [ "counts = []\n", "for kk in range(2**num_qubits):\n", " counts.append(bin(kk)[2:].zfill(num_qubits))\n", "\n", "S = fq.Subspace([counts])" ] }, { "cell_type": "markdown", "id": "ca2c4986-604b-4de4-8ac3-2aeae4da5754", "metadata": {}, "source": [ "## Create subspace Hamiltonian and initial vector\n", "\n", "The Hamiltonian and subspace are combined into a `SubspaceHamiltonian` object for eigensolving. Here we also set the initial vector for reproducibility." ] }, { "cell_type": "code", "execution_count": 26, "id": "1715e9ec-4fe5-47b7-89c7-4431dd0da9f6", "metadata": {}, "outputs": [], "source": [ "Hsub = fq.SubspaceHamiltonian(H, S)\n", "v0 = np.ones(S.size(), dtype=Hsub.dtype)" ] }, { "cell_type": "markdown", "id": "1fe5982a-150d-450f-b1f7-08e347ddaa74", "metadata": {}, "source": [ "## Perform diagonalization\n", "\n", "Here we perform the diagonalization twice; first matrix-free and then using a CSR matrix" ] }, { "cell_type": "markdown", "id": "69783948-7610-433d-ae7f-0a53a73ce664", "metadata": {}, "source": [ "### Matrix-free" ] }, { "cell_type": "code", "execution_count": 33, "id": "69f07f94-bd9c-4eee-82b3-c305837e23d3", "metadata": {}, "outputs": [], "source": [ "evals, evecs = spla.eigsh(Hsub, k=1, which=\"SA\", v0=v0)" ] }, { "cell_type": "markdown", "id": "d1aca958-c4d8-4552-8d1d-531a79b41a65", "metadata": {}, "source": [ "### CSR-matrix solution" ] }, { "cell_type": "code", "execution_count": 34, "id": "a53aa19e-7f7b-4147-bd12-63af203da29b", "metadata": {}, "outputs": [], "source": [ "M = Hsub.to_csr_linearoperator_fast()\n", "evals2, evecs2 = spla.eigsh(M, k=1, which=\"SA\", v0=v0)" ] }, { "cell_type": "markdown", "id": "a45b9c10-2eb2-4fb1-83a2-3f79a943fdc9", "metadata": {}, "source": [ "### Compare solutions\n", "\n", "First compare relative error in found eigenvalues" ] }, { "cell_type": "code", "execution_count": 39, "id": "fa0f8487-94e6-4c72-827f-79948d7eb68d", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "np.float64(1.4802973661668783e-16)" ] }, "execution_count": 39, "metadata": {}, "output_type": "execute_result" } ], "source": [ "abs((evals[0] - evals2[0]) / evals[0])" ] }, { "cell_type": "markdown", "id": "dc5c3c10-909d-4469-b34b-2eb9c581cf44", "metadata": {}, "source": [ "Show that the two eigenstates agree:" ] }, { "cell_type": "code", "execution_count": 36, "id": "a9190258-f4c2-4c49-b710-dbbf7e37a851", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{'0000000000000000': 0.7071067811865476,\n", " '1111111111111111': 0.7071067811865476}" ] }, "execution_count": 36, "metadata": {}, "output_type": "execute_result" } ], "source": [ "Hsub.interpret_vector(evecs)" ] }, { "cell_type": "code", "execution_count": 37, "id": "8618b3be-822a-4c18-867c-f0bee30babdf", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{'0000000000000000': 0.7071067811865477,\n", " '1111111111111111': 0.7071067811865477}" ] }, "execution_count": 37, "metadata": {}, "output_type": "execute_result" } ], "source": [ "Hsub.interpret_vector(evecs2)" ] }, { "cell_type": "code", "execution_count": null, "id": "27e5f6f8-f13c-4a44-9e46-1610daaf8b79", "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": "Python 3 (ipykernel)", "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.13.11" } }, "nbformat": 4, "nbformat_minor": 5 }