Metadata-Version: 2.5
Name: qiskit-addon-sqd
Version: 0.14.0
Summary: Classically postprocess noisy quantum samples to yield more accurate energy estimations
License-Expression: Apache-2.0
License-File: LICENSE.txt
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: Science/Research
Classifier: Natural Language :: English
Classifier: Operating System :: POSIX :: Linux
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Classifier: Topic :: Scientific/Engineering :: Physics
Requires-Python: >=3.10
Requires-Dist: jax>=0.4.30
Requires-Dist: jaxlib>=0.4.30
Requires-Dist: numpy>=2.0
Requires-Dist: pyscf>=2.9; sys_platform != 'win32'
Requires-Dist: qiskit<3,>=2.0
Requires-Dist: scipy>=1.14.1
Provides-Extra: basetest
Requires-Dist: pytest-cov>=5.0; extra == 'basetest'
Requires-Dist: pytest>=8.0; extra == 'basetest'
Provides-Extra: dev
Requires-Dist: ffsim>=0.0.58; extra == 'dev'
Requires-Dist: fulqrum>=0.4.4; extra == 'dev'
Requires-Dist: jupyter-sphinx; extra == 'dev'
Requires-Dist: matplotlib; extra == 'dev'
Requires-Dist: mypy==2.3.1; extra == 'dev'
Requires-Dist: nbmake>=1.5.0; extra == 'dev'
Requires-Dist: nbqa>=1.8.5; extra == 'dev'
Requires-Dist: nbsphinx>=0.9.4; extra == 'dev'
Requires-Dist: primme>=3.2.3; extra == 'dev'
Requires-Dist: pylatexenc; extra == 'dev'
Requires-Dist: pylint==4.0.9; extra == 'dev'
Requires-Dist: pytest-cov>=5.0; extra == 'dev'
Requires-Dist: pytest>=8.0; extra == 'dev'
Requires-Dist: qiskit; extra == 'dev'
Requires-Dist: qiskit-addon-utils; extra == 'dev'
Requires-Dist: qiskit-aer; extra == 'dev'
Requires-Dist: qiskit-ibm-runtime; extra == 'dev'
Requires-Dist: qiskit-sphinx-theme~=2.1.0; extra == 'dev'
Requires-Dist: reno>=4.1; extra == 'dev'
Requires-Dist: ruff==0.16.9; extra == 'dev'
Requires-Dist: sbd-eigensolver>=1.6.1; extra == 'dev'
Requires-Dist: sphinx-autodoc-typehints; extra == 'dev'
Requires-Dist: sphinx-copybutton; extra == 'dev'
Requires-Dist: sphinx-design; extra == 'dev'
Requires-Dist: sphinx-reredirects; extra == 'dev'
Requires-Dist: toml>=0.9.6; extra == 'dev'
Requires-Dist: tox>=4.4.3; extra == 'dev'
Provides-Extra: docs
Requires-Dist: ffsim>=0.0.58; extra == 'docs'
Requires-Dist: fulqrum>=0.4.4; extra == 'docs'
Requires-Dist: jupyter-sphinx; extra == 'docs'
Requires-Dist: matplotlib; extra == 'docs'
Requires-Dist: nbsphinx>=0.9.4; extra == 'docs'
Requires-Dist: primme>=3.2.3; extra == 'docs'
Requires-Dist: pylatexenc; extra == 'docs'
Requires-Dist: pytest-cov>=5.0; extra == 'docs'
Requires-Dist: pytest>=8.0; extra == 'docs'
Requires-Dist: qiskit; extra == 'docs'
Requires-Dist: qiskit-addon-utils; extra == 'docs'
Requires-Dist: qiskit-aer; extra == 'docs'
Requires-Dist: qiskit-ibm-runtime; extra == 'docs'
Requires-Dist: qiskit-sphinx-theme~=2.1.0; extra == 'docs'
Requires-Dist: reno>=4.1; extra == 'docs'
Requires-Dist: sbd-eigensolver>=1.6.1; extra == 'docs'
Requires-Dist: sphinx-autodoc-typehints; extra == 'docs'
Requires-Dist: sphinx-copybutton; extra == 'docs'
Requires-Dist: sphinx-design; extra == 'docs'
Requires-Dist: sphinx-reredirects; extra == 'docs'
Provides-Extra: fulqrum
Requires-Dist: fulqrum>=0.4.4; extra == 'fulqrum'
Requires-Dist: primme>=3.2.3; extra == 'fulqrum'
Provides-Extra: lint
Requires-Dist: mypy==2.3.1; extra == 'lint'
Requires-Dist: nbqa>=1.8.5; extra == 'lint'
Requires-Dist: pylint==4.0.9; extra == 'lint'
Requires-Dist: reno>=4.1; extra == 'lint'
Requires-Dist: ruff==0.16.9; extra == 'lint'
Requires-Dist: toml>=0.9.6; extra == 'lint'
Provides-Extra: nbtest
Requires-Dist: nbmake>=1.5.0; extra == 'nbtest'
Requires-Dist: pytest-cov>=5.0; extra == 'nbtest'
Requires-Dist: pytest>=8.0; extra == 'nbtest'
Provides-Extra: notebook-dependencies
Requires-Dist: ffsim>=0.0.58; extra == 'notebook-dependencies'
Requires-Dist: fulqrum>=0.4.4; extra == 'notebook-dependencies'
Requires-Dist: matplotlib; extra == 'notebook-dependencies'
Requires-Dist: primme>=3.2.3; extra == 'notebook-dependencies'
Requires-Dist: pylatexenc; extra == 'notebook-dependencies'
Requires-Dist: qiskit; extra == 'notebook-dependencies'
Requires-Dist: qiskit-addon-utils; extra == 'notebook-dependencies'
Requires-Dist: qiskit-aer; extra == 'notebook-dependencies'
Requires-Dist: qiskit-ibm-runtime; extra == 'notebook-dependencies'
Requires-Dist: sbd-eigensolver>=1.6.1; extra == 'notebook-dependencies'
Provides-Extra: sbd
Requires-Dist: sbd-eigensolver>=1.6.1; extra == 'sbd'
Provides-Extra: style
Requires-Dist: nbqa>=1.8.5; extra == 'style'
Requires-Dist: ruff==0.16.9; extra == 'style'
Provides-Extra: test
Requires-Dist: pytest-cov>=5.0; extra == 'test'
Requires-Dist: pytest>=8.0; extra == 'test'
Description-Content-Type: text/markdown

