diff --git a/docs/addons/qiskit-addon-sqd/_toc.json b/docs/addons/qiskit-addon-sqd/_toc.json
index 42126fc06e53..33bf4f5669e9 100644
--- a/docs/addons/qiskit-addon-sqd/_toc.json
+++ b/docs/addons/qiskit-addon-sqd/_toc.json
@@ -1,7 +1,7 @@
{
"parentUrl": "/docs/guides/addons",
"parentLabel": "Documentation",
- "title": "Sample-based quantum diagonalization (SQD) 0.12",
+ "title": "Sample-based quantum diagonalization (SQD) 0.13",
"collapsed": true,
"children": [
{
@@ -30,13 +30,17 @@
"title": "Choose the subspace dimension",
"url": "/docs/addons/qiskit-addon-sqd/guides/choose-subspace-dimension"
},
+ {
+ "title": "Multi-process and multi-threaded acceleration",
+ "url": "/docs/addons/qiskit-addon-sqd/guides/hpc-acceleration"
+ },
{
"title": "Scale workloads with the Dice solver",
"url": "/docs/addons/qiskit-addon-sqd/guides/integrate-dice-solver"
},
{
"title": "Orbital optimization",
- "url": "/docs/addons/qiskit-addon-sqd/guides/use-oo-to-optimize-hamiltonian-basis"
+ "url": "/docs/addons/qiskit-addon-sqd/guides/optimize-orbitals"
},
{
"title": "Open- and closed-shell options",
@@ -69,11 +73,11 @@
"children": [
{
"title": "Sample-based quantum diagonalization of a chemistry Hamiltonian",
- "url": "/docs/tutorials/sample-based-quantum-diagonalization"
+ "url": "https://quantum.cloud.ibm.com/docs/tutorials/sample-based-quantum-diagonalization"
},
{
"title": "Sample-based Krylov quantum diagonalization of a Fermionic lattice model",
- "url": "/docs/tutorials/sample-based-krylov-quantum-diagonalization"
+ "url": "https://quantum.cloud.ibm.com/docs/tutorials/sample-based-krylov-quantum-diagonalization"
}
]
},
@@ -83,7 +87,7 @@
"children": [
{
"title": "Quantum diagonalization algorithms",
- "url": "/learning/courses/quantum-diagonalization-algorithms"
+ "url": "https://quantum.cloud.ibm.com/learning/courses/quantum-diagonalization-algorithms"
}
]
},
@@ -93,7 +97,7 @@
"children": [
{
"title": "Python API reference",
- "url": "/docs/api/qiskit-addon-sqd/"
+ "url": "https://quantum.cloud.ibm.com/docs/api/qiskit-addon-sqd"
},
{
"title": "Release notes",
diff --git a/docs/addons/qiskit-addon-sqd/guides/benchmark-pauli-projection.ipynb b/docs/addons/qiskit-addon-sqd/guides/benchmark-pauli-projection.ipynb
index fb3d2ee73b7a..f845c8291119 100644
--- a/docs/addons/qiskit-addon-sqd/guides/benchmark-pauli-projection.ipynb
+++ b/docs/addons/qiskit-addon-sqd/guides/benchmark-pauli-projection.ipynb
@@ -16,9 +16,7 @@
"id": "55900f6c-2fb6-4d2c-8745-29bad8b66d9f",
"metadata": {},
"source": [
- "# Benchmark Pauli operator projection\n",
- "\n",
- "{/* cspell:ignore textrm, walltime */}"
+ "# Benchmark Pauli operator projection"
]
},
{
diff --git a/docs/addons/qiskit-addon-sqd/guides/choose-subspace-dimension.ipynb b/docs/addons/qiskit-addon-sqd/guides/choose-subspace-dimension.ipynb
index a23d2794783b..3041377776a6 100644
--- a/docs/addons/qiskit-addon-sqd/guides/choose-subspace-dimension.ipynb
+++ b/docs/addons/qiskit-addon-sqd/guides/choose-subspace-dimension.ipynb
@@ -18,8 +18,6 @@
"source": [
"# Bounding the subspace dimension\n",
"\n",
- "{/* cspell:ignore hcore */}\n",
- "\n",
"In this walkthrough, we will show the effect of the subspace dimension in the [self-consistent configuration recovery technique](https://arxiv.org/abs/2405.05068).\n",
"\n",
"*A priori*, we do not know what is the correct subspace dimension to obtain a target level of accuracy. However, we do know that increasing the subspace dimension increases the accuracy of the method. Therefore, we can study the accuracy of the predictions as a function of the subspace dimension."
diff --git a/docs/addons/qiskit-addon-sqd/guides/hpc-acceleration.mdx b/docs/addons/qiskit-addon-sqd/guides/hpc-acceleration.mdx
new file mode 100644
index 000000000000..5098c07122c7
--- /dev/null
+++ b/docs/addons/qiskit-addon-sqd/guides/hpc-acceleration.mdx
@@ -0,0 +1,39 @@
+---
+title: "Support for multi-process and multi-threaded acceleration"
+description: "Support for multi-process and multi-threaded acceleration for the latest version of Sample-based quantum diagonalization (SQD)"
+---
+
+# Support for multi-process and multi-threaded acceleration
+
+This page documents the extent to which `qiskit-addon-sqd` supports multi-threaded and multi-process acceleration, and the assumptions that a high-performance-computing (HPC) developer can rely on when integrating this package into an accelerated workload.
+
+## The single-threaded assumption
+
+Unless otherwise specified, the APIs in this package are meant to be called from a single thread. High-level APIs exposed by this package are not guaranteed to be re-entrant, and end users should not invoke them from any thread other than the main thread.
+
+## Collective multi-process execution
+
+This package supports collective multi-process acceleration in the single-program, multiple-data (SPMD) style, in which the entire program is launched as multiple isolated processes that run with explicit global synchronization and communication between them (for example, `mpirun -n 128 python my_program.py`). Because the SPMD style composes cleanly with job schedulers and other parallel software and scales to large process counts, it is the recommended model for high-performance and large-scale workloads, and it is the subject of this page.
+
+Although this package is designed to accommodate different collective-execution backends, its current implementation targets MPI, the standard message-passing API for HPC systems. Regardless of implementation, this package assumes that a single thread controls each process. In the case of MPI, this corresponds to `MPI_THREAD_FUNNELED` or lower.
+
+If a function supports collective execution, its documentation must say so. If the documentation does not mention collective execution, the function has no collective semantics and must be called from the control process alone.
+
+The specific return-value and synchronization semantics of a collective function are documented with the function itself. In general, that documentation should make clear:
+
+* Whether the function is meant to be called independently by each process on its own local data, or collectively by all processes.
+* How its arguments must agree across processes.
+* How its return value is delivered—whether the result exists only on the control process, whether all processes receive the same value, or whether each process receives a handle to a local portion of a distributed data structure.
+
+Only one function currently supports being called collectively from all processes: [`diagonalize_fermionic_hamiltonian()`](/docs/api/qiskit-addon-sqd/fermion#qiskit_addon_sqd.fermion.diagonalize_fermionic_hamiltonian "qiskit_addon_sqd.fermion.diagonalize_fermionic_hamiltonian"). When it is invoked collectively, the eigensolver step is where all processes participate and contribute work, so an eigensolver implementation can use every process. The remaining parts of the configuration-recovery loop have no distributed implementation and run on the control process (rank 0) only.
+
+Some existing eigensolver implementations instead require the calling program to run outside an MPI/SPMD environment, because they launch and manage their own parallel processes internally, for example by invoking `mpirun` on the user’s behalf. That mode is convenient for interactive and notebook-based work and remains supported; its requirements on the calling program are described in the API reference of the [`diagonalize_fermionic_hamiltonian()`](/docs/api/qiskit-addon-sqd/fermion#qiskit_addon_sqd.fermion.diagonalize_fermionic_hamiltonian "qiskit_addon_sqd.fermion.diagonalize_fermionic_hamiltonian") function.
+
+## Error handling in a multi-process context
+
+A function that is called collectively from all processes must not raise an exception or abort only a single process, because that would leave the remaining processes deadlocked or in an inconsistent state. Instead, error handling follows fail-stop semantics for the execution context as a whole: upon an error, the implementation must be prepared to abort the entire execution context collectively (for example, by using `MPI_Abort`).
+
+The API cannot guarantee coordinated error reporting or collective delivery of exceptions across processes, because MPI implementations do not provide such guarantees. An implementation might additionally attempt to make an error visible to all participating processes—for example, by having each process raise an exception—but this can only be provided on a best-effort basis and must not be relied upon for correctness or recovery.
+
+These are properties that a collective implementation is permitted to have, not guarantees about any particular one. In this package, the only collective step is the eigensolver (see the preceding section); its default implementation is not distributed, so these considerations apply to a custom, collective eigensolver supplied by the user.
+
diff --git a/docs/addons/qiskit-addon-sqd/guides/integrate-dice-solver.ipynb b/docs/addons/qiskit-addon-sqd/guides/integrate-dice-solver.ipynb
index 0b549e787818..9aada239aeda 100644
--- a/docs/addons/qiskit-addon-sqd/guides/integrate-dice-solver.ipynb
+++ b/docs/addons/qiskit-addon-sqd/guides/integrate-dice-solver.ipynb
@@ -18,8 +18,6 @@
"source": [
"# Scale SQD chemistry workflows with Dice solver\n",
"\n",
- "{/* cspell:ignore hcore */}\n",
- "\n",
"This guide shows how to use the Dice solver as an alternative SCI solver to diagonalize larger Fermionic problems beyond what the default PySCF solver can support. For information on how to install and use ``qiskit-addon-dice-solver``, [visit the documentation](https://qiskit.github.io/qiskit-addon-dice-solver/). For more details on the SQD code used in this example, see the [chemistry Hamiltonian tutorial](/docs/tutorials/sample-based-quantum-diagonalization)."
]
},
diff --git a/docs/addons/qiskit-addon-sqd/guides/optimize-orbitals.ipynb b/docs/addons/qiskit-addon-sqd/guides/optimize-orbitals.ipynb
new file mode 100644
index 000000000000..20ce96d1e6b5
--- /dev/null
+++ b/docs/addons/qiskit-addon-sqd/guides/optimize-orbitals.ipynb
@@ -0,0 +1,403 @@
+{
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "id": "frontmatter",
+ "metadata": {},
+ "source": [
+ "---\n",
+ "title: \"Improve an SQD estimate with orbital optimization\"\n",
+ "description: \"Improve an SQD estimate with orbital optimization for the latest version of Sample-based quantum diagonalization (SQD)\"\n",
+ "---"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "bb5a576d",
+ "metadata": {},
+ "source": [
+ "# Improve an SQD estimate with orbital optimization\n",
+ "\n",
+ "Sample-based quantum diagonalization (SQD) approximates a ground-state energy by\n",
+ "diagonalizing the Hamiltonian in a fixed subspace of electronic configurations. That\n",
+ "estimate depends on the orbital basis in which the Hamiltonian is expressed, and\n",
+ "*orbital optimization* (OO) exploits this freedom to lower the energy without enlarging\n",
+ "the subspace.\n",
+ "\n",
+ "This guide runs SQD on an $N_2$ molecule and then improves the result with orbital\n",
+ "optimization, using [`ffsim`](https://qiskit-community.github.io/ffsim/) to represent\n",
+ "the Hamiltonian and find the energy-minimizing orbital rotation."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "77ab953b",
+ "metadata": {},
+ "source": [
+ "## Run SQD\n",
+ "\n",
+ "We build the molecular integrals for $N_2$ in the molecular-orbital (MO) basis, generate\n",
+ "uniform random samples, and run SQD to obtain a ground-state approximation."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 1,
+ "id": "b8d5618e",
+ "metadata": {
+ "execution": {
+ "iopub.execute_input": "2026-07-16T01:36:48.334261Z",
+ "iopub.status.busy": "2026-07-16T01:36:48.334063Z",
+ "iopub.status.idle": "2026-07-16T01:37:42.585853Z",
+ "shell.execute_reply": "2026-07-16T01:37:42.584303Z"
+ }
+ },
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "converged SCF energy = -108.835236570775\n",
+ "CASCI E = -109.046671778080 E(CI) = -32.8155692383187 S^2 = 0.0000000\n"
+ ]
+ }
+ ],
+ "source": [
+ "import numpy as np\n",
+ "import pyscf\n",
+ "import pyscf.cc\n",
+ "import pyscf.mcscf\n",
+ "from qiskit_addon_sqd.counts import generate_bit_array_uniform\n",
+ "from qiskit_addon_sqd.fermion import diagonalize_fermionic_hamiltonian\n",
+ "\n",
+ "# Specify molecule properties\n",
+ "num_orbitals = 16\n",
+ "num_elec_a = num_elec_b = 5\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\n",
+ "\n",
+ "# Create a seed to control randomness throughout this workflow\n",
+ "rng = np.random.default_rng(24)\n",
+ "\n",
+ "\n",
+ "# Generate random samples\n",
+ "bit_array = generate_bit_array_uniform(\n",
+ " 10_000, num_orbitals * 2, rand_seed=rng\n",
+ ")\n",
+ "\n",
+ "# Run SQD\n",
+ "result = diagonalize_fermionic_hamiltonian(\n",
+ " hcore,\n",
+ " eri,\n",
+ " bit_array,\n",
+ " samples_per_batch=100,\n",
+ " norb=num_orbitals,\n",
+ " nelec=(num_elec_a, num_elec_b),\n",
+ " num_batches=1,\n",
+ " max_iterations=5,\n",
+ " symmetrize_spin=True,\n",
+ " seed=rng,\n",
+ ")"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 2,
+ "id": "0ca70028",
+ "metadata": {
+ "execution": {
+ "iopub.execute_input": "2026-07-16T01:37:42.590790Z",
+ "iopub.status.busy": "2026-07-16T01:37:42.589477Z",
+ "iopub.status.idle": "2026-07-16T01:37:42.595563Z",
+ "shell.execute_reply": "2026-07-16T01:37:42.595133Z"
+ }
+ },
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Exact energy: -109.04667178\n",
+ "SQD energy: -108.98469255\n"
+ ]
+ }
+ ],
+ "source": [
+ "sqd_energy = result.energy + nuclear_repulsion_energy\n",
+ "print(f\"Exact energy: {exact_energy:.8f}\")\n",
+ "print(f\"SQD energy: {sqd_energy:.8f}\")"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "9160d09c",
+ "metadata": {},
+ "source": [
+ "## Optimize the orbitals\n",
+ "\n",
+ "Orbital optimization searches for an orbital rotation that lowers the variational energy\n",
+ "\n",
+ "$$\n",
+ "E = \\langle \\psi | \\mathcal{U}^\\dagger\\, H\\, \\mathcal{U} | \\psi \\rangle\n",
+ "$$\n",
+ "\n",
+ "of the SQD ground-state approximation $|\\psi\\rangle$. An orbital rotation is specified by\n",
+ "an $N \\times N$ unitary matrix $\\mathbf{U}$ ($N$ is the number of spatial orbitals), which\n",
+ "acts on the many-body state through the operator\n",
+ "\n",
+ "$$\n",
+ "\\mathcal{U} = \\exp\\left[\\sum_{pq, \\sigma} \\log(\\mathbf{U})_{pq}\\, a^\\dagger_{p\\sigma} a_{q\\sigma}\\right].\n",
+ "$$\n",
+ "\n",
+ "`ffsim.optimize_orbitals` returns the **matrix** $\\mathbf{U}$, and applying it to the\n",
+ "orbital basis (via `hamiltonian.rotated`) is equivalent to applying $\\mathcal{U}$ to the\n",
+ "state. See the\n",
+ "[ffsim orbital-rotation explanation](https://qiskit-community.github.io/ffsim/explanations/orbital-rotation.html)\n",
+ "for details.\n",
+ "\n",
+ "Since rotating the orbitals changes the Hamiltonian seen by the subspace, we alternate\n",
+ "two steps until the energy stops improving:\n",
+ "\n",
+ "1. **Diagonalize** the Hamiltonian in the current basis over the fixed set of\n",
+ " configurations.\n",
+ "2. **Optimize the orbitals** by finding the rotation that minimizes the energy of the\n",
+ " resulting state, then rotate the integrals into the new basis.\n",
+ "\n",
+ "We delegate the orbital-rotation step to\n",
+ "[`ffsim.optimize_orbitals`](https://qiskit-community.github.io/ffsim/api/ffsim.html#ffsim.optimize_orbitals),\n",
+ "which finds the energy-minimizing rotation from the one- and two-body reduced density\n",
+ "matrices (RDMs) of the state. See\n",
+ "[Sec. II A 4](https://arxiv.org/pdf/2405.05068) for details."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "006745b5",
+ "metadata": {},
+ "source": [
+ "### Why orbital optimization helps here\n",
+ "\n",
+ "The SCF molecular-orbital (MO) basis is stationary with respect to orbital rotations\n",
+ "for the *full*-CI problem. But SQD works in a small truncated subspace (here a few\n",
+ "hundred CI strings out of roughly 19 million full-CI determinants), for which the MO\n",
+ "basis is generally not optimal, so rotating the orbitals lowers the energy the subspace\n",
+ "can represent."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 3,
+ "id": "46eb2f5a",
+ "metadata": {
+ "execution": {
+ "iopub.execute_input": "2026-07-16T01:37:42.597573Z",
+ "iopub.status.busy": "2026-07-16T01:37:42.597399Z",
+ "iopub.status.idle": "2026-07-16T01:37:42.654809Z",
+ "shell.execute_reply": "2026-07-16T01:37:42.654267Z"
+ }
+ },
+ "outputs": [],
+ "source": [
+ "import ffsim\n",
+ "from pyscf import fci\n",
+ "\n",
+ "# ffsim's ``MolecularHamiltonian`` uses the same \"chemist\" ordering for the two-body\n",
+ "# tensor as PySCF's ``eri``, and stores the nuclear repulsion energy as the constant\n",
+ "# term so that expectation values come out as total energies."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "93179dc4",
+ "metadata": {},
+ "source": [
+ "### Alternate diagonalization and orbital optimization\n",
+ "\n",
+ "We keep the diagonalization subspace **fixed** to the configurations discovered by SQD\n",
+ "above, so that each iteration isolates the effect of rotating the orbitals. Each\n",
+ "iteration:\n",
+ "\n",
+ "1. **Diagonalizes** the Hamiltonian over the fixed subspace in the current basis, using\n",
+ " PySCF's selected-CI solver.\n",
+ "2. **Builds the RDMs** of the resulting state, which is all `ffsim.optimize_orbitals`\n",
+ " needs.\n",
+ "3. **Optimizes the orbitals**: `ffsim.optimize_orbitals` returns the energy-minimizing\n",
+ " rotation, which we apply to the integrals to move into the improved basis.\n",
+ "\n",
+ "We record the energy *before* each optimization step. Because the basis improves every\n",
+ "iteration, this sequence decreases monotonically toward the best energy achievable in\n",
+ "the fixed subspace."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 4,
+ "id": "a0783e88",
+ "metadata": {
+ "execution": {
+ "iopub.execute_input": "2026-07-16T01:37:42.657394Z",
+ "iopub.status.busy": "2026-07-16T01:37:42.657213Z",
+ "iopub.status.idle": "2026-07-16T01:38:48.374706Z",
+ "shell.execute_reply": "2026-07-16T01:38:48.373697Z"
+ }
+ },
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Iteration 0: energy = -108.98452447\n",
+ "Iteration 1: energy = -108.99981993\n",
+ "Iteration 2: energy = -109.00585329\n",
+ "Iteration 3: energy = -109.00816569\n",
+ "Iteration 4: energy = -109.00936616\n",
+ "Iteration 5: energy = -109.01014322\n",
+ "Iteration 6: energy = -109.01069439\n",
+ "Iteration 7: energy = -109.01109308\n",
+ "Iteration 8: energy = -109.01138928\n",
+ "Iteration 9: energy = -109.01161411\n"
+ ]
+ }
+ ],
+ "source": [
+ "# Fix the diagonalization subspace to the configurations found by SQD.\n",
+ "ci_strings = (result.sci_state.ci_strs_a, result.sci_state.ci_strs_b)\n",
+ "nelec = (num_elec_a, num_elec_b)\n",
+ "\n",
+ "# Start from the MO basis in which we ran SQD.\n",
+ "hamiltonian_opt = ffsim.MolecularHamiltonian(\n",
+ " hcore, eri, constant=nuclear_repulsion_energy\n",
+ ")\n",
+ "\n",
+ "num_iters = 10\n",
+ "for i in range(num_iters):\n",
+ " # Diagonalize over the fixed subspace in the current basis.\n",
+ " myci = fci.selected_ci.SelectedCI()\n",
+ " myci = fci.addons.fix_spin_(myci, ss=spin_sq)\n",
+ " _, amplitudes = fci.selected_ci.kernel_fixed_space(\n",
+ " myci,\n",
+ " hamiltonian_opt.one_body_tensor,\n",
+ " hamiltonian_opt.two_body_tensor,\n",
+ " num_orbitals,\n",
+ " nelec,\n",
+ " ci_strs=ci_strings,\n",
+ " )\n",
+ "\n",
+ " # Build the RDMs and record the energy before re-optimizing the orbitals.\n",
+ " dm1, dm2 = myci.make_rdm12(amplitudes, num_orbitals, nelec)\n",
+ " rdm = ffsim.ReducedDensityMatrix(dm1, dm2)\n",
+ " energy = rdm.expectation(hamiltonian_opt).real\n",
+ " print(f\"Iteration {i}: energy = {energy:.8f}\")\n",
+ "\n",
+ " # Rotate the Hamiltonian into the energy-minimizing basis for the next iteration.\n",
+ " # optimize_orbitals returns the unitary matrix U minimizing\n",
+ " # rdm.rotated(U).expectation(hamiltonian), equivalently\n",
+ " # rdm.expectation(hamiltonian.rotated(U.conj().T)), so we rotate by U^dagger.\n",
+ " orbital_rotation = ffsim.optimize_orbitals(rdm, hamiltonian_opt)\n",
+ " hamiltonian_opt = hamiltonian_opt.rotated(orbital_rotation.T.conj())"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "a61dbda8",
+ "metadata": {},
+ "source": [
+ "### Compare the results\n",
+ "\n",
+ "Orbital optimization improves the fixed-subspace estimate, closing much of the gap to\n",
+ "the exact energy while staying above it."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 5,
+ "id": "762b0903",
+ "metadata": {
+ "execution": {
+ "iopub.execute_input": "2026-07-16T01:38:48.377620Z",
+ "iopub.status.busy": "2026-07-16T01:38:48.377404Z",
+ "iopub.status.idle": "2026-07-16T01:38:53.111168Z",
+ "shell.execute_reply": "2026-07-16T01:38:53.110312Z"
+ }
+ },
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Exact energy: -109.04667178\n",
+ "SQD energy (MO): -108.98469255\n",
+ "Energy after OO: -109.01178727\n"
+ ]
+ }
+ ],
+ "source": [
+ "# Diagonalize once more in the final optimized basis to report the improved energy.\n",
+ "myci = fci.selected_ci.SelectedCI()\n",
+ "myci = fci.addons.fix_spin_(myci, ss=spin_sq)\n",
+ "_, amplitudes = fci.selected_ci.kernel_fixed_space(\n",
+ " myci,\n",
+ " hamiltonian_opt.one_body_tensor,\n",
+ " hamiltonian_opt.two_body_tensor,\n",
+ " num_orbitals,\n",
+ " nelec,\n",
+ " ci_strs=ci_strings,\n",
+ ")\n",
+ "dm1, dm2 = myci.make_rdm12(amplitudes, num_orbitals, nelec)\n",
+ "energy_after_oo = (\n",
+ " ffsim.ReducedDensityMatrix(dm1, dm2).expectation(hamiltonian_opt).real\n",
+ ")\n",
+ "\n",
+ "print(f\"Exact energy: {exact_energy:.8f}\")\n",
+ "print(f\"SQD energy (MO): {sqd_energy:.8f}\")\n",
+ "print(f\"Energy after OO: {energy_after_oo:.8f}\")"
+ ]
+ }
+ ],
+ "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
+}
diff --git a/docs/addons/qiskit-addon-sqd/guides/overview.mdx b/docs/addons/qiskit-addon-sqd/guides/overview.mdx
index 2147d3756dbd..e627b79aced8 100644
--- a/docs/addons/qiskit-addon-sqd/guides/overview.mdx
+++ b/docs/addons/qiskit-addon-sqd/guides/overview.mdx
@@ -20,11 +20,12 @@ These guides provide a deeper explanation of specific concepts and components fr
### General
* [How to choose the subspace dimension from its impact on eigenvalue estimation accuracy](choose-subspace-dimension)
+* [Understand this package’s support for multi-process and multi-threaded acceleration](hpc-acceleration)
### Fermionic systems
* [Scale SQD workflows for Fermionic systems with the Dice solver](integrate-dice-solver)
-* [Optimize the Hamiltonian basis with orbital optimization to improve energy estimations](use-oo-to-optimize-hamiltonian-basis)
+* [Improve an SQD estimate with orbital optimization](optimize-orbitals)
* [Understand open- and closed-shell options and their effect on subspace construction](select-open-closed-shell)
* [Augment the pool of electronic configurations using Fermionic transition operators to improve energy estimations and compute energies of excited states](add-fermionic-excitations-to-configuration-pool)
diff --git a/docs/addons/qiskit-addon-sqd/guides/quickstart.ipynb b/docs/addons/qiskit-addon-sqd/guides/quickstart.ipynb
index 3cfc36c9005e..28405de7690e 100644
--- a/docs/addons/qiskit-addon-sqd/guides/quickstart.ipynb
+++ b/docs/addons/qiskit-addon-sqd/guides/quickstart.ipynb
@@ -18,8 +18,6 @@
"source": [
"# Quickstart\n",
"\n",
- "{/* cspell:ignore mcscf, ncas, nelecas, hcore, binom */}\n",
- "\n",
"This guide demonstrates a minimal working example of the `qiskit-addon-sqd` package. We use sample-based quantum diagonalization (SQD) to refine noisy samples taken from a quantum circuit that approximates the ground state of a chemistry Hamiltonian. Ground state energies are approximated by diagonalizing the Hamiltonian in subspaces formed by the refined samples.\n",
"\n",
"For more explanatory end-to-end workflows that run on quantum hardware, check out the tutorials:\n",
diff --git a/docs/addons/qiskit-addon-sqd/guides/use-oo-to-optimize-hamiltonian-basis.ipynb b/docs/addons/qiskit-addon-sqd/guides/use-oo-to-optimize-hamiltonian-basis.ipynb
deleted file mode 100644
index bedc2a18f963..000000000000
--- a/docs/addons/qiskit-addon-sqd/guides/use-oo-to-optimize-hamiltonian-basis.ipynb
+++ /dev/null
@@ -1,400 +0,0 @@
-{
- "cells": [
- {
- "cell_type": "markdown",
- "id": "frontmatter",
- "metadata": {},
- "source": [
- "---\n",
- "title: \"Optimize Hamiltonian basis with orbital optimization\"\n",
- "description: \"Optimize Hamiltonian basis with orbital optimization for the latest version of Sample-based quantum diagonalization (SQD)\"\n",
- "---"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "9e40af77-7f0f-4dd6-ab0a-420cf396050e",
- "metadata": {},
- "source": [
- "# Optimize Hamiltonian basis with orbital optimization\n",
- "\n",
- "{/* cspell:ignore hcore, SQSD */}\n",
- "\n",
- "In this guide, we will show how to use the `sqd` package to post-process quantum samples using the [self-consistent configuration recovery technique](https://arxiv.org/abs/2405.05068) and then further optimize the ground state approximation using orbital optimization.\n",
- "\n",
- "Refer to [Sec. II A 4](https://arxiv.org/pdf/2405.05068) for a more detailed discussion on this technique."
- ]
- },
- {
- "cell_type": "markdown",
- "id": "a6755afb-ca1e-4473-974b-ba89acc8abce",
- "metadata": {},
- "source": [
- "### Specify the molecule and generate samples\n",
- "\n",
- "In this example, we will approximate the ground state energy of an $N_2$ molecule and then improve the answer using orbital optimization. This guide studies $N_2$ at equilibrium, which is mean-field dominated. This means the MO basis is already a good choice for our integrals; therefore, we will rotate our integrals **out** of the MO basis in order to illustrate the effects of orbital optimization."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 1,
- "id": "677f54ac-b4ed-47e3-b5ba-5366d3a520f9",
- "metadata": {},
- "outputs": [],
- "source": [
- "%%capture\n",
- "import numpy as np\n",
- "import pyscf\n",
- "import pyscf.cc\n",
- "import pyscf.mcscf\n",
- "from qiskit_addon_sqd.fermion import rotate_integrals\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": "b23a74fc-708c-4bd0-af4e-c9cd189b6346",
- "metadata": {},
- "source": [
- "The MO basis is already a good basis for this problem, so we will rotate out of that basis in this guide in order to highlight the effect of orbital optimization."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 2,
- "id": "9f46d1c6-3b49-45ad-b9ed-972bd58f7e3c",
- "metadata": {},
- "outputs": [],
- "source": [
- "# Rotate our integrals out of MO basis\n",
- "rng = np.random.default_rng(24)\n",
- "num_params = (\n",
- " num_orbitals**2 - num_orbitals\n",
- ") // 2 # antisymmetric, specified by upper triangle\n",
- "k_rot = (rng.random(num_params) - 0.5) * 0.5\n",
- "hcore_rot, eri_rot = rotate_integrals(hcore, eri, k_rot)"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "c58e988c-a109-44cd-a975-9df43250c318",
- "metadata": {},
- "source": [
- "Generate samples:"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 3,
- "id": "e9506e0b-ed64-48bb-a97a-ef851b604af1",
- "metadata": {},
- "outputs": [],
- "source": [
- "from qiskit_addon_sqd.counts import counts_to_arrays, generate_counts_uniform\n",
- "\n",
- "# Generate random samples\n",
- "counts_dict = generate_counts_uniform(10_000, num_orbitals * 2, rand_seed=rng)\n",
- "\n",
- "# Convert counts into bitstring and probability arrays\n",
- "bitstring_matrix_full, probs_arr_full = counts_to_arrays(counts_dict)"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "eb704101-0fe8-4d12-b572-b1d844e35a90",
- "metadata": {},
- "source": [
- "### Iteratively refine the samples using SQD and approximate the ground state"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 4,
- "id": "b72c048e-fe8e-4fc2-b28b-03138249074e",
- "metadata": {},
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "Starting configuration recovery iteration 0\n",
- "Starting configuration recovery iteration 1\n",
- "Starting configuration recovery iteration 2\n",
- "Starting configuration recovery iteration 3\n",
- "Starting configuration recovery iteration 4\n"
- ]
- }
- ],
- "source": [
- "from qiskit_addon_sqd.configuration_recovery import recover_configurations\n",
- "from qiskit_addon_sqd.fermion import solve_fermion\n",
- "from qiskit_addon_sqd.subsampling import postselect_and_subsample\n",
- "\n",
- "# SQSD options\n",
- "iterations = 5\n",
- "\n",
- "# Eigenstate solver options\n",
- "n_batches = 3\n",
- "samples_per_batch = 100\n",
- "max_davidson_cycles = 200\n",
- "\n",
- "# Self-consistent configuration recovery loop\n",
- "e_hist = np.zeros((iterations, n_batches)) # energy history\n",
- "s_hist = np.zeros((iterations, n_batches)) # spin history\n",
- "occupancy_hist = []\n",
- "avg_occupancy = None\n",
- "for i in range(iterations):\n",
- " print(f\"Starting configuration recovery iteration {i}\")\n",
- " # On the first iteration, we have no orbital occupancy information from the\n",
- " # solver, so we just post-select from the full bitstring set based on hamming weight.\n",
- " if avg_occupancy is None:\n",
- " bs_mat_tmp = bitstring_matrix_full\n",
- " probs_arr_tmp = probs_arr_full\n",
- "\n",
- " # In following iterations, we use both the occupancy info and the target hamming\n",
- " # weight to refine bitstrings.\n",
- " else:\n",
- " bs_mat_tmp, probs_arr_tmp = recover_configurations(\n",
- " bitstring_matrix_full,\n",
- " probs_arr_full,\n",
- " avg_occupancy,\n",
- " num_elec_a,\n",
- " num_elec_b,\n",
- " rand_seed=rng,\n",
- " )\n",
- "\n",
- " # Throw out samples with incorrect hamming weight and create batches of subsamples.\n",
- " batches = postselect_and_subsample(\n",
- " bs_mat_tmp,\n",
- " probs_arr_tmp,\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=rng,\n",
- " )\n",
- "\n",
- " # Run eigenstate solvers in a loop. This loop should be parallelized for larger problems.\n",
- " int_e = np.zeros(n_batches)\n",
- " int_s = np.zeros(n_batches)\n",
- " int_occs = []\n",
- " cs = []\n",
- " for j in range(n_batches):\n",
- " energy_sci, coeffs_sci, avg_occs, spin = solve_fermion(\n",
- " batches[j],\n",
- " hcore_rot,\n",
- " eri_rot,\n",
- " open_shell=open_shell,\n",
- " spin_sq=spin_sq,\n",
- " max_cycle=max_davidson_cycles,\n",
- " )\n",
- " energy_sci += nuclear_repulsion_energy\n",
- " int_e[j] = energy_sci\n",
- " int_s[j] = spin\n",
- " int_occs.append(avg_occs)\n",
- " cs.append(coeffs_sci)\n",
- "\n",
- " # Combine batch results\n",
- " avg_occupancy = tuple(np.mean(int_occs, axis=0))\n",
- "\n",
- " # Track optimization history\n",
- " e_hist[i, :] = int_e\n",
- " s_hist[i, :] = int_s\n",
- " occupancy_hist.append(avg_occupancy)"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "917cf2d0",
- "metadata": {},
- "source": [
- "### Refine the subspace\n",
- "\n",
- "To refine the subspace, we will take the CI strings of the batch with the lowest energy\n",
- "from the last configuration recovery step. Other strategies may be used, like taking the union\n",
- "of the CI strings of the batches in the last configuration recovery iteration."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 5,
- "id": "2a587030",
- "metadata": {},
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "Subspace dimension: 32761\n",
- "Energy of that batch from SQD: -108.7531706601421\n"
- ]
- }
- ],
- "source": [
- "from qiskit_addon_sqd.fermion import bitstring_matrix_to_ci_strs\n",
- "\n",
- "best_batch = batches[np.argmin(e_hist[-1])]\n",
- "ci_strs_up, ci_strs_dn = bitstring_matrix_to_ci_strs(\n",
- " best_batch, open_shell=open_shell\n",
- ")\n",
- "print(f\"Subspace dimension: {len(ci_strs_up) * len(ci_strs_dn)}\")\n",
- "print(f\"Energy of that batch from SQD: {e_hist[-1, np.argmin(e_hist[-1])]}\")\n",
- "\n",
- "# Union strategy\n",
- "\n",
- "# batches_union = np.concatenate((batches[0], batches[1]), axis = 0)\n",
- "# for i in range(n_batches-2):\n",
- "# batches_union = np.concatenate((batches_union, batches[ i+ 2]))\n",
- "# ci_strs_up, ci_strs_dn = bitstring_matrix_to_ci_strs(\n",
- "# batches_union, open_shell=open_shell\n",
- "# )\n",
- "# print (f\"Subspace dimension: {len(ci_strs_up) * len(ci_strs_dn)}\")"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "e8c6d5e4",
- "metadata": {},
- "source": [
- "### Perform orbital optimization to improve the energy approximation\n",
- "\n",
- "We now describe how to optimize the orbitals to further improve the quality of the SQD calculation.\n",
- "\n",
- "The orbital rotations that are implemented in this package are those described by:\n",
- "$$\n",
- "U(\\kappa) = e^{\\sum_{pq, \\sigma} \\kappa_{pq} c^\\dagger_{p\\sigma} c_{q\\sigma}},\n",
- "$$\n",
- "where $\\kappa_{p, q} \\in \\mathbb{R}$ and $\\kappa_{p, q} = -\\kappa_{q, p}$. The orbitals are optimized to\n",
- "minimize the variational energy:\n",
- "$$\n",
- "E(\\kappa) = \\langle \\psi | U^\\dagger(\\kappa) H U(\\kappa) |\\psi \\rangle,\n",
- "$$\n",
- "with respect to $\\kappa$ using gradient descent with momentum. Recall that\n",
- "$|\\psi\\rangle$ is spanned in a subspace defined by determinants.\n",
- "\n",
- "Since the change of basis alters the Hamiltonian, we allow $|\\psi\\rangle$ to\n",
- "respond to the change in the Hamiltonian. This is done by performing a number of alternating\n",
- "self-consistent optimizations of $\\kappa$ and $|\\psi\\rangle$. We recall that the optimal\n",
- "$|\\psi\\rangle$ is given by the lowest eigenvector of the Hamiltonian projected into the\n",
- "subspace.\n",
- "\n",
- "The ``sqd.fermion.fermion`` module provides the tools to perform this alternating\n",
- "optimization. In particular, the function ``sqd.fermion.optimize_orbitals()``.\n",
- "\n",
- "Some of the arguments that define the optimization are as follows:\n",
- "\n",
- "- ``num_iters``: number of self-consistent iterations.\n",
- "- ``num_steps_grad``: number of gradient step updates performed when optimizing $\\kappa$ on each self-consistent iteration.\n",
- "- ``learning_rate``: step-size in the gradient descent optimization of $\\kappa$."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 6,
- "id": "b5e56baf",
- "metadata": {},
- "outputs": [],
- "source": [
- "from qiskit_addon_sqd.fermion import optimize_orbitals\n",
- "\n",
- "k_flat = (rng.random(num_params) - 0.5) * 0.1\n",
- "num_iters = 20\n",
- "num_steps_grad = 10_000 # relatively cheap to execute\n",
- "learning_rate = 0.05\n",
- "\n",
- "e_improved, k_flat, orbital_occupancies = optimize_orbitals(\n",
- " best_batch,\n",
- " hcore_rot,\n",
- " eri_rot,\n",
- " k_flat,\n",
- " open_shell=open_shell,\n",
- " spin_sq=spin_sq,\n",
- " num_iters=num_iters,\n",
- " num_steps_grad=num_steps_grad,\n",
- " learning_rate=learning_rate,\n",
- " max_cycle=max_davidson_cycles,\n",
- ")"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "e06f5c28-83d0-4dc2-b2bd-2ec92676745d",
- "metadata": {},
- "source": [
- "Here we see that by optimizing rotation parameters for our Hamiltonian, we can improve the result from SQD."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 7,
- "id": "78a80e64",
- "metadata": {},
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "Exact energy: -109.04667177808032\n",
- "SQD energy: -108.7531706601421\n",
- "Energy after OO: -108.80400806164377\n"
- ]
- }
- ],
- "source": [
- "print(f\"Exact energy: {exact_energy}\")\n",
- "print(f\"SQD energy: {np.min(e_hist[-1])}\")\n",
- "print(f\"Energy after OO: {e_improved + nuclear_repulsion_energy}\")"
- ]
- }
- ],
- "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
-}
diff --git a/docs/api/qiskit-addon-sqd/0.12/_package.json b/docs/api/qiskit-addon-sqd/0.12/_package.json
new file mode 100644
index 000000000000..1f226e87545d
--- /dev/null
+++ b/docs/api/qiskit-addon-sqd/0.12/_package.json
@@ -0,0 +1,4 @@
+{
+ "name": "qiskit-addon-sqd",
+ "version": "0.12.1"
+}
diff --git a/docs/api/qiskit-addon-sqd/0.12/_toc.json b/docs/api/qiskit-addon-sqd/0.12/_toc.json
new file mode 100644
index 000000000000..eaf2f37f38c8
--- /dev/null
+++ b/docs/api/qiskit-addon-sqd/0.12/_toc.json
@@ -0,0 +1,43 @@
+{
+ "title": "Sample-based quantum diagonalization (SQD)",
+ "children": [
+ {
+ "title": "API index",
+ "url": "/docs/api/qiskit-addon-sqd/0.12"
+ },
+ {
+ "title": "Release notes",
+ "useDivider": true,
+ "url": "/docs/api/qiskit-addon-sqd/release-notes"
+ },
+ {
+ "title": "qiskit_addon_sqd.configuration_recovery",
+ "url": "/docs/api/qiskit-addon-sqd/0.12/configuration-recovery",
+ "untranslatable": true
+ },
+ {
+ "title": "qiskit_addon_sqd.counts",
+ "url": "/docs/api/qiskit-addon-sqd/0.12/counts",
+ "untranslatable": true
+ },
+ {
+ "title": "qiskit_addon_sqd.fermion",
+ "url": "/docs/api/qiskit-addon-sqd/0.12/fermion",
+ "untranslatable": true
+ },
+ {
+ "title": "qiskit_addon_sqd.qubit",
+ "url": "/docs/api/qiskit-addon-sqd/0.12/qubit",
+ "untranslatable": true
+ },
+ {
+ "title": "qiskit_addon_sqd.subsampling",
+ "url": "/docs/api/qiskit-addon-sqd/0.12/subsampling",
+ "untranslatable": true
+ }
+ ],
+ "collapsed": true,
+ "untranslatable": true,
+ "parentUrl": "/docs/addons/qiskit-addon-sqd",
+ "parentLabel": "Sample-based quantum diagonalization (SQD)"
+}
diff --git a/docs/api/qiskit-addon-sqd/0.12/configuration-recovery.mdx b/docs/api/qiskit-addon-sqd/0.12/configuration-recovery.mdx
new file mode 100644
index 000000000000..79e46134a6bc
--- /dev/null
+++ b/docs/api/qiskit-addon-sqd/0.12/configuration-recovery.mdx
@@ -0,0 +1,77 @@
+---
+title: configuration_recovery (v0.12)
+description: API reference for qiskit_addon_sqd.configuration_recovery in qiskit-addon-sqd v0.12
+in_page_toc_min_heading_level: 2
+python_api_type: module
+python_api_name: qiskit_addon_sqd.configuration_recovery
+---
+
+
+
+
+
+# Configuration recovery
+
+`qiskit_addon_sqd.configuration_recovery`
+
+Functions for performing self-consistent configuration recovery.
+
+### post\_select\_by\_hamming\_weight
+
+
+ Post-select bitstrings based on the hamming weight of each half.
+
+
+ The function `qiskit_addon_sqd.configuration_recovery.post_select_by_hamming_weight()` is deprecated as of qiskit-addon-sqd 0.12.0. It will be removed no earlier than v0.13.0. Instead, use the `postselect_by_hamming_right_and_left` function.
+
+
+ **Parameters**
+
+ * **bitstring\_matrix** ([*ndarray*](https://numpy.org/doc/stable/reference/generated/numpy.ndarray.html#numpy.ndarray)) – A 2D array of `bool` representations of bit values such that each row represents a single bitstring
+ * **hamming\_right** ([*int*](https://docs.python.org/3/library/functions.html#int)) – The target hamming weight of the right half of bitstrings
+ * **hamming\_left** ([*int*](https://docs.python.org/3/library/functions.html#int)) – The target hamming weight of the left half of bitstrings
+
+ **Returns**
+
+ A mask signifying which samples (rows) were selected from the input matrix.
+
+ **Return type**
+
+ [*ndarray*](https://numpy.org/doc/stable/reference/generated/numpy.ndarray.html#numpy.ndarray)
+
+
+### recover\_configurations
+
+
+ Refine bitstrings based on average orbital occupancy and a target hamming weight.
+
+ This function refines each bit in isolation in an attempt to transform the Hilbert space represented by the input `bitstring_matrix` into a space closer to that which supports the ground state.
+
+
+ This function makes the assumption that bit `i` represents the spin-down orbital corresponding to the spin-up orbital in bit `i + N` where `N` is the number of spatial orbitals and `i < N`.
+
+
+ **Parameters**
+
+ * **bitstring\_matrix** ([*ndarray*](https://numpy.org/doc/stable/reference/generated/numpy.ndarray.html#numpy.ndarray)) – A 2D array of `bool` representations of bit values such that each row represents a single bitstring
+ * **probabilities** ([*Sequence*](https://docs.python.org/3/library/collections.abc.html#collections.abc.Sequence)*\[*[*float*](https://docs.python.org/3/library/functions.html#float)*] |* [*ndarray*](https://numpy.org/doc/stable/reference/generated/numpy.ndarray.html#numpy.ndarray)) – A 1D array specifying a probability distribution over the bitstrings
+ * **avg\_occupancies** ([*tuple*](https://docs.python.org/3/library/stdtypes.html#tuple)*\[*[*ndarray*](https://numpy.org/doc/stable/reference/generated/numpy.ndarray.html#numpy.ndarray)*,* [*ndarray*](https://numpy.org/doc/stable/reference/generated/numpy.ndarray.html#numpy.ndarray)*]*) – A length-2 tuple of arrays holding the mean occupancy of the spin-up and spin-down orbitals, respectively. The occupancies should be formatted as: `(array([occ_a_0, ..., occ_a_N]), array([occ_b_0, ..., occ_b_N]))`
+ * **num\_elec\_a** ([*int*](https://docs.python.org/3/library/functions.html#int)) – The number of spin-up electrons in the system.
+ * **num\_elec\_b** ([*int*](https://docs.python.org/3/library/functions.html#int)) – The number of spin-down electrons in the system.
+ * **rand\_seed** ([*Generator*](https://numpy.org/doc/stable/reference/random/generator.html#numpy.random.Generator) *|*[*int*](https://docs.python.org/3/library/functions.html#int) *| None*) – A seed for controlling randomness
+
+ **Returns**
+
+ A refined bitstring matrix and an updated probability array.
+
+ **Return type**
+
+ [tuple](https://docs.python.org/3/library/stdtypes.html#tuple)\[[*ndarray*](https://numpy.org/doc/stable/reference/generated/numpy.ndarray.html#numpy.ndarray), [*ndarray*](https://numpy.org/doc/stable/reference/generated/numpy.ndarray.html#numpy.ndarray)]
+
+ **References**
+
+ **\[1]: J. Robledo-Moreno, et al., [Chemistry Beyond Exact Solutions on a Quantum-Centric Supercomputer](https://arxiv.org/abs/2405.05068),**
+
+ arXiv:2405.05068 \[quant-ph].
+
+
diff --git a/docs/api/qiskit-addon-sqd/0.12/counts.mdx b/docs/api/qiskit-addon-sqd/0.12/counts.mdx
new file mode 100644
index 000000000000..70baa64fc7d7
--- /dev/null
+++ b/docs/api/qiskit-addon-sqd/0.12/counts.mdx
@@ -0,0 +1,146 @@
+---
+title: counts (v0.12)
+description: API reference for qiskit_addon_sqd.counts in qiskit-addon-sqd v0.12
+in_page_toc_min_heading_level: 2
+python_api_type: module
+python_api_name: qiskit_addon_sqd.counts
+---
+
+
+
+
+
+# Counts
+
+`qiskit_addon_sqd.counts`
+
+Functions for transforming counts dictionaries.
+
+### counts\_to\_arrays
+
+
+ Convert a counts dictionary into a bitstring matrix and a probability array.
+
+ **Parameters**
+
+ **counts** ([*Mapping*](https://docs.python.org/3/library/collections.abc.html#collections.abc.Mapping)*\[*[*str*](https://docs.python.org/3/library/stdtypes.html#str)*,* [*float*](https://docs.python.org/3/library/functions.html#float) *|*[*int*](https://docs.python.org/3/library/functions.html#int)*]*) – The counts dictionary to convert
+
+ **Returns**
+
+ * A 2D array representing the sampled bitstrings. Each row represents a bitstring, and each element is a `bool` representation of the bit’s value
+ * A 1D array containing the probability with which each bitstring was sampled
+
+ **Return type**
+
+ [tuple](https://docs.python.org/3/library/stdtypes.html#tuple)\[[*ndarray*](https://numpy.org/doc/stable/reference/generated/numpy.ndarray.html#numpy.ndarray), [*ndarray*](https://numpy.org/doc/stable/reference/generated/numpy.ndarray.html#numpy.ndarray)]
+
+
+### generate\_counts\_uniform
+
+
+ Generate a bitstring counts dictionary of samples drawn from the uniform distribution.
+
+ **Parameters**
+
+ * **num\_samples** ([*int*](https://docs.python.org/3/library/functions.html#int)) – The number of samples to draw
+ * **num\_bits** ([*int*](https://docs.python.org/3/library/functions.html#int)) – The number of bits in the bitstrings
+ * **rand\_seed** ([*Generator*](https://numpy.org/doc/stable/reference/random/generator.html#numpy.random.Generator) *|*[*int*](https://docs.python.org/3/library/functions.html#int) *| None*) – A seed for controlling randomness
+
+ **Returns**
+
+ A dictionary mapping bitstrings of length `num_bits` to the number of times they were sampled.
+
+ **Raises**
+
+ [**ValueError**](https://docs.python.org/3/library/exceptions.html#ValueError) – `num_samples` and `num_bits` must be positive integers.
+
+ **Return type**
+
+ [dict](https://docs.python.org/3/library/stdtypes.html#dict)\[[str](https://docs.python.org/3/library/stdtypes.html#str), [int](https://docs.python.org/3/library/functions.html#int)]
+
+
+### generate\_counts\_bipartite\_hamming
+
+
+ Generate a bitstring counts dictionary with specified bipartite hamming weight.
+
+ **Parameters**
+
+ * **num\_samples** ([*int*](https://docs.python.org/3/library/functions.html#int)) – The number of samples to draw
+ * **num\_bits** ([*int*](https://docs.python.org/3/library/functions.html#int)) – The number of bits in the bitstrings
+ * **hamming\_right** ([*int*](https://docs.python.org/3/library/functions.html#int)) – The hamming weight on the right half of each bitstring
+ * **hamming\_left** ([*int*](https://docs.python.org/3/library/functions.html#int)) – The hamming weight on the left half of each bitstring
+ * **rand\_seed** ([*Generator*](https://numpy.org/doc/stable/reference/random/generator.html#numpy.random.Generator) *|*[*int*](https://docs.python.org/3/library/functions.html#int) *| None*) – A seed for controlling randomness
+
+ **Returns**
+
+ A dictionary mapping bitstrings to the number of times they were sampled. Each half of each bitstring in the output dictionary will have a hamming weight as specified by the inputs.
+
+ **Raises**
+
+ * [**ValueError**](https://docs.python.org/3/library/exceptions.html#ValueError) – `num_bits` and `num_samples` must be positive integers.
+ * [**ValueError**](https://docs.python.org/3/library/exceptions.html#ValueError) – Hamming weights must be specified as non-negative integers.
+ * [**ValueError**](https://docs.python.org/3/library/exceptions.html#ValueError) – `num_bits` must be even.
+
+ **Return type**
+
+ [dict](https://docs.python.org/3/library/stdtypes.html#dict)\[[str](https://docs.python.org/3/library/stdtypes.html#str), [int](https://docs.python.org/3/library/functions.html#int)]
+
+
+### normalize\_counts\_dict
+
+
+ Convert a counts dictionary into a probability dictionary.
+
+ **Parameters**
+
+ **counts** ([*Mapping*](https://docs.python.org/3/library/collections.abc.html#collections.abc.Mapping)*\[*[*str*](https://docs.python.org/3/library/stdtypes.html#str)*,* [*float*](https://docs.python.org/3/library/functions.html#float) *|*[*int*](https://docs.python.org/3/library/functions.html#int)*]*)
+
+ **Return type**
+
+ [*Mapping*](https://docs.python.org/3/library/collections.abc.html#collections.abc.Mapping)\[[str](https://docs.python.org/3/library/stdtypes.html#str), [float](https://docs.python.org/3/library/functions.html#float)]
+
+
+### bit\_array\_to\_arrays
+
+
+ Convert a bit array into a bitstring matrix and a probability array.
+
+ **Parameters**
+
+ **bit\_array** ([*BitArray*](/docs/api/qiskit/qiskit.primitives.BitArray)) – The bit array to convert
+
+ **Returns**
+
+ * A 2D array representing the sampled bitstrings. Each row represents a bitstring, and each element is a `bool` representation of the bit’s value
+ * A 1D array containing the probability with which each bitstring was sampled
+
+ **Return type**
+
+ [tuple](https://docs.python.org/3/library/stdtypes.html#tuple)\[[*ndarray*](https://numpy.org/doc/stable/reference/generated/numpy.ndarray.html#numpy.ndarray), [*ndarray*](https://numpy.org/doc/stable/reference/generated/numpy.ndarray.html#numpy.ndarray)]
+
+
+### generate\_bit\_array\_uniform
+
+
+ Generate a bit array of samples drawn from the uniform distribution.
+
+ **Parameters**
+
+ * **num\_samples** ([*int*](https://docs.python.org/3/library/functions.html#int)) – The number of samples to draw
+ * **num\_bits** ([*int*](https://docs.python.org/3/library/functions.html#int)) – The number of bits in the bitstrings
+ * **rand\_seed** ([*Generator*](https://numpy.org/doc/stable/reference/random/generator.html#numpy.random.Generator) *|*[*int*](https://docs.python.org/3/library/functions.html#int) *| None*) – A seed for controlling randomness
+
+ **Returns**
+
+ The sampled bit array.
+
+ **Raises**
+
+ [**ValueError**](https://docs.python.org/3/library/exceptions.html#ValueError) – `num_samples` and `num_bits` must be positive integers.
+
+ **Return type**
+
+ [*BitArray*](/docs/api/qiskit/qiskit.primitives.BitArray)
+
+
diff --git a/docs/api/qiskit-addon-sqd/0.12/fermion.mdx b/docs/api/qiskit-addon-sqd/0.12/fermion.mdx
new file mode 100644
index 000000000000..95b4133d79c6
--- /dev/null
+++ b/docs/api/qiskit-addon-sqd/0.12/fermion.mdx
@@ -0,0 +1,413 @@
+---
+title: fermion (v0.12)
+description: API reference for qiskit_addon_sqd.fermion in qiskit-addon-sqd v0.12
+in_page_toc_min_heading_level: 2
+python_api_type: module
+python_api_name: qiskit_addon_sqd.fermion
+---
+
+
+
+
+
+# Fermion
+
+`qiskit_addon_sqd.fermion`
+
+Functions for the study of fermionic systems.
+
+### SCIState
+
+
+ Bases: [`object`](https://docs.python.org/3/library/functions.html#object)
+
+ The amplitudes and determinants describing a quantum state.
+
+ **Parameters**
+
+ * **amplitudes** ([*ndarray*](https://numpy.org/doc/stable/reference/generated/numpy.ndarray.html#numpy.ndarray))
+ * **ci\_strs\_a** ([*ndarray*](https://numpy.org/doc/stable/reference/generated/numpy.ndarray.html#numpy.ndarray))
+ * **ci\_strs\_b** ([*ndarray*](https://numpy.org/doc/stable/reference/generated/numpy.ndarray.html#numpy.ndarray))
+ * **norb** ([*int*](https://docs.python.org/3/library/functions.html#int))
+ * **nelec** ([*tuple*](https://docs.python.org/3/library/stdtypes.html#tuple)*\[*[*int*](https://docs.python.org/3/library/functions.html#int)*,* [*int*](https://docs.python.org/3/library/functions.html#int)*]*)
+
+ #### amplitudes
+
+
+ An $M \times N$ array where $M =$ len(`ci_strs_a`) and $N$ = len(`ci_strs_b`). `amplitudes[i][j]` is the amplitude of the determinant pair (`ci_strs_a[i]`, `ci_strs_b[j]`).
+
+
+ #### ci\_strs\_a
+
+
+ The alpha determinants.
+
+
+ #### ci\_strs\_b
+
+
+ The beta determinants.
+
+
+ #### load
+
+
+ Load an SCIState object from an .npz file.
+
+
+ #### nelec
+
+
+ The numbers of alpha and beta electrons.
+
+
+ #### norb
+
+
+ The number of spatial orbitals.
+
+
+ #### orbital\_occupancies
+
+
+ Average orbital occupancies.
+
+ **Return type**
+
+ [tuple](https://docs.python.org/3/library/stdtypes.html#tuple)\[[*ndarray*](https://numpy.org/doc/stable/reference/generated/numpy.ndarray.html#numpy.ndarray), [*ndarray*](https://numpy.org/doc/stable/reference/generated/numpy.ndarray.html#numpy.ndarray)]
+
+
+ #### rdm
+
+
+ Compute reduced density matrix.
+
+ **Parameters**
+
+ * **rank** ([*int*](https://docs.python.org/3/library/functions.html#int))
+ * **spin\_summed** ([*bool*](https://docs.python.org/3/library/functions.html#bool))
+
+ **Return type**
+
+ [*ndarray*](https://numpy.org/doc/stable/reference/generated/numpy.ndarray.html#numpy.ndarray)
+
+
+ #### save
+
+
+ Save the SCIState object to an .npz file.
+
+
+ #### spin\_square
+
+
+ Return spin squared.
+
+ **Return type**
+
+ [float](https://docs.python.org/3/library/functions.html#float)
+
+
+
+### bitstring\_matrix\_to\_ci\_strs
+
+
+ Convert bitstrings (rows) in a `bitstring_matrix` into integer representations of determinants.
+
+ This function separates each bitstring in `bitstring_matrix` in half, translates them into integer representations, and finally appends them to their respective (spin-up or spin-down) lists. Those lists are sorted and output from this function.
+
+ **Parameters**
+
+ * **bitstring\_matrix** ([*ndarray*](https://numpy.org/doc/stable/reference/generated/numpy.ndarray.html#numpy.ndarray)) – A 2D array of `bool` representations of bit values such that each row represents a single bitstring
+ * **open\_shell** ([*bool*](https://docs.python.org/3/library/functions.html#bool)) – A flag specifying whether unique configurations from the left and right halves of the bitstrings should be kept separate. If `False`, configurations from the left and right halves of the bitstrings are combined into a single set of unique configurations. That combined set will be returned for both the left and right bitstrings.
+
+ **Returns**
+
+ A length-2 tuple of determinant lists representing the right (spin-up) and left (spin-down) halves of the bitstrings, respectively.
+
+ **Return type**
+
+ [tuple](https://docs.python.org/3/library/stdtypes.html#tuple)\[[*ndarray*](https://numpy.org/doc/stable/reference/generated/numpy.ndarray.html#numpy.ndarray), [*ndarray*](https://numpy.org/doc/stable/reference/generated/numpy.ndarray.html#numpy.ndarray)]
+
+
+### diagonalize\_fermionic\_hamiltonian
+
+
+ Run the sample-based quantum diagonalization (SQD) algorithm.
+
+ **Parameters**
+
+ * **one\_body\_tensor** ([*ndarray*](https://numpy.org/doc/stable/reference/generated/numpy.ndarray.html#numpy.ndarray)) – The one-body tensor of the Hamiltonian.
+
+ * **two\_body\_tensor** ([*ndarray*](https://numpy.org/doc/stable/reference/generated/numpy.ndarray.html#numpy.ndarray)) – The two-body tensor of the Hamiltonian.
+
+ * **bit\_array** ([*BitArray*](/docs/api/qiskit/qiskit.primitives.BitArray)) – Array of sampled bitstrings. Each bitstring should have both the alpha part and beta part concatenated together, with the alpha part concatenated on the right-hand side, like this: `[b_N, ..., b_0, a_N, ..., a_0]`.
+
+ * **samples\_per\_batch** ([*int*](https://docs.python.org/3/library/functions.html#int)) – The number of bitstrings to include in each subsampled batch of bitstrings.
+
+ * **norb** ([*int*](https://docs.python.org/3/library/functions.html#int)) – The number of spatial orbitals.
+
+ * **nelec** ([*tuple*](https://docs.python.org/3/library/stdtypes.html#tuple)*\[*[*int*](https://docs.python.org/3/library/functions.html#int)*,* [*int*](https://docs.python.org/3/library/functions.html#int)*]*) – The numbers of alpha and beta electrons.
+
+ * **num\_batches** ([*int*](https://docs.python.org/3/library/functions.html#int)) – The number of batches to subsample in each configuration recovery iteration. This argument indirectly controls the dimensions of the diagonalization subspaces. A higher value will yield larger subspace dimensions.
+
+ * **energy\_tol** ([*float*](https://docs.python.org/3/library/functions.html#float)) – Numerical tolerance for convergence of the energy. If the change in energy between iterations is smaller than this value, then the configuration recovery loop will exit, if the occupancies have also converged (see the `occupancies_tol` argument).
+
+ * **occupancies\_tol** ([*float*](https://docs.python.org/3/library/functions.html#float)) – Numerical tolerance for convergence of the average orbital occupancies. If the maximum change in absolute value of the average occupancy of an orbital between iterations is smaller than this value, then the configuration recovery loop will exit, if the energy has also converged (see the `energy_tol` argument).
+
+ * **max\_iterations** ([*int*](https://docs.python.org/3/library/functions.html#int)) – Limit on the number of configuration recovery iterations.
+
+ * **sci\_solver** ([*Callable*](https://docs.python.org/3/library/typing.html#typing.Callable)*\[\[*[*list*](https://docs.python.org/3/library/stdtypes.html#list)*\[*[*tuple*](https://docs.python.org/3/library/stdtypes.html#tuple)*\[*[*ndarray*](https://numpy.org/doc/stable/reference/generated/numpy.ndarray.html#numpy.ndarray)*,* [*ndarray*](https://numpy.org/doc/stable/reference/generated/numpy.ndarray.html#numpy.ndarray)*]],* [*ndarray*](https://numpy.org/doc/stable/reference/generated/numpy.ndarray.html#numpy.ndarray)*,* [*ndarray*](https://numpy.org/doc/stable/reference/generated/numpy.ndarray.html#numpy.ndarray)*,* [*int*](https://docs.python.org/3/library/functions.html#int)*,* [*tuple*](https://docs.python.org/3/library/stdtypes.html#tuple)*\[*[*int*](https://docs.python.org/3/library/functions.html#int)*,* [*int*](https://docs.python.org/3/library/functions.html#int)*]],* [*list*](https://docs.python.org/3/library/stdtypes.html#list)*\[SCIResult]] | None*) –
+
+ Selected configuration interaction solver function.
+
+ Inputs:
+
+ * List of pairs (strings\_a, strings\_b) of arrays of spin-alpha CI strings and spin-beta CI strings whose Cartesian product give the basis of the subspace in which to perform a diagonalization. A list is passed to allow the solver function to perform the diagonalizations in parallel.
+ * One-body tensor of the Hamiltonian.
+ * Two-body tensor of the Hamiltonian.
+ * The number of spatial orbitals.
+ * A pair (n\_alpha, n\_beta) indicating the numbers of alpha and beta electrons.
+
+ Output: List of (energy, sci\_state, occupancies) triplets, where each triplet contains the result of the corresponding diagonalization.
+
+ * **symmetrize\_spin** ([*bool*](https://docs.python.org/3/library/functions.html#bool)) – Whether to always merge spin-alpha and spin-beta CI strings into a single list, so that the diagonalization subspace is invariant with respect to the exchange of spin alpha with spin beta.
+
+ * **max\_dim** ([*int*](https://docs.python.org/3/library/functions.html#int) *|*[*tuple*](https://docs.python.org/3/library/stdtypes.html#tuple)*\[*[*int*](https://docs.python.org/3/library/functions.html#int)*,* [*int*](https://docs.python.org/3/library/functions.html#int)*] | None*) –
+
+ Limit on the dimension of the spin sectors of the SCI subspace. It can be either:
+
+ * A tuple `(max_dim_a, max_dim_b)` of integers giving separate limits for the spin-alpha and spin-beta sectors. In this case, the dimension of the SCI subspace won’t exceed `max_dim_a * max_dim_b`.
+ * A single integer specifying a limit that will be used for both the spin-alpha and spin-beta sectors. In this case, the dimension of the SCI subspace won’t exceed `max_dim**2`.
+ * `None`, in which case no limit is set.
+
+ Note that the dimension limit is set on the spin-sector(s), while the full dimension of the SCI subspace is the product of the dimensions of the individual spin sectors.
+
+ * **include\_configurations** ([*list*](https://docs.python.org/3/library/stdtypes.html#list)*\[*[*int*](https://docs.python.org/3/library/functions.html#int)*] |* [*tuple*](https://docs.python.org/3/library/stdtypes.html#tuple)*\[*[*list*](https://docs.python.org/3/library/stdtypes.html#list)*\[*[*int*](https://docs.python.org/3/library/functions.html#int)*],* [*list*](https://docs.python.org/3/library/stdtypes.html#list)*\[*[*int*](https://docs.python.org/3/library/functions.html#int)*]] |* [*ndarray*](https://numpy.org/doc/stable/reference/generated/numpy.ndarray.html#numpy.ndarray) *| None*) – Configurations to always include in the diagonalization subspace. You can specify either a single list of single-spin strings to use for both spin sectors, or a pair (alpha\_strings, beta\_strings) of lists of single-spin strings, one for each spin.
+
+ * **initial\_occupancies** ([*tuple*](https://docs.python.org/3/library/stdtypes.html#tuple)*\[*[*ndarray*](https://numpy.org/doc/stable/reference/generated/numpy.ndarray.html#numpy.ndarray)*,* [*ndarray*](https://numpy.org/doc/stable/reference/generated/numpy.ndarray.html#numpy.ndarray)*] | None*) – Initial guess for the average occupancies of the orbitals.
+
+ * **carryover\_threshold** ([*float*](https://docs.python.org/3/library/functions.html#float)) – Threshold for carrying over bitstrings with large CI weight from one iteration of configuration recovery to the next. All single-spin CI strings associated with configurations whose coefficient has absolute value greater than this threshold will be included in the diagonalization subspace for the next iteration. A smaller threshold will retain more configurations, leading to a larger subspace and hence a more costly diagonalization.
+
+ * **callback** ([*Callable*](https://docs.python.org/3/library/typing.html#typing.Callable)*\[\[*[*list*](https://docs.python.org/3/library/stdtypes.html#list)*\[SCIResult]], None] | None*) – A callback function to be called after each configuration recovery iteration. The function will be passed the output of the sci\_solver function, which is a list of (energy, sci\_state, occupancies) triplets, where each triplet contains the result of a diagonalization.
+
+ * **seed** ([*Generator*](https://numpy.org/doc/stable/reference/random/generator.html#numpy.random.Generator) *|*[*int*](https://docs.python.org/3/library/functions.html#int) *| None*) – A seed for the pseudorandom number generator.
+
+ **Returns**
+
+ The estimate of the energy and the SCI state with that energy.
+
+ **Return type**
+
+ *SCIResult*
+
+
+### enlarge\_batch\_from\_transitions
+
+
+ Apply the set of transition operators to the configurations represented in `bitstring_matrix`.
+
+ **Parameters**
+
+ * **bitstring\_matrix** ([*ndarray*](https://numpy.org/doc/stable/reference/generated/numpy.ndarray.html#numpy.ndarray)) – A 2D array of `bool` representations of bit values such that each row represents a single bitstring.
+ * **transition\_operators** ([*ndarray*](https://numpy.org/doc/stable/reference/generated/numpy.ndarray.html#numpy.ndarray)) – A 1D or 2D array `I`, `+`, `-`, and `n` strings representing the action of the identity, creation, annihilation, or number operators. Each row represents a transition operator.
+
+ **Returns**
+
+ Bitstring matrix representing the augmented set of electronic configurations after applying the excitation operators.
+
+ **Return type**
+
+ [*ndarray*](https://numpy.org/doc/stable/reference/generated/numpy.ndarray.html#numpy.ndarray)
+
+
+### solve\_fermion
+
+
+ Approximate the ground state given molecular integrals and a set of electronic configurations.
+
+ **Parameters**
+
+ * **bitstring\_matrix** ([*tuple*](https://docs.python.org/3/library/stdtypes.html#tuple)*\[*[*ndarray*](https://numpy.org/doc/stable/reference/generated/numpy.ndarray.html#numpy.ndarray)*,* [*ndarray*](https://numpy.org/doc/stable/reference/generated/numpy.ndarray.html#numpy.ndarray)*] |* [*ndarray*](https://numpy.org/doc/stable/reference/generated/numpy.ndarray.html#numpy.ndarray)) –
+
+ A set of configurations defining the subspace onto which the Hamiltonian will be projected and diagonalized.
+
+ This may be specified in two ways:
+
+ * Bitstring matrix: A 2D `numpy.ndarray` of `bool` values, where each row represents a bitstring. The spin-up configurations should occupy column indices `(N, N/2]`, and the spin-down configurations should occupy column indices `(N/2, 0]`, where `N` is the number of qubits.
+ * CI strings: A tuple of two sequences containing integer representations of spin-up and spin-down determinants, respectively. The expected format is `([a_str_0, ..., a_str_N], [b_str_0, ..., b_str_M])`.
+
+ * **hcore** ([*ndarray*](https://numpy.org/doc/stable/reference/generated/numpy.ndarray.html#numpy.ndarray)) – Core Hamiltonian matrix representing single-electron integrals
+
+ * **eri** ([*ndarray*](https://numpy.org/doc/stable/reference/generated/numpy.ndarray.html#numpy.ndarray)) – Electronic repulsion integrals representing two-electron integrals
+
+ * **open\_shell** ([*bool*](https://docs.python.org/3/library/functions.html#bool)) – A flag specifying whether configurations from the left and right halves of the bitstrings should be kept separate. If `False`, CI strings from the left and right halves of the bitstrings are combined into a single set of unique configurations and used for both the alpha and beta subspaces.
+
+ * **spin\_sq** ([*float*](https://docs.python.org/3/library/functions.html#float) *| None*) – Target value for the total spin squared for the ground state, $S^2 = s(s + 1)$. If `None`, no spin will be imposed.
+
+ * **shift** ([*float*](https://docs.python.org/3/library/functions.html#float)) – Level shift for states which have different spin. $(H + shift * S^2)|ψ> = E|ψ>$
+
+ * **\*\*kwargs** – Keyword arguments to pass to [pyscf.fci.selected\_ci.kernel\_fixed\_space](https://pyscf.org/pyscf_api_docs/pyscf.fci.html#pyscf.fci.selected_ci.kernel_fixed_space)
+
+ **Returns**
+
+ * Minimum energy from SCI calculation
+ * The SCI ground state
+ * Tuple containing orbital occupancies for spin-up and spin-down orbitals. Formatted as: `(array([occ_a_0, ..., occ_a_N]), array([occ_b_0, ..., occ_b_N]))`
+ * Expectation value of spin-squared
+
+ **Return type**
+
+ [tuple](https://docs.python.org/3/library/stdtypes.html#tuple)\[[float](https://docs.python.org/3/library/functions.html#float), [*SCIState*](#qiskit_addon_sqd.fermion.SCIState "qiskit_addon_sqd.fermion.SCIState"), [tuple](https://docs.python.org/3/library/stdtypes.html#tuple)\[[*ndarray*](https://numpy.org/doc/stable/reference/generated/numpy.ndarray.html#numpy.ndarray), [*ndarray*](https://numpy.org/doc/stable/reference/generated/numpy.ndarray.html#numpy.ndarray)], [float](https://docs.python.org/3/library/functions.html#float)]
+
+
+### solve\_sci
+
+
+ Diagonalize Hamiltonian in subspace defined by CI strings.
+
+ **Parameters**
+
+ * **ci\_strings** ([*tuple*](https://docs.python.org/3/library/stdtypes.html#tuple)*\[*[*ndarray*](https://numpy.org/doc/stable/reference/generated/numpy.ndarray.html#numpy.ndarray)*,* [*ndarray*](https://numpy.org/doc/stable/reference/generated/numpy.ndarray.html#numpy.ndarray)*]*) – Pair (strings\_a, strings\_b) of arrays of spin-alpha CI strings and spin-beta CI strings whose Cartesian product give the basis of the subspace in which to perform a diagonalization.
+
+ * **one\_body\_tensor** ([*ndarray*](https://numpy.org/doc/stable/reference/generated/numpy.ndarray.html#numpy.ndarray)) – The one-body tensor of the Hamiltonian.
+
+ * **two\_body\_tensor** ([*ndarray*](https://numpy.org/doc/stable/reference/generated/numpy.ndarray.html#numpy.ndarray)) – The two-body tensor of the Hamiltonian.
+
+ * **norb** ([*int*](https://docs.python.org/3/library/functions.html#int)) – The number of spatial orbitals.
+
+ * **nelec** ([*tuple*](https://docs.python.org/3/library/stdtypes.html#tuple)*\[*[*int*](https://docs.python.org/3/library/functions.html#int)*,* [*int*](https://docs.python.org/3/library/functions.html#int)*]*) – The numbers of alpha and beta electrons.
+
+ * **spin\_sq** ([*float*](https://docs.python.org/3/library/functions.html#float) *| None*) – Target value for the total spin squared for the ground state. If `None`, no spin will be imposed.
+
+ * **\*\*kwargs** –
+
+ Keyword arguments to pass to [pyscf.fci.selected\_ci.kernel\_fixed\_space](https://pyscf.org/pyscf_api_docs/pyscf.fci.html#pyscf.fci.selected_ci.kernel_fixed_space)
+
+ **Returns**
+
+ The diagonalization result.
+
+ **Return type**
+
+ *SCIResult*
+
+
+### solve\_sci\_batch
+
+
+ Diagonalize Hamiltonian in subspaces.
+
+ **Parameters**
+
+ * **ci\_strings** ([*list*](https://docs.python.org/3/library/stdtypes.html#list)*\[*[*tuple*](https://docs.python.org/3/library/stdtypes.html#tuple)*\[*[*ndarray*](https://numpy.org/doc/stable/reference/generated/numpy.ndarray.html#numpy.ndarray)*,* [*ndarray*](https://numpy.org/doc/stable/reference/generated/numpy.ndarray.html#numpy.ndarray)*]]*) – List of pairs (strings\_a, strings\_b) of arrays of spin-alpha CI strings and spin-beta CI strings whose Cartesian product give the basis of the subspace in which to perform a diagonalization.
+
+ * **one\_body\_tensor** ([*ndarray*](https://numpy.org/doc/stable/reference/generated/numpy.ndarray.html#numpy.ndarray)) – The one-body tensor of the Hamiltonian.
+
+ * **two\_body\_tensor** ([*ndarray*](https://numpy.org/doc/stable/reference/generated/numpy.ndarray.html#numpy.ndarray)) – The two-body tensor of the Hamiltonian.
+
+ * **norb** ([*int*](https://docs.python.org/3/library/functions.html#int)) – The number of spatial orbitals.
+
+ * **nelec** ([*tuple*](https://docs.python.org/3/library/stdtypes.html#tuple)*\[*[*int*](https://docs.python.org/3/library/functions.html#int)*,* [*int*](https://docs.python.org/3/library/functions.html#int)*]*) – The numbers of alpha and beta electrons.
+
+ * **spin\_sq** ([*float*](https://docs.python.org/3/library/functions.html#float) *| None*) – Target value for the total spin squared for the ground state. If `None`, no spin will be imposed.
+
+ * **\*\*kwargs** –
+
+ Keyword arguments to pass to [pyscf.fci.selected\_ci.kernel\_fixed\_space](https://pyscf.org/pyscf_api_docs/pyscf.fci.html#pyscf.fci.selected_ci.kernel_fixed_space)
+
+ **Returns**
+
+ The results of the diagonalizations in the subspaces given by ci\_strings.
+
+ **Return type**
+
+ [list](https://docs.python.org/3/library/stdtypes.html#list)\[*SCIResult*]
+
+
+### optimize\_orbitals
+
+
+ Optimize orbitals to produce a minimal ground state.
+
+ The process involves iterating over 3 steps:
+
+ **For `num_iters` iterations:**
+
+ * Rotate the integrals with respect to the parameters, `k_flat`
+ * Diagonalize and approximate the groundstate energy and wavefunction amplitudes
+ * Optimize `k_flat` using gradient descent and the wavefunction amplitudes found in Step 2
+
+ Refer to [Sec. II A 4](https://arxiv.org/pdf/2405.05068) for more detailed discussion on this orbital optimization technique.
+
+ **Parameters**
+
+ * **bitstring\_matrix** ([*tuple*](https://docs.python.org/3/library/stdtypes.html#tuple)*\[*[*ndarray*](https://numpy.org/doc/stable/reference/generated/numpy.ndarray.html#numpy.ndarray)*,* [*ndarray*](https://numpy.org/doc/stable/reference/generated/numpy.ndarray.html#numpy.ndarray)*] |* [*ndarray*](https://numpy.org/doc/stable/reference/generated/numpy.ndarray.html#numpy.ndarray)) –
+
+ A set of configurations defining the subspace onto which the Hamiltonian will be projected and diagonalized.
+
+ This may be specified in two ways:
+
+ * Bitstring matrix: A 2D `numpy.ndarray` of `bool` values, where each row represents a bitstring. The spin-up configurations should occupy column indices `(N, N/2]`, and the spin-down configurations should occupy column indices `(N/2, 0]`, where `N` is the number of qubits.
+ * CI strings: A tuple of two sequences containing integer representations of spin-up and spin-down determinants, respectively. The expected format is `([a_str_0, ..., a_str_N], [b_str_0, ..., b_str_M])`.
+
+ * **hcore** ([*ndarray*](https://numpy.org/doc/stable/reference/generated/numpy.ndarray.html#numpy.ndarray)) – Core Hamiltonian matrix representing single-electron integrals
+
+ * **eri** ([*ndarray*](https://numpy.org/doc/stable/reference/generated/numpy.ndarray.html#numpy.ndarray)) – Electronic repulsion integrals representing two-electron integrals
+
+ * **k\_flat** ([*ndarray*](https://numpy.org/doc/stable/reference/generated/numpy.ndarray.html#numpy.ndarray)) – 1D array defining the orbital transform, `K`. The array should specify the upper triangle of the anti-symmetric transform operator in row-major order, excluding the diagonal.
+
+ * **open\_shell** ([*bool*](https://docs.python.org/3/library/functions.html#bool)) – A flag specifying whether configurations from the left and right halves of the bitstrings should be kept separate. If `False`, CI strings from the left and right halves of the bitstrings are combined into a single set of unique configurations and used for both the alpha and beta subspaces.
+
+ * **spin\_sq** ([*float*](https://docs.python.org/3/library/functions.html#float)) – Target value for the total spin squared for the ground state
+
+ * **num\_iters** ([*int*](https://docs.python.org/3/library/functions.html#int)) – The number of iterations of orbital optimization to perform
+
+ * **num\_steps\_grad** ([*int*](https://docs.python.org/3/library/functions.html#int)) – The number of steps of gradient descent to perform during each optimization iteration
+
+ * **learning\_rate** ([*float*](https://docs.python.org/3/library/functions.html#float)) – The learning rate to use during gradient descent
+
+ * **\*\*kwargs** –
+
+ Keyword arguments to pass to [pyscf.fci.selected\_ci.kernel\_fixed\_space](https://pyscf.org/pyscf_api_docs/pyscf.fci.html#pyscf.fci.selected_ci.kernel_fixed_space)
+
+ **Returns**
+
+ * The groundstate energy found during the last optimization iteration
+ * An optimized 1D array defining the orbital transform
+ * Tuple containing orbital occupancies for spin-up and spin-down orbitals. Formatted as: `(array([occ_a_0, ..., occ_a_N]), array([occ_b_0, ..., occ_b_N]))`
+
+ **Return type**
+
+ [tuple](https://docs.python.org/3/library/stdtypes.html#tuple)\[[float](https://docs.python.org/3/library/functions.html#float), [*ndarray*](https://numpy.org/doc/stable/reference/generated/numpy.ndarray.html#numpy.ndarray), [tuple](https://docs.python.org/3/library/stdtypes.html#tuple)\[[*ndarray*](https://numpy.org/doc/stable/reference/generated/numpy.ndarray.html#numpy.ndarray), [*ndarray*](https://numpy.org/doc/stable/reference/generated/numpy.ndarray.html#numpy.ndarray)]]
+
+
+### rotate\_integrals
+
+
+ Perform a similarity transform on the integrals.
+
+ The transformation is described as:
+
+$$
+\hat{\widetilde{H}} = \hat{U^{\dagger}}(k)\hat{H}\hat{U}(k)
+$$
+
+ For more information on how $\hat{U}$ and $\hat{U^{\dagger}}$ are generated from `k_flat` and applied to the one- and two-body integrals, refer to [Sec. II A 4](https://arxiv.org/pdf/2405.05068).
+
+ **Parameters**
+
+ * **hcore** ([*ndarray*](https://numpy.org/doc/stable/reference/generated/numpy.ndarray.html#numpy.ndarray)) – Core Hamiltonian matrix representing single-electron integrals
+ * **eri** ([*ndarray*](https://numpy.org/doc/stable/reference/generated/numpy.ndarray.html#numpy.ndarray)) – Electronic repulsion integrals representing two-electron integrals
+ * **k\_flat** ([*ndarray*](https://numpy.org/doc/stable/reference/generated/numpy.ndarray.html#numpy.ndarray)) – 1D array defining the orbital transform, `K`. The array should specify the upper triangle of the anti-symmetric transform operator in row-major order, excluding the diagonal.
+
+ **Returns**
+
+ * The rotated core Hamiltonian matrix
+ * The rotated ERI matrix
+
+ **Return type**
+
+ [tuple](https://docs.python.org/3/library/stdtypes.html#tuple)\[[*ndarray*](https://numpy.org/doc/stable/reference/generated/numpy.ndarray.html#numpy.ndarray), [*ndarray*](https://numpy.org/doc/stable/reference/generated/numpy.ndarray.html#numpy.ndarray)]
+
+
diff --git a/docs/api/qiskit-addon-sqd/0.12/index.mdx b/docs/api/qiskit-addon-sqd/0.12/index.mdx
new file mode 100644
index 000000000000..bc7070e827d1
--- /dev/null
+++ b/docs/api/qiskit-addon-sqd/0.12/index.mdx
@@ -0,0 +1,15 @@
+---
+title: Sample-based quantum diagonalization (SQD) API documentation (v0.12)
+description: Index of all the modules in qiskit-addon-sqd v0.12.
+---
+
+
+
+# `qiskit-addon-sqd` API reference
+
+* [Configuration recovery (`qiskit_addon_sqd.configuration_recovery`)](configuration-recovery)
+* [Counts (`qiskit_addon_sqd.counts`)](counts)
+* [Fermion (`qiskit_addon_sqd.fermion`)](fermion)
+* [Qubit (`qiskit_addon_sqd.qubit`)](qubit)
+* [Subsampling (`qiskit_addon_sqd.subsampling`)](subsampling)
+
diff --git a/docs/api/qiskit-addon-sqd/0.12/qubit.mdx b/docs/api/qiskit-addon-sqd/0.12/qubit.mdx
new file mode 100644
index 000000000000..3aeb5c19b3d8
--- /dev/null
+++ b/docs/api/qiskit-addon-sqd/0.12/qubit.mdx
@@ -0,0 +1,144 @@
+---
+title: qubit (v0.12)
+description: API reference for qiskit_addon_sqd.qubit in qiskit-addon-sqd v0.12
+in_page_toc_min_heading_level: 2
+python_api_type: module
+python_api_name: qiskit_addon_sqd.qubit
+---
+
+
+
+
+
+# Qubit
+
+`qiskit_addon_sqd.qubit`
+
+Functions for handling quantum samples.
+
+### solve\_qubit
+
+
+ Find the energies and eigenstates of a Hamiltonian projected into a subspace.
+
+ The subspace is defined by a collection of computational basis states which are specified by the bitstrings (rows) in the `bitstring_matrix`. The `bitstring_matrix` will be sorted and de-duplicated in this function, as the underlying solver requires that structure.
+
+ This function calls [scipy.sparse.linalg.eigsh](https://docs.scipy.org/doc/scipy/reference/generated/scipy.sparse.linalg.eigsh.html#eigsh) for the diagonalization.
+
+ **Parameters**
+
+ * **bitstring\_matrix** ([*ndarray*](https://numpy.org/doc/stable/reference/generated/numpy.ndarray.html#numpy.ndarray)) – A 2D array of `bool` representations of bit values such that each row represents a single bitstring. This set of bitstrings specifies the subspace into which the `hamiltonian` will be projected and diagonalized.
+
+ * **hamiltonian** ([*SparsePauliOp*](/docs/api/qiskit/qiskit.quantum_info.SparsePauliOp)) – A Hamiltonian specified as a Pauli operator.
+
+ * **verbose** ([*bool*](https://docs.python.org/3/library/functions.html#bool)) – Whether to print the stage of the subroutine.
+
+ * **\*\*scipy\_kwargs** –
+
+ Keyword arguments to be passed to [scipy.sparse.linalg.eigsh](https://docs.scipy.org/doc/scipy/reference/generated/scipy.sparse.linalg.eigsh.html#eigsh).
+
+ **Returns**
+
+ * 1D array with the eigenvalues
+ * 2D array with the eigenvectors. Each column represents an eigenvector.
+
+ **Raises**
+
+ [**ValueError**](https://docs.python.org/3/library/exceptions.html#ValueError) – Bitstrings (rows) in `bitstring_matrix` must have length \< `64`.
+
+ **Return type**
+
+ [tuple](https://docs.python.org/3/library/stdtypes.html#tuple)\[[*ndarray*](https://numpy.org/doc/stable/reference/generated/numpy.ndarray.html#numpy.ndarray), [*ndarray*](https://numpy.org/doc/stable/reference/generated/numpy.ndarray.html#numpy.ndarray)]
+
+
+### project\_operator\_to\_subspace
+
+
+ Project a Pauli operator onto a Hilbert subspace defined by the computational basis states (rows) in `bitstring_matrix`.
+
+ The output sparse matrix, `A`, represents an `NxN` matrix s.t. `N` is the number of rows in `bitstring_matrix`. The rows of `A` represent the input configurations, and the columns represent the connected component associated with the configuration in the corresponding row. The non-zero elements of the matrix represent the complex amplitudes associated with the connected components.
+
+
+ The bitstrings in the `bitstring_matrix` must be unique and sorted in ascending order according to their unsigned integer representation. Otherwise the projection will return wrong results. This function does not explicitly check for uniqueness and order because this can be rather time consuming. See [`qiskit_addon_sqd.qubit.sort_and_remove_duplicates()`](#qiskit_addon_sqd.qubit.sort_and_remove_duplicates "qiskit_addon_sqd.qubit.sort_and_remove_duplicates") for a simple way to ensure your bitstring matrix is well-formatted.
+
+
+
+ This function relies on `jax` to efficiently perform some calculations. `jax` converts the bit arrays to `int64_t`, which means the bit arrays in `bitstring_matrix` may not have length greater than `63`.
+
+
+ **Parameters**
+
+ * **bitstring\_matrix** ([*ndarray*](https://numpy.org/doc/stable/reference/generated/numpy.ndarray.html#numpy.ndarray)) – A 2D array of `bool` representations of bit values such that each row represents a single bitstring. This set of bitstrings specifies the subspace into which the `hamiltonian` will be projected and diagonalized.
+ * **hamiltonian** ([*SparsePauliOp*](/docs/api/qiskit/qiskit.quantum_info.SparsePauliOp)) – A Pauli operator to project onto a Hilbert subspace defined by `bitstring_matrix`.
+ * **verbose** ([*bool*](https://docs.python.org/3/library/functions.html#bool)) – Whether to print the stage of the subroutine.
+
+ **Returns**
+
+ A [scipy.sparse.coo\_matrix](https://docs.scipy.org/doc/scipy/reference/generated/scipy.sparse.coo_matrix.html#coo-matrix) representing the operator projected in the subspace. The rows represent the input configurations, and the columns represent the connected component associated with the configuration in the corresponding row. The non-zero elements of the matrix represent the complex amplitudes associated with the pairs of connected components.
+
+ **Raises**
+
+ [**ValueError**](https://docs.python.org/3/library/exceptions.html#ValueError) – Bitstrings (rows) in `bitstring_matrix` must have length \< `64`.
+
+ **Return type**
+
+ *spmatrix*
+
+
+### sort\_and\_remove\_duplicates
+
+
+ Sort a bitstring matrix and remove duplicate entries.
+
+ The lowest bitstring values will be placed in the lowest-indexed rows.
+
+ **Parameters**
+
+ **bitstring\_matrix** ([*ndarray*](https://numpy.org/doc/stable/reference/generated/numpy.ndarray.html#numpy.ndarray)) – A 2D array of `bool` representations of bit values such that each row represents a single bitstring.
+
+ **Returns**
+
+ Sorted version of `bitstring_matrix` without repeated rows.
+
+ **Return type**
+
+ [*ndarray*](https://numpy.org/doc/stable/reference/generated/numpy.ndarray.html#numpy.ndarray)
+
+
+### matrix\_elements\_from\_pauli
+
+
+ Find the sparse matrix elements of a Pauli operator in the subspace defined by the bitstrings.
+
+ The sparse matrix, `A`, defined by the outputs represents an `NxN` matrix s.t. `N` is the number of rows in `bitstring_matrix`. The rows of `A` represent the input configurations, and the columns represent the connected component associated with the configuration in the corresponding row. The output arrays define the sparse matrix, `A`, as follows:
+
+ `A[rows[k], cols[k]] = amplutides[k]`.
+
+
+ The bitstrings in the `bitstring_matrix` must be unique and sorted in ascending order according to their unsigned integer representation. Otherwise the projection will return wrong results. This function does not explicitly check for uniqueness and order because this can be rather time consuming. See [`qiskit_addon_sqd.qubit.sort_and_remove_duplicates()`](#qiskit_addon_sqd.qubit.sort_and_remove_duplicates "qiskit_addon_sqd.qubit.sort_and_remove_duplicates") for a simple way to ensure your bitstring matrix is well-formatted.
+
+
+
+ This function relies on `jax` to efficiently perform some calculations. `jax` converts the bit arrays to `int64_t`, which means the bit arrays in `bitstring_matrix` may not have length greater than `63`.
+
+
+ **Parameters**
+
+ * **bitstring\_matrix** ([*ndarray*](https://numpy.org/doc/stable/reference/generated/numpy.ndarray.html#numpy.ndarray)) – A 2D array of `bool` representations of bit values such that each row represents a single bitstring. The bitstrings in the matrix must be sorted according to their unsigned integer representations. Otherwise the projection will return wrong results.
+ * **pauli** ([*Pauli*](/docs/api/qiskit/qiskit.quantum_info.Pauli)) – A Pauli operator for which to find connected elements
+
+ **Returns**
+
+ * The complex amplitudes corresponding to the nonzero matrix elements
+ * The row indices corresponding to non-zero matrix elements
+ * The column indices corresponding to non-zero matrix elements
+
+ **Raises**
+
+ [**ValueError**](https://docs.python.org/3/library/exceptions.html#ValueError) – Bitstrings (rows) in `bitstring_matrix` must have length \< `64`.
+
+ **Return type**
+
+ [tuple](https://docs.python.org/3/library/stdtypes.html#tuple)\[[*ndarray*](https://numpy.org/doc/stable/reference/generated/numpy.ndarray.html#numpy.ndarray), [*ndarray*](https://numpy.org/doc/stable/reference/generated/numpy.ndarray.html#numpy.ndarray), [*ndarray*](https://numpy.org/doc/stable/reference/generated/numpy.ndarray.html#numpy.ndarray)]
+
+
diff --git a/docs/api/qiskit-addon-sqd/0.12/subsampling.mdx b/docs/api/qiskit-addon-sqd/0.12/subsampling.mdx
new file mode 100644
index 000000000000..5ded9f343538
--- /dev/null
+++ b/docs/api/qiskit-addon-sqd/0.12/subsampling.mdx
@@ -0,0 +1,112 @@
+---
+title: subsampling (v0.12)
+description: API reference for qiskit_addon_sqd.subsampling in qiskit-addon-sqd v0.12
+in_page_toc_min_heading_level: 2
+python_api_type: module
+python_api_name: qiskit_addon_sqd.subsampling
+---
+
+
+
+
+
+# Subsampling
+
+`qiskit_addon_sqd.subsampling`
+
+Functions for creating batches of samples from a bitstring matrix.
+
+### subsample
+
+
+ Subsample batches of bit arrays from an input `bitstring_matrix`.
+
+ Each individual batch will be sampled without replacement from the input `bitstring_matrix`. Samples will be replaced after creation of each batch, so different batches may contain identical samples.
+
+ **Parameters**
+
+ * **bitstring\_matrix** ([*ndarray*](https://numpy.org/doc/stable/reference/generated/numpy.ndarray.html#numpy.ndarray)) – A 2D array of `bool` representations of bit values such that each row represents a single bitstring.
+ * **probabilities** ([*ndarray*](https://numpy.org/doc/stable/reference/generated/numpy.ndarray.html#numpy.ndarray)) – A 1D array specifying a probability distribution over the bitstrings
+ * **samples\_per\_batch** ([*int*](https://docs.python.org/3/library/functions.html#int)) – The number of samples to draw for each batch
+ * **num\_batches** ([*int*](https://docs.python.org/3/library/functions.html#int)) – The number of batches to generate
+ * **rand\_seed** ([*Generator*](https://numpy.org/doc/stable/reference/random/generator.html#numpy.random.Generator) *|*[*int*](https://docs.python.org/3/library/functions.html#int) *| None*) – A seed to control random behavior
+
+ **Returns**
+
+ A list of bitstring matrices subsampled from the input bitstring matrix.
+
+ **Raises**
+
+ * [**ValueError**](https://docs.python.org/3/library/exceptions.html#ValueError) – The number of elements in `probabilities` must equal the number of rows in `bitstring_matrix`.
+ * [**ValueError**](https://docs.python.org/3/library/exceptions.html#ValueError) – Samples per batch and number of batches must be positive integers.
+
+ **Return type**
+
+ [list](https://docs.python.org/3/library/stdtypes.html#list)\[[*ndarray*](https://numpy.org/doc/stable/reference/generated/numpy.ndarray.html#numpy.ndarray)]
+
+
+### postselect\_and\_subsample
+
+
+ Subsample batches of bit arrays with correct hamming weight from an input `bitstring_matrix`.
+
+ Bitstring samples with incorrect hamming weight on either their left or right half will not be sampled.
+
+ Each individual batch will be sampled without replacement from the input `bitstring_matrix`. Samples will be replaced after creation of each batch, so different batches may contain identical samples.
+
+
+ The function `qiskit_addon_sqd.subsampling.postselect_and_subsample()` is deprecated as of qiskit-addon-sqd 0.12.0. It will be removed no earlier than v0.13.0. Instead, use the `postselect_by_hamming_right_and_left` and `subsample` functions.
+
+
+ **Parameters**
+
+ * **bitstring\_matrix** ([*ndarray*](https://numpy.org/doc/stable/reference/generated/numpy.ndarray.html#numpy.ndarray)) – A 2D array of `bool` representations of bit values such that each row represents a single bitstring.
+ * **probabilities** ([*ndarray*](https://numpy.org/doc/stable/reference/generated/numpy.ndarray.html#numpy.ndarray)) – A 1D array specifying a probability distribution over the bitstrings
+ * **hamming\_right** ([*int*](https://docs.python.org/3/library/functions.html#int)) – The target hamming weight for the right half of sampled bitstrings
+ * **hamming\_left** ([*int*](https://docs.python.org/3/library/functions.html#int)) – The target hamming weight for the left half of sampled bitstrings
+ * **samples\_per\_batch** ([*int*](https://docs.python.org/3/library/functions.html#int)) – The number of samples to draw for each batch
+ * **num\_batches** ([*int*](https://docs.python.org/3/library/functions.html#int)) – The number of batches to generate
+ * **rand\_seed** ([*Generator*](https://numpy.org/doc/stable/reference/random/generator.html#numpy.random.Generator) *|*[*int*](https://docs.python.org/3/library/functions.html#int) *| None*) – A seed to control random behavior
+
+ **Returns**
+
+ A list of bitstring matrices with correct hamming weight subsampled from the input bitstring matrix
+
+ **Raises**
+
+ * [**ValueError**](https://docs.python.org/3/library/exceptions.html#ValueError) – The number of elements in `probabilities` must equal the number of rows in `bitstring_matrix`.
+ * [**ValueError**](https://docs.python.org/3/library/exceptions.html#ValueError) – Hamming weights must be non-negative integers.
+ * [**ValueError**](https://docs.python.org/3/library/exceptions.html#ValueError) – Samples per batch and number of batches must be positive integers.
+
+ **Return type**
+
+ [list](https://docs.python.org/3/library/stdtypes.html#list)\[[*ndarray*](https://numpy.org/doc/stable/reference/generated/numpy.ndarray.html#numpy.ndarray)]
+
+
+### postselect\_by\_hamming\_right\_and\_left
+
+
+ Postselect bitstrings based on desired Hamming weight on right and left halves.
+
+ **Parameters**
+
+ * **bitstring\_matrix** ([*ndarray*](https://numpy.org/doc/stable/reference/generated/numpy.ndarray.html#numpy.ndarray)) – A 2D array of `bool` representations of bit values such that each row represents a single bitstring.
+ * **probabilities** ([*ndarray*](https://numpy.org/doc/stable/reference/generated/numpy.ndarray.html#numpy.ndarray)) – A 1D array specifying a probability distribution over the bitstrings
+ * **hamming\_right** ([*int*](https://docs.python.org/3/library/functions.html#int)) – The target hamming weight for the right half of sampled bitstrings
+ * **hamming\_left** ([*int*](https://docs.python.org/3/library/functions.html#int)) – The target hamming weight for the left half of sampled bitstrings
+
+ **Returns**
+
+ Postselected bitstring matrix and probabilities. The new bitstring matrix contains only those bitstrings from the original matrix that have the desired Hamming weight on the right and left halves, and the new probabilities are constructed by taking the original probabilities corresponding to the postselected bitstrings and rescaling them to sum to one.
+
+ **Raises**
+
+ * [**ValueError**](https://docs.python.org/3/library/exceptions.html#ValueError) – Hamming weights must be non-negative integers.
+ * [**ValueError**](https://docs.python.org/3/library/exceptions.html#ValueError) – The number of columns in `bitstring_matrix` must be even.
+ * [**ValueError**](https://docs.python.org/3/library/exceptions.html#ValueError) – The number of elements in `probabilities` must equal the number of rows in `bitstring_matrix`.
+
+ **Return type**
+
+ [tuple](https://docs.python.org/3/library/stdtypes.html#tuple)\[[*ndarray*](https://numpy.org/doc/stable/reference/generated/numpy.ndarray.html#numpy.ndarray), [*ndarray*](https://numpy.org/doc/stable/reference/generated/numpy.ndarray.html#numpy.ndarray)]
+
+
diff --git a/docs/api/qiskit-addon-sqd/_package.json b/docs/api/qiskit-addon-sqd/_package.json
index 1f226e87545d..2e769efbf10d 100644
--- a/docs/api/qiskit-addon-sqd/_package.json
+++ b/docs/api/qiskit-addon-sqd/_package.json
@@ -1,4 +1,4 @@
{
"name": "qiskit-addon-sqd",
- "version": "0.12.1"
+ "version": "0.13.1"
}
diff --git a/docs/api/qiskit-addon-sqd/_toc.json b/docs/api/qiskit-addon-sqd/_toc.json
index ed5c0c5b2979..0b5a0466148f 100644
--- a/docs/api/qiskit-addon-sqd/_toc.json
+++ b/docs/api/qiskit-addon-sqd/_toc.json
@@ -37,5 +37,7 @@
}
],
"collapsed": true,
- "untranslatable": true
+ "untranslatable": true,
+ "parentUrl": "/docs/addons/qiskit-addon-sqd",
+ "parentLabel": "Sample-based quantum diagonalization (SQD)"
}
diff --git a/docs/api/qiskit-addon-sqd/configuration-recovery.mdx b/docs/api/qiskit-addon-sqd/configuration-recovery.mdx
index d5652c9c554b..73ce1b2b0ffb 100644
--- a/docs/api/qiskit-addon-sqd/configuration-recovery.mdx
+++ b/docs/api/qiskit-addon-sqd/configuration-recovery.mdx
@@ -18,7 +18,7 @@ Functions for performing self-consistent configuration recovery.
### post\_select\_by\_hamming\_weight
-
+
Post-select bitstrings based on the hamming weight of each half.
@@ -42,7 +42,7 @@ Functions for performing self-consistent configuration recovery.
### recover\_configurations
-
+
Refine bitstrings based on average orbital occupancy and a target hamming weight.
This function refines each bit in isolation in an attempt to transform the Hilbert space represented by the input `bitstring_matrix` into a space closer to that which supports the ground state.
diff --git a/docs/api/qiskit-addon-sqd/counts.mdx b/docs/api/qiskit-addon-sqd/counts.mdx
index 6c1f0f4a5a31..88f608f2c138 100644
--- a/docs/api/qiskit-addon-sqd/counts.mdx
+++ b/docs/api/qiskit-addon-sqd/counts.mdx
@@ -18,7 +18,7 @@ Functions for transforming counts dictionaries.
### counts\_to\_arrays
-
+
Convert a counts dictionary into a bitstring matrix and a probability array.
**Parameters**
@@ -37,7 +37,7 @@ Functions for transforming counts dictionaries.
### generate\_counts\_uniform
-
+
Generate a bitstring counts dictionary of samples drawn from the uniform distribution.
**Parameters**
@@ -61,7 +61,7 @@ Functions for transforming counts dictionaries.
### generate\_counts\_bipartite\_hamming
-
+
Generate a bitstring counts dictionary with specified bipartite hamming weight.
**Parameters**
@@ -89,7 +89,7 @@ Functions for transforming counts dictionaries.
### normalize\_counts\_dict
-
+
Convert a counts dictionary into a probability dictionary.
**Parameters**
@@ -103,7 +103,7 @@ Functions for transforming counts dictionaries.
### bit\_array\_to\_arrays
-
+
Convert a bit array into a bitstring matrix and a probability array.
**Parameters**
@@ -122,7 +122,7 @@ Functions for transforming counts dictionaries.
### generate\_bit\_array\_uniform
-
+
Generate a bit array of samples drawn from the uniform distribution.
**Parameters**
diff --git a/docs/api/qiskit-addon-sqd/fermion.mdx b/docs/api/qiskit-addon-sqd/fermion.mdx
index 76e559beff44..5cca52923fcf 100644
--- a/docs/api/qiskit-addon-sqd/fermion.mdx
+++ b/docs/api/qiskit-addon-sqd/fermion.mdx
@@ -18,7 +18,7 @@ Functions for the study of fermionic systems.
### SCIState
-
+
Bases: [`object`](https://docs.python.org/3/library/functions.html#object)
The amplitudes and determinants describing a quantum state.
@@ -33,43 +33,43 @@ Functions for the study of fermionic systems.
#### amplitudes
-
+
An $M \times N$ array where $M =$ len(`ci_strs_a`) and $N$ = len(`ci_strs_b`). `amplitudes[i][j]` is the amplitude of the determinant pair (`ci_strs_a[i]`, `ci_strs_b[j]`).
#### ci\_strs\_a
-
+
The alpha determinants.
#### ci\_strs\_b
-
+
The beta determinants.
#### load
-
+
Load an SCIState object from an .npz file.
#### nelec
-
+
The numbers of alpha and beta electrons.
#### norb
-
+
The number of spatial orbitals.
#### orbital\_occupancies
-
+
Average orbital occupancies.
**Return type**
@@ -79,7 +79,7 @@ Functions for the study of fermionic systems.
#### rdm
-
+
Compute reduced density matrix.
**Parameters**
@@ -94,13 +94,13 @@ Functions for the study of fermionic systems.
#### save
-
+
Save the SCIState object to an .npz file.
#### spin\_square
-
+
Return spin squared.
**Return type**
@@ -111,7 +111,7 @@ Functions for the study of fermionic systems.
### bitstring\_matrix\_to\_ci\_strs
-
+
Convert bitstrings (rows) in a `bitstring_matrix` into integer representations of determinants.
This function separates each bitstring in `bitstring_matrix` in half, translates them into integer representations, and finally appends them to their respective (spin-up or spin-down) lists. Those lists are sorted and output from this function.
@@ -132,7 +132,7 @@ Functions for the study of fermionic systems.
### diagonalize\_fermionic\_hamiltonian
-
+
Run the sample-based quantum diagonalization (SQD) algorithm.
**Parameters**
@@ -200,11 +200,23 @@ Functions for the study of fermionic systems.
**Return type**
*SCIResult*
+
+
+ This function supports collective multi-process (SPMD) execution using MPI, with a single thread controlling each process (`MPI_THREAD_FUNNELED` or lower). When it is invoked collectively from all processes, the arguments must agree across processes, and the following semantics apply:
+
+ * The `sci_solver` step is the only collective operation: all processes participate in it, so an `sci_solver` implementation can distribute work across every process. The remaining steps of the configuration-recovery loop (preparing the CI strings, processing the diagonalization results, and checking convergence) have no distributed implementation and are performed on the control process alone.
+ * The `callback`, if provided, is invoked on the control process only.
+ * The return value is the same on every process: the final result is broadcast from the control process to all ranks.
+
+ Whether the calling program should be launched under MPI depends on the `sci_solver` in use. A collective `sci_solver`, as described above, expects the program to run collectively across all processes. Other implementations require the calling program to run as a single process, outside any MPI/SPMD environment. Some of these implementations might manage their own parallelism internally, for example, by launching `mpirun` themselves. The default `sci_solver` is not distributed and falls into this latter category.
+
+ A collective `sci_solver` implementation is not required to raise an exception on a single process when it encounters an error; instead, it can follow fail-stop semantics for the execution context as a whole, aborting all processes collectively. (This describes what such an implementation is permitted to do, not the behavior of the default `sci_solver`.)
+
### enlarge\_batch\_from\_transitions
-
+
Apply the set of transition operators to the configurations represented in `bitstring_matrix`.
**Parameters**
@@ -223,7 +235,7 @@ Functions for the study of fermionic systems.
### solve\_fermion
-
+
Approximate the ground state given molecular integrals and a set of electronic configurations.
**Parameters**
@@ -263,7 +275,7 @@ Functions for the study of fermionic systems.
### solve\_sci
-
+
Diagonalize Hamiltonian in subspace defined by CI strings.
**Parameters**
@@ -295,7 +307,7 @@ Functions for the study of fermionic systems.
### solve\_sci\_batch
-
+
Diagonalize Hamiltonian in subspaces.
**Parameters**
@@ -327,7 +339,7 @@ Functions for the study of fermionic systems.
### optimize\_orbitals
-
+
Optimize orbitals to produce a minimal ground state.
The process involves iterating over 3 steps:
@@ -340,6 +352,10 @@ Functions for the study of fermionic systems.
Refer to [Sec. II A 4](https://arxiv.org/pdf/2405.05068) for more detailed discussion on this orbital optimization technique.
+
+ The function `qiskit_addon_sqd.fermion.optimize_orbitals()` is deprecated as of qiskit-addon-sqd 0.13.0. It will be removed no earlier than v0.15.0. Orbital optimization is now supported by the ffsim package. See [/addons/qiskit-addon-sqd/guides/optimize-orbitals](/docs/addons/qiskit-addon-sqd/guides/optimize-orbitals) for a guide on how to optimize the Hamiltonian basis with ffsim.
+
+
**Parameters**
* **bitstring\_matrix** ([*tuple*](https://docs.python.org/3/library/stdtypes.html#tuple)*\[*[*ndarray*](https://numpy.org/doc/stable/reference/generated/numpy.ndarray.html#numpy.ndarray)*,* [*ndarray*](https://numpy.org/doc/stable/reference/generated/numpy.ndarray.html#numpy.ndarray)*] |* [*ndarray*](https://numpy.org/doc/stable/reference/generated/numpy.ndarray.html#numpy.ndarray)) –
@@ -384,7 +400,7 @@ Functions for the study of fermionic systems.
### rotate\_integrals
-
+
Perform a similarity transform on the integrals.
The transformation is described as:
@@ -395,6 +411,10 @@ $$
For more information on how $\hat{U}$ and $\hat{U^{\dagger}}$ are generated from `k_flat` and applied to the one- and two-body integrals, refer to [Sec. II A 4](https://arxiv.org/pdf/2405.05068).
+
+ The function `qiskit_addon_sqd.fermion.rotate_integrals()` is deprecated as of qiskit-addon-sqd 0.13.0. It will be removed no earlier than v0.15.0. Orbital optimization is now supported by the ffsim package. See [/addons/qiskit-addon-sqd/guides/optimize-orbitals](/docs/addons/qiskit-addon-sqd/guides/optimize-orbitals) for a guide on how to optimize the Hamiltonian basis with ffsim.
+
+
**Parameters**
* **hcore** ([*ndarray*](https://numpy.org/doc/stable/reference/generated/numpy.ndarray.html#numpy.ndarray)) – Core Hamiltonian matrix representing single-electron integrals
diff --git a/docs/api/qiskit-addon-sqd/qubit.mdx b/docs/api/qiskit-addon-sqd/qubit.mdx
index 0ac751747533..a96e7293ee42 100644
--- a/docs/api/qiskit-addon-sqd/qubit.mdx
+++ b/docs/api/qiskit-addon-sqd/qubit.mdx
@@ -18,7 +18,7 @@ Functions for handling quantum samples.
### solve\_qubit
-
+
Find the energies and eigenstates of a Hamiltonian projected into a subspace.
The subspace is defined by a collection of computational basis states which are specified by the bitstrings (rows) in the `bitstring_matrix`. The `bitstring_matrix` will be sorted and de-duplicated in this function, as the underlying solver requires that structure.
@@ -53,7 +53,7 @@ Functions for handling quantum samples.
### project\_operator\_to\_subspace
-
+
Project a Pauli operator onto a Hilbert subspace defined by the computational basis states (rows) in `bitstring_matrix`.
The output sparse matrix, `A`, represents an `NxN` matrix s.t. `N` is the number of rows in `bitstring_matrix`. The rows of `A` represent the input configurations, and the columns represent the connected component associated with the configuration in the corresponding row. The non-zero elements of the matrix represent the complex amplitudes associated with the connected components.
@@ -87,7 +87,7 @@ Functions for handling quantum samples.
### sort\_and\_remove\_duplicates
-
+
Sort a bitstring matrix and remove duplicate entries.
The lowest bitstring values will be placed in the lowest-indexed rows.
@@ -107,7 +107,7 @@ Functions for handling quantum samples.
### matrix\_elements\_from\_pauli
-
+
Find the sparse matrix elements of a Pauli operator in the subspace defined by the bitstrings.
The sparse matrix, `A`, defined by the outputs represents an `NxN` matrix s.t. `N` is the number of rows in `bitstring_matrix`. The rows of `A` represent the input configurations, and the columns represent the connected component associated with the configuration in the corresponding row. The output arrays define the sparse matrix, `A`, as follows:
diff --git a/docs/api/qiskit-addon-sqd/release-notes.mdx b/docs/api/qiskit-addon-sqd/release-notes.mdx
index cf531e2f2713..ec0adbc2279a 100644
--- a/docs/api/qiskit-addon-sqd/release-notes.mdx
+++ b/docs/api/qiskit-addon-sqd/release-notes.mdx
@@ -10,10 +10,30 @@ in_page_toc_max_heading_level: 2
# Sample-based quantum diagonalization (SQD) release notes
-
+
+## 0.13.0
+
+
+
+### New Features
+
+* Added support for Python 3.13 and Python 3.14. No code changes were necessary, so older releases are expected to work on Python 3.13 and 3.14 too.
+
+* [`qiskit_addon_sqd.fermion.diagonalize_fermionic_hamiltonian()`](/docs/api/qiskit-addon-sqd/fermion#diagonalize_fermionic_hamiltonian "qiskit_addon_sqd.fermion.diagonalize_fermionic_hamiltonian") can now be called collectively from all processes of a multi-process (SPMD) execution, for example under MPI. When invoked this way, the `sci_solver` step runs on every process, so a custom, distributed `sci_solver` can spread each diagonalization across the available processes; the rest of the configuration-recovery loop runs on the control process alone, and the return value is the same on every process. Single-process behavior is unchanged. See [Support for multi-process and multi-threaded acceleration](/docs/addons/qiskit-addon-sqd/guides/hpc-acceleration) for details on the package’s support for multi-process and multi-threaded acceleration.
+
+
+
+### Deprecation Notes
+
+* The [`qiskit_addon_sqd.fermion.optimize_orbitals()`](/docs/api/qiskit-addon-sqd/fermion#optimize_orbitals "qiskit_addon_sqd.fermion.optimize_orbitals") and [`qiskit_addon_sqd.fermion.rotate_integrals()`](/docs/api/qiskit-addon-sqd/fermion#rotate_integrals "qiskit_addon_sqd.fermion.rotate_integrals") functions are now deprecated. Refer to the [orbital optimization guide](/docs/addons/qiskit-addon-sqd/guides/optimize-orbitals) for how to optimize the Hamiltonian basis with the ffsim package instead.
+
+
+
+
+
## 0.12.1
@@ -24,71 +44,75 @@ in_page_toc_max_heading_level: 2
-
+
## 0.12.0
+
+
### New Features
-* Added the `max_dim` argument to the [`qiskit_addon_sqd.fermion.diagonalize_fermionic_hamiltonian()`](fermion#diagonalize_fermionic_hamiltonian "qiskit_addon_sqd.fermion.diagonalize_fermionic_hamiltonian") function. This argument is used to limit the dimension of the SCI subspace.
+* Added the `max_dim` argument to the [`qiskit_addon_sqd.fermion.diagonalize_fermionic_hamiltonian()`](/docs/api/qiskit-addon-sqd/fermion#diagonalize_fermionic_hamiltonian "qiskit_addon_sqd.fermion.diagonalize_fermionic_hamiltonian") function. This argument is used to limit the dimension of the SCI subspace.
-* Introduced the [`qiskit_addon_sqd.subsampling.postselect_by_hamming_right_and_left()`](subsampling#postselect_by_hamming_right_and_left "qiskit_addon_sqd.subsampling.postselect_by_hamming_right_and_left") function.
+* Introduced the [`qiskit_addon_sqd.subsampling.postselect_by_hamming_right_and_left()`](/docs/api/qiskit-addon-sqd/subsampling#postselect_by_hamming_right_and_left "qiskit_addon_sqd.subsampling.postselect_by_hamming_right_and_left") function.
-
+
### Upgrade Notes
-* [`qiskit_addon_sqd.fermion.SCIState`](fermion#scistate "qiskit_addon_sqd.fermion.SCIState") now takes two additional required arguments, `norb` and `nelec`. This is a breaking change.
+* [`qiskit_addon_sqd.fermion.SCIState`](/docs/api/qiskit-addon-sqd/fermion#scistate "qiskit_addon_sqd.fermion.SCIState") now takes two additional required arguments, `norb` and `nelec`. This is a breaking change.
+
+
### Deprecation Notes
-* [`qiskit_addon_sqd.configuration_recovery.post_select_by_hamming_weight()`](configuration-recovery#post_select_by_hamming_weight "qiskit_addon_sqd.configuration_recovery.post_select_by_hamming_weight") is now deprecated. Instead, use [`qiskit_addon_sqd.subsampling.postselect_by_hamming_right_and_left()`](subsampling#postselect_by_hamming_right_and_left "qiskit_addon_sqd.subsampling.postselect_by_hamming_right_and_left").
+* [`qiskit_addon_sqd.configuration_recovery.post_select_by_hamming_weight()`](/docs/api/qiskit-addon-sqd/configuration-recovery#post_select_by_hamming_weight "qiskit_addon_sqd.configuration_recovery.post_select_by_hamming_weight") is now deprecated. Instead, use [`qiskit_addon_sqd.subsampling.postselect_by_hamming_right_and_left()`](/docs/api/qiskit-addon-sqd/subsampling#postselect_by_hamming_right_and_left "qiskit_addon_sqd.subsampling.postselect_by_hamming_right_and_left").
-* [`qiskit_addon_sqd.subsampling.postselect_and_subsample()`](subsampling#postselect_and_subsample "qiskit_addon_sqd.subsampling.postselect_and_subsample") is now deprecated. Instead, use [`qiskit_addon_sqd.subsampling.postselect_by_hamming_right_and_left()`](subsampling#postselect_by_hamming_right_and_left "qiskit_addon_sqd.subsampling.postselect_by_hamming_right_and_left") and [`qiskit_addon_sqd.subsampling.subsample()`](subsampling#subsample "qiskit_addon_sqd.subsampling.subsample").
+* [`qiskit_addon_sqd.subsampling.postselect_and_subsample()`](/docs/api/qiskit-addon-sqd/subsampling#postselect_and_subsample "qiskit_addon_sqd.subsampling.postselect_and_subsample") is now deprecated. Instead, use [`qiskit_addon_sqd.subsampling.postselect_by_hamming_right_and_left()`](/docs/api/qiskit-addon-sqd/subsampling#postselect_by_hamming_right_and_left "qiskit_addon_sqd.subsampling.postselect_by_hamming_right_and_left") and [`qiskit_addon_sqd.subsampling.subsample()`](/docs/api/qiskit-addon-sqd/subsampling#subsample "qiskit_addon_sqd.subsampling.subsample").
### Bug Fixes
-* Fixed a bug in [`qiskit_addon_sqd.fermion.bitstring_matrix_to_ci_strs()`](fermion#bitstring_matrix_to_ci_strs "qiskit_addon_sqd.fermion.bitstring_matrix_to_ci_strs") in which the conversion of bitstrings to CI strings could be incorrect when the number of orbitals is greater than 53.
+* Fixed a bug in [`qiskit_addon_sqd.fermion.bitstring_matrix_to_ci_strs()`](/docs/api/qiskit-addon-sqd/fermion#bitstring_matrix_to_ci_strs "qiskit_addon_sqd.fermion.bitstring_matrix_to_ci_strs") in which the conversion of bitstrings to CI strings could be incorrect when the number of orbitals is greater than 53.
-* Fixed a bug in which saving and loading [`qiskit_addon_sqd.fermion.SCIState`](fermion#scistate "qiskit_addon_sqd.fermion.SCIState") objects resulted in an error.
+* Fixed a bug in which saving and loading [`qiskit_addon_sqd.fermion.SCIState`](/docs/api/qiskit-addon-sqd/fermion#scistate "qiskit_addon_sqd.fermion.SCIState") objects resulted in an error.
-* Added a release note to version 0.11 for a breaking change involving [`qiskit_addon_sqd.fermion.SCIState`](fermion#scistate "qiskit_addon_sqd.fermion.SCIState").
+* Added a release note to version 0.11 for a breaking change involving [`qiskit_addon_sqd.fermion.SCIState`](/docs/api/qiskit-addon-sqd/fermion#scistate "qiskit_addon_sqd.fermion.SCIState").
-
+
## 0.11.0
-
+
### New Features
-* Added a new function [`qiskit_addon_sqd.fermion.diagonalize_fermionic_hamiltonian()`](fermion#diagonalize_fermionic_hamiltonian "qiskit_addon_sqd.fermion.diagonalize_fermionic_hamiltonian") to serve as the main entrypoint to the SQD algorithm. See the updated [tutorials](https://qiskit.github.io/qiskit-addon-sqd/tutorials/index.html) for a demonstration of how to use this function.
+* Added a new function [`qiskit_addon_sqd.fermion.diagonalize_fermionic_hamiltonian()`](/docs/api/qiskit-addon-sqd/fermion#diagonalize_fermionic_hamiltonian "qiskit_addon_sqd.fermion.diagonalize_fermionic_hamiltonian") to serve as the main entrypoint to the SQD algorithm.
-* [`qiskit_addon_sqd.fermion.solve_fermion()`](fermion#solve_fermion "qiskit_addon_sqd.fermion.solve_fermion") now accepts a `shift` argument used to shift states which have the wrong spin, $(H + shift * S^2)|ψ> = E|ψ>$.
+* [`qiskit_addon_sqd.fermion.solve_fermion()`](/docs/api/qiskit-addon-sqd/fermion#solve_fermion "qiskit_addon_sqd.fermion.solve_fermion") now accepts a `shift` argument used to shift states which have the wrong spin, $(H + shift * S^2)|ψ> = E|ψ>$.
-
+
### Upgrade Notes
-* [`qiskit_addon_sqd.fermion.solve_fermion()`](fermion#solve_fermion "qiskit_addon_sqd.fermion.solve_fermion") and [`qiskit_addon_sqd.fermion.optimize_orbitals()`](fermion#optimize_orbitals "qiskit_addon_sqd.fermion.optimize_orbitals") now accept trailing `kwargs`, which will be passed directly to [pyscf.fci.selected\_ci.kernel\_fixed\_space](https://pyscf.org/pyscf_api_docs/pyscf.fci.html#pyscf.fci.selected_ci.kernel_fixed_space) under the hood to calculate the target state. The `max_davidson` argument should now be passed as `max_cycle` in both functions.
+* [`qiskit_addon_sqd.fermion.solve_fermion()`](/docs/api/qiskit-addon-sqd/fermion#solve_fermion "qiskit_addon_sqd.fermion.solve_fermion") and [`qiskit_addon_sqd.fermion.optimize_orbitals()`](/docs/api/qiskit-addon-sqd/fermion#optimize_orbitals "qiskit_addon_sqd.fermion.optimize_orbitals") now accept trailing `kwargs`, which will be passed directly to [pyscf.fci.selected\_ci.kernel\_fixed\_space](https://pyscf.org/pyscf_api_docs/pyscf.fci.html#pyscf.fci.selected_ci.kernel_fixed_space) under the hood to calculate the target state. The `max_davidson` argument should now be passed as `max_cycle` in both functions.
-
+
### Bug Fixes
@@ -96,25 +120,25 @@ in_page_toc_max_heading_level: 2
-
+
## 0.10.0
-
+
### Upgrade Notes
-* Removed `qiskit_addon_sqd.fermion.flip_orbital_occupancies()`. Users no longer need to flip the orbital occupancies output from [`qiskit_addon_sqd.fermion.solve_fermion()`](fermion#solve_fermion "qiskit_addon_sqd.fermion.solve_fermion") and [`qiskit_addon_sqd.fermion.optimize_orbitals()`](fermion#optimize_orbitals "qiskit_addon_sqd.fermion.optimize_orbitals"); they will be output in the order expected by [`qiskit_addon_sqd.configuration_recovery.recover_configurations()`](configuration-recovery#recover_configurations "qiskit_addon_sqd.configuration_recovery.recover_configurations"): `tuple(array([occ_a_0, ..., occ_a_N]), array([occ_b_0, ..., occ_b_N]))`.
+* Removed `qiskit_addon_sqd.fermion.flip_orbital_occupancies()`. Users no longer need to flip the orbital occupancies output from [`qiskit_addon_sqd.fermion.solve_fermion()`](/docs/api/qiskit-addon-sqd/fermion#solve_fermion "qiskit_addon_sqd.fermion.solve_fermion") and [`qiskit_addon_sqd.fermion.optimize_orbitals()`](/docs/api/qiskit-addon-sqd/fermion#optimize_orbitals "qiskit_addon_sqd.fermion.optimize_orbitals"); they will be output in the order expected by [`qiskit_addon_sqd.configuration_recovery.recover_configurations()`](/docs/api/qiskit-addon-sqd/configuration-recovery#recover_configurations "qiskit_addon_sqd.configuration_recovery.recover_configurations"): `tuple(array([occ_a_0, ..., occ_a_N]), array([occ_b_0, ..., occ_b_N]))`.
-
+
### Deprecation Notes
-* The `avg_occupancies` argument to [`qiskit_addon_sqd.configuration_recovery.recover_configurations()`](configuration-recovery#recover_configurations "qiskit_addon_sqd.configuration_recovery.recover_configurations") should now be a length-2 tuple containing the spin-up and spin-down occupancies, respectively.
+* The `avg_occupancies` argument to [`qiskit_addon_sqd.configuration_recovery.recover_configurations()`](/docs/api/qiskit-addon-sqd/configuration-recovery#recover_configurations "qiskit_addon_sqd.configuration_recovery.recover_configurations") should now be a length-2 tuple containing the spin-up and spin-down occupancies, respectively.
Old format: `array([occ_b_N, ..., occ_b_0, occ_a_N, ..., occ_a_0])`
@@ -122,45 +146,45 @@ in_page_toc_max_heading_level: 2
-
+
### Bug Fixes
-* Fixed a bug which would cause the energy output from [`qiskit_addon_sqd.fermion.solve_fermion()`](fermion#solve_fermion "qiskit_addon_sqd.fermion.solve_fermion") to be incorrect when the input `spin_sq` deviates from the spin^2 of the output wavefunction.
+* Fixed a bug which would cause the energy output from [`qiskit_addon_sqd.fermion.solve_fermion()`](/docs/api/qiskit-addon-sqd/fermion#solve_fermion "qiskit_addon_sqd.fermion.solve_fermion") to be incorrect when the input `spin_sq` deviates from the spin^2 of the output wavefunction.
-
+
## 0.9.0
-
+
### Upgrade Notes
-* [`qiskit_addon_sqd.fermion.optimize_orbitals()`](fermion#optimize_orbitals "qiskit_addon_sqd.fermion.optimize_orbitals") and [`qiskit_addon_sqd.fermion.rotate_integrals()`](fermion#rotate_integrals "qiskit_addon_sqd.fermion.rotate_integrals") now require `k_flat` to specify the upper triangle (not including diagonal) of the rotation matrix, rather than the entire matrix.
+* [`qiskit_addon_sqd.fermion.optimize_orbitals()`](/docs/api/qiskit-addon-sqd/fermion#optimize_orbitals "qiskit_addon_sqd.fermion.optimize_orbitals") and [`qiskit_addon_sqd.fermion.rotate_integrals()`](/docs/api/qiskit-addon-sqd/fermion#rotate_integrals "qiskit_addon_sqd.fermion.rotate_integrals") now require `k_flat` to specify the upper triangle (not including diagonal) of the rotation matrix, rather than the entire matrix.
-
+
### Bug Fixes
-* Fixed an indexing error in [`qiskit_addon_sqd.configuration_recovery()`](configuration-recovery#module-qiskit_addon_sqd.configuration_recovery "qiskit_addon_sqd.configuration_recovery") which caused bits in the right half of the bitstring to be flipped with respect to the occupancies of the oritals associated with the left half of the bitstring.
+* Fixed an indexing error in [`qiskit_addon_sqd.configuration_recovery()`](/docs/api/qiskit-addon-sqd/configuration-recovery#module-qiskit_addon_sqd.configuration_recovery "qiskit_addon_sqd.configuration_recovery") which caused bits in the right half of the bitstring to be flipped with respect to the occupancies of the oritals associated with the left half of the bitstring.
* pyscf is no longer considered a dependency on Windows, where it fails to install. However, Windows remains an unsupported platform.
-
+
## 0.8.0
-
+
### New Features
@@ -170,41 +194,41 @@ in_page_toc_max_heading_level: 2
-
+
### Upgrade Notes
-* The ground state returned by [`qiskit_addon_sqd.fermion.solve_fermion()`](fermion#solve_fermion "qiskit_addon_sqd.fermion.solve_fermion") will now be an instance of [`qiskit_addon_sqd.fermion.SCIState`](fermion#scistate "qiskit_addon_sqd.fermion.SCIState"), rather than a PySCF `SCIVector` instance.
+* The ground state returned by [`qiskit_addon_sqd.fermion.solve_fermion()`](/docs/api/qiskit-addon-sqd/fermion#solve_fermion "qiskit_addon_sqd.fermion.solve_fermion") will now be an instance of [`qiskit_addon_sqd.fermion.SCIState`](/docs/api/qiskit-addon-sqd/fermion#scistate "qiskit_addon_sqd.fermion.SCIState"), rather than a PySCF `SCIVector` instance.
-
+
## 0.7.0
-
+
### Bug Fixes
-* Fixed a bug in [`qiskit_addon_sqd.fermion.solve_fermion()`](fermion#solve_fermion "qiskit_addon_sqd.fermion.solve_fermion") and [`qiskit_addon_sqd.fermion.optimize_orbitals()`](fermion#optimize_orbitals "qiskit_addon_sqd.fermion.optimize_orbitals") which causes the determinants for spin-up and spin-down to be incorrectly flipped before solving.
+* Fixed a bug in [`qiskit_addon_sqd.fermion.solve_fermion()`](/docs/api/qiskit-addon-sqd/fermion#solve_fermion "qiskit_addon_sqd.fermion.solve_fermion") and [`qiskit_addon_sqd.fermion.optimize_orbitals()`](/docs/api/qiskit-addon-sqd/fermion#optimize_orbitals "qiskit_addon_sqd.fermion.optimize_orbitals") which causes the determinants for spin-up and spin-down to be incorrectly flipped before solving.
-* Fixed a bug in open-shell workflows which would cause [`qiskit_addon_sqd.fermion.optimize_orbitals()`](fermion#optimize_orbitals "qiskit_addon_sqd.fermion.optimize_orbitals") to crash with a `malloc` error.
+* Fixed a bug in open-shell workflows which would cause [`qiskit_addon_sqd.fermion.optimize_orbitals()`](/docs/api/qiskit-addon-sqd/fermion#optimize_orbitals "qiskit_addon_sqd.fermion.optimize_orbitals") to crash with a `malloc` error.
-
+
## 0.6.0
-
+
### Upgrade Notes
-* Specifying `addresses` as a keyword argument to [`qiskit_addon_sqd.fermion.solve_fermion()`](fermion#solve_fermion "qiskit_addon_sqd.fermion.solve_fermion") and [`qiskit_addon_sqd.fermion.optimize_orbitals()`](fermion#optimize_orbitals "qiskit_addon_sqd.fermion.optimize_orbitals") is no longer supported. Users may still pass `addresses` as the first positional argument; however, this usage is deprecated. Users are encouraged to pass the bitstring matrix defining the subspace as the first positional arguments to these functions, as shown below.
+* Specifying `addresses` as a keyword argument to [`qiskit_addon_sqd.fermion.solve_fermion()`](/docs/api/qiskit-addon-sqd/fermion#solve_fermion "qiskit_addon_sqd.fermion.solve_fermion") and [`qiskit_addon_sqd.fermion.optimize_orbitals()`](/docs/api/qiskit-addon-sqd/fermion#optimize_orbitals "qiskit_addon_sqd.fermion.optimize_orbitals") is no longer supported. Users may still pass `addresses` as the first positional argument; however, this usage is deprecated. Users are encouraged to pass the bitstring matrix defining the subspace as the first positional arguments to these functions, as shown below.
To upgrade, change this code
@@ -251,11 +275,11 @@ in_page_toc_max_heading_level: 2
-
+
### Deprecation Notes
-* The `qiskit_addon_sqd.fermion.bitstring_matrix_to_sorted_addresses()` function has been deprecated in favor of [`qiskit_addon_sqd.fermion.bitstring_matrix_to_ci_strs()`](fermion#bitstring_matrix_to_ci_strs "qiskit_addon_sqd.fermion.bitstring_matrix_to_ci_strs"). These two functions behave the same with one key exception – `qiskit_addon_sqd.fermion.bitstring_matrix_to_sorted_addresses()` returns the configurations as `tuple(spin_dn, spin_up)`; whereas, [`qiskit_addon_sqd.fermion.bitstring_matrix_to_ci_strs()`](fermion#bitstring_matrix_to_ci_strs "qiskit_addon_sqd.fermion.bitstring_matrix_to_ci_strs") returns the configurations as `tuple(spin_up, spin_dn)`.
+* The `qiskit_addon_sqd.fermion.bitstring_matrix_to_sorted_addresses()` function has been deprecated in favor of [`qiskit_addon_sqd.fermion.bitstring_matrix_to_ci_strs()`](/docs/api/qiskit-addon-sqd/fermion#bitstring_matrix_to_ci_strs "qiskit_addon_sqd.fermion.bitstring_matrix_to_ci_strs"). These two functions behave the same with one key exception – `qiskit_addon_sqd.fermion.bitstring_matrix_to_sorted_addresses()` returns the configurations as `tuple(spin_dn, spin_up)`; whereas, [`qiskit_addon_sqd.fermion.bitstring_matrix_to_ci_strs()`](/docs/api/qiskit-addon-sqd/fermion#bitstring_matrix_to_ci_strs "qiskit_addon_sqd.fermion.bitstring_matrix_to_ci_strs") returns the configurations as `tuple(spin_up, spin_dn)`.
To migrate
@@ -276,31 +300,31 @@ in_page_toc_max_heading_level: 2
ci_strs_up, ci_strs_dn = bitstring_matrix_to_ci_strs(bs_matrix, open_shell=True)
```
-* The `addresses` argument to [`qiskit_addon_sqd.fermion.solve_fermion()`](fermion#solve_fermion "qiskit_addon_sqd.fermion.solve_fermion") and [`qiskit_addon_sqd.fermion.optimize_orbitals()`](fermion#optimize_orbitals "qiskit_addon_sqd.fermion.optimize_orbitals") has been deprecated in favor of `bitstring_matrix`. Users are no longer required to convert their configurations to integers; instead, they should now pass in the bitstring matrix specifying the subspace onto which to project and diagonalize the Hamiltonian. The conversion to the integer representation of determinants will be done internally.
+* The `addresses` argument to [`qiskit_addon_sqd.fermion.solve_fermion()`](/docs/api/qiskit-addon-sqd/fermion#solve_fermion "qiskit_addon_sqd.fermion.solve_fermion") and [`qiskit_addon_sqd.fermion.optimize_orbitals()`](/docs/api/qiskit-addon-sqd/fermion#optimize_orbitals "qiskit_addon_sqd.fermion.optimize_orbitals") has been deprecated in favor of `bitstring_matrix`. Users are no longer required to convert their configurations to integers; instead, they should now pass in the bitstring matrix specifying the subspace onto which to project and diagonalize the Hamiltonian. The conversion to the integer representation of determinants will be done internally.
-
+
### Bug Fixes
-* Fixed a bug in [`qiskit_addon_sqd.configuration_recovery.recover_configurations()`](configuration-recovery#recover_configurations "qiskit_addon_sqd.configuration_recovery.recover_configurations") which would sometimes cause a divide-by-zero error when calculating individual bit-flip probability.
+* Fixed a bug in [`qiskit_addon_sqd.configuration_recovery.recover_configurations()`](/docs/api/qiskit-addon-sqd/configuration-recovery#recover_configurations "qiskit_addon_sqd.configuration_recovery.recover_configurations") which would sometimes cause a divide-by-zero error when calculating individual bit-flip probability.
* Fixes a bug that caused configuration recovery to fail on bitstrings of length greater than 72.
-
+
## 0.5.0
-
+
### Upgrade Notes
-* The [`qiskit_addon_sqd.counts.generate_counts_bipartite_hamming()`](counts#generate_counts_bipartite_hamming "qiskit_addon_sqd.counts.generate_counts_bipartite_hamming"), [`qiskit_addon_sqd.subsampling.postselect_and_subsample()`](subsampling#postselect_and_subsample "qiskit_addon_sqd.subsampling.postselect_and_subsample"), and [`qiskit_addon_sqd.configuration_recovery.post_select_by_hamming_weight()`](configuration-recovery#post_select_by_hamming_weight "qiskit_addon_sqd.configuration_recovery.post_select_by_hamming_weight") now require the `hamming_right` and `hamming_left` arguments to be specified as keyword arguments. Additionally, the `samples_per_batch` and `n_batches` arguments to [`qiskit_addon_sqd.subsampling.postselect_and_subsample()`](subsampling#postselect_and_subsample "qiskit_addon_sqd.subsampling.postselect_and_subsample") should now be passed as keyword arguments.
+* The [`qiskit_addon_sqd.counts.generate_counts_bipartite_hamming()`](/docs/api/qiskit-addon-sqd/counts#generate_counts_bipartite_hamming "qiskit_addon_sqd.counts.generate_counts_bipartite_hamming"), [`qiskit_addon_sqd.subsampling.postselect_and_subsample()`](/docs/api/qiskit-addon-sqd/subsampling#postselect_and_subsample "qiskit_addon_sqd.subsampling.postselect_and_subsample"), and [`qiskit_addon_sqd.configuration_recovery.post_select_by_hamming_weight()`](/docs/api/qiskit-addon-sqd/configuration-recovery#post_select_by_hamming_weight "qiskit_addon_sqd.configuration_recovery.post_select_by_hamming_weight") now require the `hamming_right` and `hamming_left` arguments to be specified as keyword arguments. Additionally, the `samples_per_batch` and `n_batches` arguments to [`qiskit_addon_sqd.subsampling.postselect_and_subsample()`](/docs/api/qiskit-addon-sqd/subsampling#postselect_and_subsample "qiskit_addon_sqd.subsampling.postselect_and_subsample") should now be passed as keyword arguments.
To upgrade
@@ -354,7 +378,7 @@ in_page_toc_max_heading_level: 2
-
+
## 0.4.0
@@ -366,11 +390,11 @@ This is a minor release which introduces a couple of small, but important, break
-
+
### Upgrade Notes
-* The [`qiskit_addon_sqd.counts.generate_counts_bipartite_hamming()`](counts#generate_counts_bipartite_hamming "qiskit_addon_sqd.counts.generate_counts_bipartite_hamming"), [`qiskit_addon_sqd.subsampling.postselect_and_subsample()`](subsampling#postselect_and_subsample "qiskit_addon_sqd.subsampling.postselect_and_subsample"), and [`qiskit_addon_sqd.configuration_recovery.post_select_by_hamming_weight()`](configuration-recovery#post_select_by_hamming_weight "qiskit_addon_sqd.configuration_recovery.post_select_by_hamming_weight") now take the `hamming_right` positional argument before the `hamming_left` argument to better match the rest of the workflow.
+* The [`qiskit_addon_sqd.counts.generate_counts_bipartite_hamming()`](/docs/api/qiskit-addon-sqd/counts#generate_counts_bipartite_hamming "qiskit_addon_sqd.counts.generate_counts_bipartite_hamming"), [`qiskit_addon_sqd.subsampling.postselect_and_subsample()`](/docs/api/qiskit-addon-sqd/subsampling#postselect_and_subsample "qiskit_addon_sqd.subsampling.postselect_and_subsample"), and [`qiskit_addon_sqd.configuration_recovery.post_select_by_hamming_weight()`](/docs/api/qiskit-addon-sqd/configuration-recovery#post_select_by_hamming_weight "qiskit_addon_sqd.configuration_recovery.post_select_by_hamming_weight") now take the `hamming_right` positional argument before the `hamming_left` argument to better match the rest of the workflow.
To upgrade
diff --git a/docs/api/qiskit-addon-sqd/subsampling.mdx b/docs/api/qiskit-addon-sqd/subsampling.mdx
index c071199dc001..7e10897b032e 100644
--- a/docs/api/qiskit-addon-sqd/subsampling.mdx
+++ b/docs/api/qiskit-addon-sqd/subsampling.mdx
@@ -18,7 +18,7 @@ Functions for creating batches of samples from a bitstring matrix.
### subsample
-
+
Subsample batches of bit arrays from an input `bitstring_matrix`.
Each individual batch will be sampled without replacement from the input `bitstring_matrix`. Samples will be replaced after creation of each batch, so different batches may contain identical samples.
@@ -47,7 +47,7 @@ Functions for creating batches of samples from a bitstring matrix.
### postselect\_and\_subsample
-
+
Subsample batches of bit arrays with correct hamming weight from an input `bitstring_matrix`.
Bitstring samples with incorrect hamming weight on either their left or right half will not be sampled.
@@ -85,7 +85,7 @@ Functions for creating batches of samples from a bitstring matrix.
### postselect\_by\_hamming\_right\_and\_left
-
+
Postselect bitstrings based on desired Hamming weight on right and left halves.
**Parameters**
diff --git a/public/docs/api/qiskit-addon-sqd/0.12/objects.inv b/public/docs/api/qiskit-addon-sqd/0.12/objects.inv
new file mode 100644
index 000000000000..73d11ceaed44
Binary files /dev/null and b/public/docs/api/qiskit-addon-sqd/0.12/objects.inv differ
diff --git a/public/docs/api/qiskit-addon-sqd/objects.inv b/public/docs/api/qiskit-addon-sqd/objects.inv
index 6440277abb6e..b5515793b0b5 100644
Binary files a/public/docs/api/qiskit-addon-sqd/objects.inv and b/public/docs/api/qiskit-addon-sqd/objects.inv differ
diff --git a/public/docs/images/addons/qiskit-addon-sqd/guides/benchmark-pauli-projection/extracted-outputs/6b961c81-0.avif b/public/docs/images/addons/qiskit-addon-sqd/guides/benchmark-pauli-projection/extracted-outputs/6b961c81-0.avif
index 95fb46a67fc4..66993de688b7 100644
Binary files a/public/docs/images/addons/qiskit-addon-sqd/guides/benchmark-pauli-projection/extracted-outputs/6b961c81-0.avif and b/public/docs/images/addons/qiskit-addon-sqd/guides/benchmark-pauli-projection/extracted-outputs/6b961c81-0.avif differ
diff --git a/public/docs/images/addons/qiskit-addon-sqd/guides/benchmark-pauli-projection/extracted-outputs/9abb110f-0.avif b/public/docs/images/addons/qiskit-addon-sqd/guides/benchmark-pauli-projection/extracted-outputs/9abb110f-0.avif
index 3737095c5208..8514cb8a16e9 100644
Binary files a/public/docs/images/addons/qiskit-addon-sqd/guides/benchmark-pauli-projection/extracted-outputs/9abb110f-0.avif and b/public/docs/images/addons/qiskit-addon-sqd/guides/benchmark-pauli-projection/extracted-outputs/9abb110f-0.avif differ
diff --git a/public/docs/images/addons/qiskit-addon-sqd/guides/choose-subspace-dimension/extracted-outputs/caffd888-e89c-4aa9-8bae-4d1bb723b35e-0.avif b/public/docs/images/addons/qiskit-addon-sqd/guides/choose-subspace-dimension/extracted-outputs/caffd888-e89c-4aa9-8bae-4d1bb723b35e-0.avif
index 4baa43f40651..e2e1c66b1054 100644
Binary files a/public/docs/images/addons/qiskit-addon-sqd/guides/choose-subspace-dimension/extracted-outputs/caffd888-e89c-4aa9-8bae-4d1bb723b35e-0.avif and b/public/docs/images/addons/qiskit-addon-sqd/guides/choose-subspace-dimension/extracted-outputs/caffd888-e89c-4aa9-8bae-4d1bb723b35e-0.avif differ
diff --git a/scripts/config/api-html-artifacts.json b/scripts/config/api-html-artifacts.json
index 5ad73a1afbde..129f92eb5fe2 100644
--- a/scripts/config/api-html-artifacts.json
+++ b/scripts/config/api-html-artifacts.json
@@ -109,6 +109,7 @@
"0.1": "https://ibm.box.com/shared/static/avbot44xlamcvccs8ylj7md7kjfjgfw8.zip"
},
"qiskit-addon-sqd": {
+ "0.13": "https://ibm.box.com/shared/static/fclsbxvg3a92x7n1jay0bbke5hbda63f.zip",
"0.12": "https://ibm.box.com/shared/static/s96j7d1ofs6esevo75ox78u8kqks131i.zip",
"0.11": "https://ibm.box.com/shared/static/b2d306sfbkejd7j6c80asywh1fjrpftn.zip",
"0.10": "https://ibm.box.com/shared/static/g73sbmg2bt3gmq3x26ybxbm7vsj6ioyb.zip",
diff --git a/scripts/config/cspell/dictionaries/qiskit.txt b/scripts/config/cspell/dictionaries/qiskit.txt
index f82d5392db3f..900a6afd75f9 100644
--- a/scripts/config/cspell/dictionaries/qiskit.txt
+++ b/scripts/config/cspell/dictionaries/qiskit.txt
@@ -454,3 +454,11 @@ postselect
postselected
postselecting
postselects
+textrm
+walltime
+hcore
+myci
+mcscf
+ncas
+nelecas
+binom
\ No newline at end of file
diff --git a/scripts/config/historical-pages-to-latest.json b/scripts/config/historical-pages-to-latest.json
index abb059a27f2b..53ef338ea934 100644
--- a/scripts/config/historical-pages-to-latest.json
+++ b/scripts/config/historical-pages-to-latest.json
@@ -1541,6 +1541,7 @@
"0.17": {}
},
"qiskit-c": {
+ "1.4": {},
"2.0": {},
"2.1": {},
"2.2": {
@@ -1565,6 +1566,7 @@
"qiskit-addon-sqd": {
"0.10": {},
"0.11": {},
+ "0.12": {},
"0.7": {},
"0.8": {},
"0.9": {}