-
Notifications
You must be signed in to change notification settings - Fork 210
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Refactor FCIDump integration into qiskit_nature.second_q.formats (#799)
* Refactor FCIDump integration into qiskit_nature.second_q.formats * Update qiskit_nature/second_q/formats/fcidump/fcidump.py Co-authored-by: Max Rossmannek <[email protected]> * update translator * Update qiskit_nature/second_q/formats/fcidump/fcidump.py Co-authored-by: Max Rossmannek <[email protected]> * Update qiskit_nature/second_q/formats/fcidump/fcidump.py Co-authored-by: Max Rossmannek <[email protected]> * Update qiskit_nature/second_q/formats/fcidump/fcidump.py Co-authored-by: Max Rossmannek <[email protected]> * Update qiskit_nature/second_q/formats/fcidump/fcidump.py Co-authored-by: Max Rossmannek <[email protected]> * Update qiskit_nature/second_q/formats/fcidump/fcidump.py Co-authored-by: Max Rossmannek <[email protected]> * Update test/second_q/formats/fcidump/test_fcidump.py Co-authored-by: Max Rossmannek <[email protected]> * Update test/second_q/formats/fcidump/test_fcidump.py Co-authored-by: Max Rossmannek <[email protected]> * Update test/second_q/formats/fcidump/test_methods_fcidump.py Co-authored-by: Max Rossmannek <[email protected]> * Update test/second_q/formats/fcidump/test_methods_fcidump.py Co-authored-by: Max Rossmannek <[email protected]> * enable unit test * Apply suggestions from code review * fix energy name * Update qiskit_nature/second_q/formats/fcidump/fcidump.py Co-authored-by: Max Rossmannek <[email protected]> * Update qiskit_nature/second_q/formats/fcidump/fcidump.py Co-authored-by: Max Rossmannek <[email protected]> * Update qiskit_nature/second_q/formats/fcidump/fcidump.py Co-authored-by: Max Rossmannek <[email protected]> * Update qiskit_nature/second_q/formats/fcidump/fcidump.py Co-authored-by: Max Rossmannek <[email protected]> * change _parse to return FCIDump Co-authored-by: Max Rossmannek <[email protected]>
- Loading branch information
1 parent
d1b5e07
commit aaa41f7
Showing
17 changed files
with
1,863 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
FCIDump | ||
============================== | ||
|
||
.. automodule:: qiskit_nature.second_q.formats.fcidump | ||
:no-members: | ||
:no-inherited-members: | ||
:no-special-members: |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -23,6 +23,7 @@ | |
.. autosummary:: | ||
:toctree: | ||
fcidump | ||
qcschema | ||
""" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
# This code is part of Qiskit. | ||
# | ||
# (C) Copyright IBM 2020, 2022. | ||
# | ||
# This code is licensed under the Apache License, Version 2.0. You may | ||
# obtain a copy of this license in the LICENSE.txt file in the root directory | ||
# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0. | ||
# | ||
# Any modifications or derivative works of this code must retain this | ||
# copyright notice, and modified files need to carry a notice indicating | ||
# that they have been altered from the originals. | ||
|
||
""" | ||
The FCIDump (:mod:`qiskit_nature.second_q.formats.fcidump`) | ||
============================================================= | ||
Contains tools to parse and dump FCIDump files. | ||
.. currentmodule:: qiskit_nature.second_q.formats.fcidump | ||
.. autosummary:: | ||
:toctree: ../stubs/ | ||
:nosignatures: | ||
FCIDump | ||
""" | ||
|
||
from .fcidump import FCIDump | ||
|
||
__all__ = ["FCIDump"] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
# This code is part of Qiskit. | ||
# | ||
# (C) Copyright IBM 2020, 2022. | ||
# | ||
# This code is licensed under the Apache License, Version 2.0. You may | ||
# obtain a copy of this license in the LICENSE.txt file in the root directory | ||
# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0. | ||
# | ||
# Any modifications or derivative works of this code must retain this | ||
# copyright notice, and modified files need to carry a notice indicating | ||
# that they have been altered from the originals. | ||
|
||
"""FCIDump dumper.""" | ||
|
||
from typing import List, Union, TextIO, Tuple, Iterator, Any | ||
import itertools | ||
import numpy as np | ||
|
||
|
||
def _dump_1e_ints( | ||
hij: np.ndarray, | ||
mos: Union[range, List[int]], | ||
outfile: TextIO, | ||
beta: bool = False, | ||
) -> None: | ||
idx_offset = 1 if not beta else 1 + len(mos) | ||
hij_elements = set() | ||
for i, j in itertools.product(mos, repeat=2): | ||
if i == j: | ||
_write_to_outfile(outfile, hij[i][j], (i + idx_offset, j + idx_offset, 0, 0)) | ||
continue | ||
if (j, i) in hij_elements and np.isclose(hij[i][j], hij[j][i]): | ||
continue | ||
_write_to_outfile(outfile, hij[i][j], (i + idx_offset, j + idx_offset, 0, 0)) | ||
hij_elements.add((i, j)) | ||
|
||
|
||
def _dump_2e_ints( | ||
hijkl: np.ndarray, mos: Union[range, List[int]], outfile: TextIO, beta: int = 0 | ||
) -> None: | ||
idx_offsets = [1, 1] | ||
for b in range(beta): | ||
idx_offsets[1 - b] += len(mos) | ||
hijkl_elements = set() | ||
for elem in itertools.product(mos, repeat=4): | ||
if np.isclose(hijkl[elem], 0.0, atol=1e-14): | ||
continue | ||
if len(set(elem)) == 1: | ||
_write_to_outfile( | ||
outfile, | ||
hijkl[elem], | ||
( | ||
*[e + idx_offsets[0] for e in elem[:2]], | ||
*[e + idx_offsets[1] for e in elem[2:]], | ||
), | ||
) | ||
continue | ||
if ( | ||
beta != 1 | ||
and elem[::-1] in hijkl_elements | ||
and np.isclose(hijkl[elem], hijkl[elem[::-1]]) | ||
): | ||
continue | ||
bra_perms = set(itertools.permutations(elem[:2])) | ||
ket_perms = set(itertools.permutations(elem[2:])) | ||
permutations: Iterator[Any] | ||
if beta == 1: | ||
permutations = itertools.product(bra_perms, ket_perms) | ||
else: | ||
permutations = itertools.chain( | ||
itertools.product(bra_perms, ket_perms), | ||
itertools.product(ket_perms, bra_perms), | ||
) | ||
for perm in {e1 + e2 for e1, e2 in permutations}: | ||
if perm in hijkl_elements and np.isclose(hijkl[elem], hijkl[perm]): | ||
break | ||
else: | ||
_write_to_outfile( | ||
outfile, | ||
hijkl[elem], | ||
( | ||
*[e + idx_offsets[0] for e in elem[:2]], | ||
*[e + idx_offsets[1] for e in elem[2:]], | ||
), | ||
) | ||
hijkl_elements.add(elem) | ||
|
||
|
||
def _write_to_outfile(outfile: TextIO, value: float, indices: Tuple): | ||
outfile.write(f"{value:23.16E}{indices[0]:4d}{indices[1]:4d}{indices[2]:4d}{indices[3]:4d}\n") |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,121 @@ | ||
# This code is part of Qiskit. | ||
# | ||
# (C) Copyright IBM 2020, 2022. | ||
# | ||
# This code is licensed under the Apache License, Version 2.0. You may | ||
# obtain a copy of this license in the LICENSE.txt file in the root directory | ||
# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0. | ||
# | ||
# Any modifications or derivative works of this code must retain this | ||
# copyright notice, and modified files need to carry a notice indicating | ||
# that they have been altered from the originals. | ||
|
||
"""FCIDump""" | ||
|
||
from __future__ import annotations | ||
|
||
from typing import List | ||
from dataclasses import dataclass | ||
from pathlib import Path | ||
import numpy as np | ||
|
||
from qiskit_nature import QiskitNatureError | ||
|
||
|
||
from .dumper import _dump_1e_ints, _dump_2e_ints, _write_to_outfile | ||
|
||
|
||
@dataclass | ||
class FCIDump: | ||
""" | ||
Qiskit Nature dataclass for representing the FCIDump format. | ||
The FCIDump format is partially defined in Knowles1989. | ||
References: | ||
Knowles1989: Peter J. Knowles, Nicholas C. Handy, | ||
A determinant based full configuration interaction program, | ||
Computer Physics Communications, Volume 54, Issue 1, 1989, Pages 75-83, | ||
ISSN 0010-4655, https://doi.org/10.1016/0010-4655(89)90033-7. | ||
""" | ||
|
||
hij: np.ndarray | ||
"""The alpha 1-electron integrals.""" | ||
hijkl: np.ndarray | ||
"""The alpha/alpha 2-electron integrals.""" | ||
hij_b: np.ndarray | None | ||
"""The beta 1-electron integrals.""" | ||
hijkl_ba: np.ndarray | None | ||
"""The beta/alpha 2-electron integrals.""" | ||
hijkl_bb: np.ndarray | None | ||
"""The beta/beta 2-electron integrals.""" | ||
multiplicity: int | ||
"""The multiplicity.""" | ||
num_electrons: int | ||
"""The number of electrons.""" | ||
num_orbitals: int | ||
"""The number of orbitals.""" | ||
constant_energy: float | None | ||
"""The constant energy comprising (for example) the nuclear repulsion energy | ||
and inactive energies.""" | ||
orbsym: List[str] | None | ||
"""A list of spatial symmetries of the orbitals.""" | ||
isym: int | ||
"""The spatial symmetry of the wave function.""" | ||
|
||
@classmethod | ||
def from_file(cls, fcidump: str | Path) -> FCIDump: | ||
"""Constructs an FCIDump object from a file.""" | ||
# pylint: disable=cyclic-import | ||
from .parser import _parse | ||
|
||
return _parse(fcidump if isinstance(fcidump, Path) else Path(fcidump)) | ||
|
||
def to_file(self, fcidump: str | Path) -> None: | ||
"""Dumps an FCIDump object to a file. | ||
Args: | ||
fcidump: Path to the output file. | ||
Raises: | ||
QiskitNatureError: invalid number of orbitals. | ||
QiskitNatureError: not all beta-spin related matrices are either None or not None. | ||
""" | ||
outpath = fcidump if isinstance(fcidump, Path) else Path(fcidump) | ||
# either all beta variables are None or all of them are not | ||
if not all(h is None for h in [self.hij_b, self.hijkl_ba, self.hijkl_bb]) and not all( | ||
h is not None for h in [self.hij_b, self.hijkl_ba, self.hijkl_bb] | ||
): | ||
raise QiskitNatureError("Invalid beta variables.") | ||
norb = self.num_orbitals | ||
nelec = self.num_electrons | ||
einact = self.constant_energy | ||
ms2 = self.multiplicity - 1 | ||
if norb != self.hij.shape[0] or norb != self.hijkl.shape[0]: | ||
raise QiskitNatureError( | ||
f"Invalid number of orbitals {norb} {self.hij.shape[0]} {self.hijkl.shape[0]}" | ||
) | ||
|
||
mos = range(norb) | ||
with outpath.open("w", encoding="utf8") as outfile: | ||
# print header | ||
outfile.write(f"&FCI NORB={norb:4d},NELEC={nelec:4d},MS2={ms2:4d}\n") | ||
if self.orbsym is None: | ||
outfile.write(" ORBSYM=" + "1," * norb + "\n") | ||
else: | ||
if len(self.orbsym) != norb: | ||
raise QiskitNatureError(f"Invalid number of orbitals {norb} {len(self.orbsym)}") | ||
outfile.write(" ORBSYM=" + ",".join(self.orbsym) + "\n") | ||
outfile.write(f" ISYM={self.isym:d},\n&END\n") | ||
# append 2e integrals | ||
_dump_2e_ints(self.hijkl, mos, outfile) | ||
if self.hijkl_ba is not None: | ||
_dump_2e_ints(self.hijkl_ba.transpose(), mos, outfile) | ||
if self.hijkl_bb is not None: | ||
_dump_2e_ints(self.hijkl_bb, mos, outfile) | ||
# append 1e integrals | ||
_dump_1e_ints(self.hij, mos, outfile) | ||
if self.hij_b is not None: | ||
_dump_1e_ints(self.hij_b, mos, outfile) | ||
# TODO append MO energies (last three indices are 0) | ||
# append inactive energy | ||
_write_to_outfile(outfile, einact, (0, 0, 0, 0)) |
Oops, something went wrong.