<!-- SHIELDS -->
<div align="left">

  [![Release](https://img.shields.io/pypi/v/qiskit-addon-sqd.svg?label=Release)](https://github.com/Qiskit/qiskit-addon-sqd/releases)
  ![Platform](https://img.shields.io/badge/%F0%9F%92%BB_Platform-Linux%20%7C%20macOS-blue)
  [![Python](https://img.shields.io/pypi/pyversions/qiskit-addon-sqd?label=Python&logo=python)](https://www.python.org/)
  [![Qiskit](https://img.shields.io/badge/Qiskit%20-%20%3E%3D1.2%20-%20%236133BD?logo=Qiskit)](https://github.com/Qiskit/qiskit)
<br />
  <!-- [![DOI](https://zenodo.org/badge/DOI/TODO](https://zenodo.org/doi/TODO -->
  [![License](https://img.shields.io/github/license/Qiskit/qiskit-addon-sqd?label=License)](LICENSE.txt)
  [![Downloads](https://img.shields.io/pypi/dm/qiskit-addon-sqd.svg?label=Downloads)](https://pypi.org/project/qiskit-addon-sqd/)
  [![Tests](https://github.com/Qiskit/qiskit-addon-sqd/actions/workflows/test_latest_versions.yml/badge.svg)](https://github.com/Qiskit/qiskit-addon-sqd/actions/workflows/test_latest_versions.yml)
  [![Coverage](https://coveralls.io/repos/github/Qiskit/qiskit-addon-sqd/badge.svg?branch=main)](https://coveralls.io/github/Qiskit/qiskit-addon-sqd?branch=main)

# Sample-based quantum diagonalization (SQD)

This package implements sample-based quantum diagonalization (SQD) -- a technique for finding eigenvalues and eigenvectors of quantum operators, such as a quantum system Hamiltonian [[1-6]](#references). It can target Hamiltonians expressed as linear combinations of Pauli operators or second-quantized Fermionic operators. SQD-based workflows can be run on current quantum computers and have been shown to scale to problem sizes beyond what was possible with variational methods — and even beyond the reach of exact classical diagonalization methods.

SQD-based workflows involve first preparing one or more quantum states on a quantum device and sampling from them. Then, classical distributed computing is used to process those noisy samples. This processing occurs iteratively in two steps: first, a configuration recovery step corrects noisy samples using information about the input problem; second, the Hamiltonian is projected and diagonalized in the subspace spanned by those samples. These steps are repeated self-consistently until convergence. The result is an approximated lowest eigenvalue (energy) and lowest energy eigenstate of a given Hamiltonian. SQD is robust to samples corrupted by quantum noise; in fact, as long as a useful signal can be retrieved out of the quantum computer, the outcome of SQD will be insensitive to noisy bitstrings.

`qiskit-addon-sqd` can be used to classically process samples drawn from a variety of quantum circuits in practice. For example:
  
  1. A variational circuit ansatz with parameters chosen such that sampling the circuit produces electronic configurations on which the target wavefunction (for example, the ground state) has significant support. This is appealing for chemistry applications where Hamiltonians can have millions of interaction terms [[1]](#references). For an example of this approach applied to chemistry using an LUCJ circuit see the [tutorial for approximating the ground state energy of the N2 molecule](https://quantum.cloud.ibm.com/docs/tutorials/sample-based-quantum-diagonalization).

  2. A set of Krylov basis states prepared over increasing time intervals. Assuming a good initial state and sparsity of the ground state, this approach is proven to converge efficiently. As one needs to prepare Trotterized time evolution circuits on a quantum device, this approach is best for applications to lattice models [[2]](#references) instead of complex many-body Hamiltonians like those for quantum chemistry. For an example of this approach applied to Fermionic lattice Hamiltonians, see the [tutorial for approximating the ground state energy of a simplified single-impurity Anderson model](https://quantum.cloud.ibm.com/docs/tutorials/sample-based-krylov-quantum-diagonalization).
  
  3. A set of Krylov basis states implemented with qDRIFT randomized compilation of the time evolution operator. This approach yields shorter-depth circuits compared to Trotter-based decompositions of the time evolution and so can be used for quantum chemistry Hamiltonians. This technique has been applied to the ground state energy of polycyclic aromatic hydrocarbons [[6]](#references).

----------------------------------------------------------------------------------------------------

### Documentation

All documentation is available at https://quantum.cloud.ibm.com/docs/addons/qiskit-addon-sqd.

----------------------------------------------------------------------------------------------------

### Installation

We encourage installing this package via `pip`, when possible:

```bash
pip install 'qiskit-addon-sqd'
```

For more installation information refer to these [installation instructions](docs/install.rst).

----------------------------------------------------------------------------------------------------

### Getting started

A simple guide to help you get started quickly with this package is available [here](docs/guides/quickstart.ipynb).

----------------------------------------------------------------------------------------------------

### Use case examples

The sample-based quantum diagonalization technique can be used to implement a diverse set of workflows. Some examples of where it has been used include:

- Electronic structure calculations of the ground state energies of [iron-sulfur clusters](https://arxiv.org/abs/2405.05068)
- Estimating ground state energies to predict [band gaps of dielectrics](https://arxiv.org/abs/2503.10901)
- Estimating low-lying [molecular excited states](https://arxiv.org/abs/2411.00468)
- Simulating [interactions between molecules](https://arxiv.org/abs/2410.09209)
- Studying [solute-solvent interactions](https://arxiv.org/abs/2502.10189) in simulations of electronic structure
- Open-shell analysis of [molecular dissociation](https://arxiv.org/abs/2411.04827)
- Modeling reaction pathways for [photochemistry problems](https://arxiv.org/abs/2510.00484)
- Combining with entanglement forging to study reaction pathways for materials degradation via [hydrogen abstraction](https://arxiv.org/abs/2508.08229)
- Constructing subspaces from quantum Krylov basis states to perform ground state simulations of [impurity models](https://arxiv.org/abs/2501.09702) for Fermionic systems
- Using qDRIFT randomized compilation to lower the overhead of implementing Krylov basis states for [chemistry Hamiltonians](https://arxiv.org/abs/2508.02578) and with application to a molecule exhibiting a [half-Mobius electronic topology](https://arxiv.org/abs/2603.08696)
- Using SQD as a solver used in the context of embedding and fragmentation methods for molecular systems, such as to compute energies of [hydrogen rings and cyclohexane](https://arxiv.org/abs/2411.09861) and [of bi- and tri-metallic complexes](https://arxiv.org/abs/2512.14936), study [oxygen reduction reaction](https://arxiv.org/abs/2503.10923), [estimate energies of proteins](https://arxiv.org/abs/2512.17130) and [protein–ligand complexes](https://arxiv.org/abs/2605.01138), and to predict [tritium speciation](https://arxiv.org/abs/2606.30402).

----------------------------------------------------------------------------------------------------
### Technical discussion


#### Computational requirements

The computational cost of SQD is dominated by the eigenstate solver calls. At each step of the self-consistent configuration recovery iteration, `n_batches` of eigenstate solver calls are performed. The different calls are embarrassingly parallel. In this [tutorial](https://quantum.cloud.ibm.com/docs/tutorials/sample-based-quantum-diagonalization), those calls are inside a `for` loop. **It is highly recommended to perform these calls in parallel**.

The [`qiskit_addon_sqd.fermion.solve_fermion()`](qiskit_addon_sqd/fermion.py) function is multithreaded and capable of handling systems with ~25 spatial orbitals and ~10 electrons with subspace dimensions of ~$10^7$, using ~10-30 cores.

#### Choosing subspace dimensions

The choice of the subspace dimension affects the accuracy and runtime of the eigenstate solver. The larger the subspace the more accurate the calculation, at the cost of increasing the runtime and memory requirements. The optimal subspace size for a given system is not known, thus a convergence study with the subspace dimension may be performed as described in this [example](docs/guides/choose_subspace_dimension.ipynb).

#### Bounding the subspace dimension

The `samples_per_batch` argument of [`qiskit_addon_sqd.fermion.diagonalize_fermionic_hamiltonian()`](qiskit_addon_sqd/fermion.py) sets the number of bitstrings contained in each batch, and thereby controls the subspace dimension indirectly: in the case of quantum chemistry applications, its value sets an upper bound to the subspace dimension. The dimension that actually results depends on how many of the sampled bitstrings are distinct, and it grows over the course of the self-consistent configuration recovery iterations, so it is not known in advance. See this [example](docs/guides/select_open_closed_shell.ipynb) for more details.

The `max_dim` argument of the same function bounds the dimension directly, by limiting the number of CI strings retained in each spin sector. Since the subspace is spanned by the Cartesian product of the two spin sectors, `max_dim=d` caps the subspace dimension at `d**2`, while a tuple `max_dim=(d_a, d_b)` limits the spin-alpha and spin-beta sectors separately, capping the subspace dimension at `d_a * d_b` (with `symmetrize_spin=True`, the two limits must be equal). When a batch yields more CI strings than the limit allows, the strings requested through `include_configurations` and those carried over from the previous iteration are retained preferentially, and the remaining slots are filled with the most frequently sampled strings. Because it caps the size of the largest diagonalization that the eigenstate solver will be asked to perform, `max_dim` is a convenient way to keep the solver within a runtime and memory budget. See this [example](docs/guides/choose_subspace_dimension.ipynb) for more details.

#### Solvers

This package contains the functionality for the classical processing of user-provided samples. It can target Hamiltonians expressed as linear combinations of Pauli operators or second-quantized Fermionic operators. The projection and diagonalization steps are performed by a classical solver. We provide here two generic solvers, one for Fermionic systems and another for qubit systems. Other solvers that might be more efficient for specific systems can be interfaced by the users.

#### Trim SQD

Standard SQD diagonalizes each subsampled batch independently and keeps the best result, so the number of configurations it can consider is limited to what one affordable subspace can hold. **Trim SQD** instead partitions the bitstrings into batches, performs an intermediate diagonalization of each batch, then performs a larger diagonalization using the highest-weight determinants from each partition.  This method is based on joint research from the Cleveland Clinic Foundation, RIKEN, and IBM [[7](#References)], and can be enabled by passing a `TrimPolicy` object to the `diagonalize_fermionic_hamiltonian` function.

----------------------------------------------------------------------------------------------------

### Contributing

The source code is available [on GitHub](https://github.com/Qiskit/qiskit-addon-sqd).

The developer guide is located at [CONTRIBUTING.md](https://github.com/Qiskit/qiskit-addon-sqd/blob/main/CONTRIBUTING.md)
in the root of this project's repository.
By participating, you are expected to uphold Qiskit's [code of conduct](https://github.com/Qiskit/qiskit/blob/main/CODE_OF_CONDUCT.md).

----------------------------------------------------------------------------------------------------

### Citing this package

If you use this package in your research, use the [CITATION.bib](CITATION.bib) file in this project’s repository to cite the appropriate reference(s).

----------------------------------------------------------------------------------------------------

## Acknowledgements

This package includes an optional sampling strategy within the self-consistent
configuration recovery loop that trims determinants based on intermediate
diagonalization results. The implementation is based on joint research from
the Cleveland Clinic Foundation, RIKEN, and IBM. If you use this feature in
your research, please also use the citation for the paper, which can be found
in the `CITATION.bib` file with citation key `merz2026crossing`. An
implementation of the full workflow from that paper is expected to be available on GitHub
soon.

----------------------------------------------------------------------------------------------------

### License

[Apache License 2.0](LICENSE.txt)

----------------------------------------------------------------------------------------------------

### Deprecation policy

We follow [semantic versioning](https://semver.org/). We may occasionally make breaking changes in
order to improve the user experience. When possible, we will keep old interfaces and mark them as
deprecated, as long as they can co-exist with the new ones. Each substantial improvement, breaking
change, or deprecation will be documented in the [release notes](https://quantum.cloud.ibm.com/docs/api/qiskit-addon-sqd/release-notes).

----------------------------------------------------------------------------------------------------

### References

[1] Javier Robledo-Moreno, et al., [Chemistry Beyond Exact Solutions on a Quantum-Centric Supercomputer](https://arxiv.org/abs/2405.05068), arXiv:2405.05068 [quant-ph].

[2] Jeffery Yu, et al., [Quantum-Centric Algorithm for Sample-Based Krylov Diagonalization](https://arxiv.org/abs/2501.09702), arXiv:2501.09702 [quant-ph].

[3] Keita Kanno, et al., [Quantum-Selected Configuration Interaction: classical diagonalization of Hamiltonians in subspaces selected by quantum computers](https://arxiv.org/abs/2302.11320), arXiv:2302.11320 [quant-ph].

[4] Kenji Sugisaki, et al., [Hamiltonian simulation-based quantum-selected configuration interaction for large-scale electronic structure calculations with a quantum computer](https://arxiv.org/abs/2412.07218), arXiv:2412.07218 [quant-ph].

[5] Mathias Mikkelsen, Yuya O. Nakagawa, [Quantum-selected configuration interaction with time-evolved state](https://arxiv.org/abs/2412.13839), arXiv:2412.13839 [quant-ph].

[6] Samuele Piccinelli, et al., [Quantum chemistry with provable convergence via randomized sample-based Krylov quantum diagonalization](https://arxiv.org/abs/2508.02578), arXiv:2508.02578 [quant-ph].

[7] Kenneth M. Merz Jr., et al., [Crossing the 12,000-atom barrier with heterogeneous quantum-classical supercomputing: quantum chemistry of protein-ligand complexes](https://arxiv.org/abs/2605.01138), arXiv:2605.01138 [quant-ph].
