Skip to content

Commit

Permalink
Adds documentation for the default_filter_criterion (#726)
Browse files Browse the repository at this point in the history
* Adds documentation for the default_filter_criterion to explicit the singlet spin configuration assumption.

* Fixes the documentation.

* Fixes some checks.

* Fixes style.

* Moves the docstring from the method get_default_filter_criterion to the class docstring.
Changes the test for custom filters to a more relevant example with the doublets of BeH

* Changes are now applied to the class located at qiskit_nature/second_q/problems

* Fixes the test

* Fixes the test

* Fixes the test

* Updates documentation the test

* Retests after coverall issue

* Retest after coverall issue

* Fix indenting of the docstring

* Update qiskit_nature/second_q/problems/electronic_structure_problem.py

Co-authored-by: Max Rossmannek <[email protected]>
Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
Co-authored-by: Max Rossmannek <[email protected]>
  • Loading branch information
4 people authored Aug 5, 2022
1 parent 23e03e6 commit efab7e0
Show file tree
Hide file tree
Showing 3 changed files with 90 additions and 0 deletions.
1 change: 1 addition & 0 deletions .pylintdict
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,7 @@ interatomic
internuclear
interpretable
ints
isclose
ising
iso
isoleucine
Expand Down
31 changes: 31 additions & 0 deletions qiskit_nature/second_q/problems/electronic_structure_problem.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,37 @@ class ElectronicStructureProblem(BaseProblem):
The attributes `num_particles` and `num_spin_orbitals` are only available _after_ the
`second_q_ops()` method has been called! Note, that if you do so, the method will be executed
again when the problem is being solved.
In the fermionic case the default filter ensures that the number of particles is being
preserved.
.. note::
The default filter_criterion assumes a singlet spin configuration. This means, that the
number of alpha-spin electrons is equal to the number of beta-spin electrons.
If the :class:`~qiskit_nature.second_q.properties.AngularMomentum`
property is available, one can correctly filter a non-singlet spin configuration with a
custom `filter_criterion` similar to the following:
.. code-block:: python
import numpy as np
from qiskit_nature.second_q.algorithms import NumPyEigensolverFactory
expected_spin = 2
expected_num_electrons = 6
def filter_criterion_custom(eigenstate, eigenvalue, aux_values):
num_particles_aux = aux_values["ParticleNumber"][0]
total_angular_momentum_aux = aux_values["AngularMomentum"][0]
return (
np.isclose(expected_spin, total_angular_momentum_aux) and
np.isclose(expected_num_electrons, num_particles_aux)
)
solver = NumPyEigensolverFactory(filter_criterion=filter_criterion_spin)
"""

def __init__(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,14 @@
""" Test Numerical qEOM excited states calculation """

import unittest

from test import QiskitNatureTestCase
import numpy as np
from qiskit import BasicAer
from qiskit.utils import algorithm_globals, QuantumInstance
from qiskit.algorithms import NumPyMinimumEigensolver, NumPyEigensolver

from qiskit_nature.second_q.transformers import ActiveSpaceTransformer
from qiskit_nature.second_q.drivers import UnitsType
from qiskit_nature.second_q.drivers import PySCFDriver
from qiskit_nature.second_q.mappers import (
Expand Down Expand Up @@ -151,6 +153,62 @@ def filter_criterion(eigenstate, eigenvalue, aux_values):
for idx, energy in enumerate(self.reference_energies):
self.assertAlmostEqual(computed_energies[idx], energy, places=4)

def test_custom_filter_criterion(self):
"""Test NumPyEigenSolverFactory with ExcitedStatesEigensolver + Custom filter criterion
for doublet states"""

driver = PySCFDriver(
atom="Be .0 .0 .0; H .0 .0 0.75",
unit=UnitsType.ANGSTROM,
charge=0,
spin=1,
basis="sto3g",
)

transformer = ActiveSpaceTransformer(
num_electrons=(1, 2),
num_molecular_orbitals=4,
)
# We define an ActiveSpaceTransformer to reduce the duration of this test example.

converter = QubitConverter(JordanWignerMapper(), z2symmetry_reduction="auto")

esp = ElectronicStructureProblem(driver, [transformer])

expected_spin = 0.75 # Doublet states
expected_num_electrons = 3 # 1 alpha electron + 2 beta electrons

# pylint: disable=unused-argument
def custom_filter_criterion(eigenstate, eigenvalue, aux_values):
num_particles_aux = aux_values["ParticleNumber"][0]
total_angular_momentum_aux = aux_values["AngularMomentum"][0]

return np.isclose(expected_spin, total_angular_momentum_aux) and np.isclose(
expected_num_electrons, num_particles_aux
)

solver = NumPyEigensolverFactory(filter_criterion=custom_filter_criterion)
esc = ExcitedStatesEigensolver(converter, solver)
results = esc.solve(esp)

# filter duplicates from list
computed_energies = [results.computed_energies[0]]
for comp_energy in results.computed_energies[1:]:
if not np.isclose(comp_energy, computed_energies[-1]):
computed_energies.append(comp_energy)

ref_energies = [
-2.6362023196223254,
-2.2971398524128923,
-2.2020252702733165,
-2.1044859216523752,
-1.696132447109807,
-1.6416831059956618,
]

for idx, energy in enumerate(ref_energies):
self.assertAlmostEqual(computed_energies[idx], energy, places=3)


if __name__ == "__main__":
unittest.main()

0 comments on commit efab7e0

Please sign in to comment.