Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Pass the approximate ground state as an SCIState instance #42

Merged
merged 6 commits into from
Nov 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 14 additions & 17 deletions qiskit_addon_dice_solver/dice_solver.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@

import numpy as np
from pyscf import tools
from qiskit_addon_sqd.fermion import bitstring_matrix_to_ci_strs
from qiskit_addon_sqd.fermion import bitstring_matrix_to_ci_strs, SCIState

# Ensure the runtime linker can find the local boost binaries at runtime
DICE_BIN = os.path.join(os.path.abspath(os.path.dirname(__file__)), "bin")
Expand Down Expand Up @@ -62,9 +62,7 @@ def solve_hci(
mpirun_options: Sequence[str] | str | None = None,
temp_dir: str | Path | None = None,
clean_temp_dir: bool = True,
) -> tuple[
float, np.ndarray, tuple[np.ndarray, np.ndarray], tuple[np.ndarray, np.ndarray]
]:
) -> tuple[float, SCIState, tuple[np.ndarray, np.ndarray]]:
"""
Approximate the ground state of a molecular Hamiltonian using the heat bath configuration interaction method.

Expand Down Expand Up @@ -123,8 +121,7 @@ def solve_hci(

Returns:
- Minimum energy from SCI calculation
- SCI coefficients
- SCI strings
- Approximate ground state from SCI
- Average orbital occupancy
"""
n_alpha, n_beta = nelec
Expand Down Expand Up @@ -158,18 +155,15 @@ def solve_hci(
_call_dice(dice_dir, mpirun_options)

# Read and convert outputs
e_dice, sci_coefficients, sci_strs, avg_occupancies = _read_dice_outputs(
dice_dir, norb
)
e_dice, sci_state, avg_occupancies = _read_dice_outputs(dice_dir, norb)

# Clean up the temp directory of intermediate files, if desired
if clean_temp_dir:
shutil.rmtree(dice_dir)

return (
e_dice,
sci_coefficients,
sci_strs,
sci_state,
(avg_occupancies[:norb], avg_occupancies[norb:]),
)

Expand All @@ -183,7 +177,7 @@ def solve_fermion(
mpirun_options: Sequence[str] | str | None = None,
temp_dir: str | Path | None = None,
clean_temp_dir: bool = True,
) -> tuple[float, np.ndarray, tuple[np.ndarray, np.ndarray]]:
) -> tuple[float, SCIState, tuple[np.ndarray, np.ndarray]]:
"""
Approximate the ground state of a molecular Hamiltonian given a bitstring matrix defining the Hilbert subspace.

Expand Down Expand Up @@ -239,13 +233,13 @@ def solve_fermion(

Returns:
- Minimum energy from SCI calculation
- SCI coefficients
- Approximate ground state from SCI
- Average orbital occupancy
"""
ci_strs = bitstring_matrix_to_ci_strs(bitstring_matrix)
num_up = format(ci_strs[0][0], "b").count("1")
num_dn = format(ci_strs[1][0], "b").count("1")
e_dice, sci_coefficients, _, avg_occupancies = solve_hci(
e_dice, sci_state, avg_occupancies = solve_hci(
hcore=hcore,
eri=eri,
norb=hcore.shape[0],
Expand All @@ -259,12 +253,12 @@ def solve_fermion(
temp_dir=temp_dir,
clean_temp_dir=clean_temp_dir,
)
return e_dice, sci_coefficients, avg_occupancies
return e_dice, sci_state, avg_occupancies


def _read_dice_outputs(
dice_dir: str | Path, num_orbitals: int
) -> tuple[float, np.ndarray, tuple[np.ndarray, np.ndarray], np.ndarray]:
) -> tuple[float, SCIState, np.ndarray]:
"""Calculate the estimated ground state energy and average orbitals occupancies from Dice outputs."""
# Read in the avg orbital occupancies
spin1_rdm_dice = np.loadtxt(os.path.join(dice_dir, "spin1RDM.0.0.txt"), skiprows=1)
Expand All @@ -288,8 +282,11 @@ def _read_dice_outputs(
sci_coefficients, ci_strs_a, ci_strs_b = _construct_ci_vec_from_amplitudes(
amps, ci_strs
)
sci_state = SCIState(
amplitudes=sci_coefficients, ci_strs_a=ci_strs_a, ci_strs_b=ci_strs_b
)

return energy_dice, sci_coefficients, (ci_strs_a, ci_strs_b), avg_occupancies
return energy_dice, sci_state, avg_occupancies


def _call_dice(dice_dir: Path, mpirun_options: Sequence[str] | str | None) -> None:
Expand Down
4 changes: 4 additions & 0 deletions releasenotes/notes/sci-state-2e80dcf3458f30dd.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
---
upgrade:
- |
:func:`qiskit_addon_dice_solver.solve_hci` and :func:`qiskit_addon_dice_solver.solve_fermion` now return an ``qiskit_addon_sqd.fermion.SCIState`` instance to describe the ground state.
4 changes: 4 additions & 0 deletions releasenotes/notes/solve-hci-370360b1472fe000.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
---
features:
- |
Added a :func:`qiskit_addon_dice_solver.solve_hci` function, which behaves very similarly to :func:`qiskit_addon_dice_solver.solve_fermion` but provides a higher level of control over the behavior of the underlying ``Dice`` command line application.
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
packages=find_packages(),
package_data={"dice_solver": ["bin/Dice", "bin/*.so*"]},
include_package_data=True,
install_requires=["numpy", "pyscf", "qiskit-addon-sqd>=0.6"],
install_requires=["numpy", "pyscf", "qiskit-addon-sqd>=0.8"],
extras_require={
"dev": ["tox>=4.0", "pytest>=8.0"],
"docs": [
Expand Down