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

Qeom refactoring and upgrades #971

Merged
merged 25 commits into from
Dec 22, 2022

Conversation

Anthony-Gandon
Copy link
Contributor

@Anthony-Gandon Anthony-Gandon commented Nov 17, 2022

Closes #769
Closes #415
Closes #403
Closes #52

Summary

Proposition for a modification to QEOM internals to :

  • Make the code easier to follow
  • Improve the potential for parallelism
  • Improve the performances of the classical calculations by using a custom treatment of the tapering.

A new functionality is also added to compute excited state properties and transition amplitudes of arbitrary observables.

The typical interface to use it would be the following:

from qiskit.algorithms.optimizers import COBYLA
from qiskit.primitives import Estimator

from qiskit_nature.units import DistanceUnit
from qiskit_nature.second_q.algorithms import VQEUCCFactory, GroundStateEigensolver
from qiskit_nature.second_q.algorithms.excited_states_solvers import QEOM
from qiskit_nature.second_q.circuit.library import UCCSD
from qiskit_nature.second_q.drivers import PySCFDriver
from qiskit_nature.second_q.mappers import QubitConverter
from qiskit_nature.second_q.mappers import JordanWignerMapper

import numpy as np

optimizer = COBYLA(maxiter=500,disp=False)
qubit_converter = QubitConverter(JordanWignerMapper(), z2symmetry_reduction=None, two_qubit_reduction=False)

new_driver = PySCFDriver(
    atom="H 0 0 0; H 0 0 1.735",
    basis="sto3g",
    charge=0,
    spin=0,
    unit=DistanceUnit.ANGSTROM,
)
new_es_problem = new_driver.run()
hamiltonian_op, _ = new_es_problem.second_q_ops()
aux_ops = {'hamiltonian':hamiltonian_op}

# Qeom results
vqe_solver = VQEUCCFactory(Estimator(), UCCSD(), optimizer)
me_gsc = GroundStateEigensolver(qubit_converter, vqe_solver)
qeom_solver = QEOM(me_gsc, estimator=Estimator(), excitations='sd', aux_eval_rules="all")
results_qeom = qeom_solver.solve(new_es_problem, aux_operators=aux_ops)

print("Aux QEOM")
for aux_op_eval in results_qeom.aux_operators_evaluated:
    print(aux_op_eval)

print("Transi QEOM")
for indice, value in results_qeom.raw_result.transition_amplitudes.items():
    print(indice, value)

Details and comments

The following guides details some of the changes that are proposed
QEOM_refactoring-3.pdf

@Anthony-Gandon Anthony-Gandon changed the title Qeom anthony Qeom refactoring and upgrades Nov 17, 2022
@coveralls
Copy link

coveralls commented Nov 25, 2022

Pull Request Test Coverage Report for Build 3755972353

  • 262 of 321 (81.62%) changed or added relevant lines in 5 files are covered.
  • 19 unchanged lines in 4 files lost coverage.
  • Overall coverage decreased (-0.04%) to 85.878%

Changes Missing Coverage Covered Lines Changed/Added Lines %
qiskit_nature/second_q/algorithms/excited_states_solvers/excited_states_eigensolver.py 2 3 66.67%
qiskit_nature/second_q/algorithms/excited_states_solvers/qeom_electronic_ops_builder.py 0 1 0.0%
qiskit_nature/second_q/mappers/qubit_converter.py 43 49 87.76%
qiskit_nature/second_q/algorithms/excited_states_solvers/qeom.py 213 264 80.68%
Files with Coverage Reduction New Missed Lines %
qiskit_nature/second_q/mappers/qubit_converter.py 1 89.83%
qiskit_nature/second_q/problems/vibrational_structure_result.py 2 55.77%
qiskit_nature/second_q/algorithms/excited_states_solvers/qeom.py 8 80.31%
qiskit_nature/second_q/problems/electronic_structure_result.py 8 89.45%
Totals Coverage Status
Change from base Build 3741697404: -0.04%
Covered Lines: 17562
Relevant Lines: 20450

💛 - Coveralls

Copy link
Member

@mrossinek mrossinek left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this PR is overall already in great shape. Thanks a lot Anthony for all the work here!

These are quite a few comments and I will need to do another pass of the actual QEOM code in a little bit more detail with some more time on my hands. But I figured I should post my review as it is now to give you time to work on these comments.

Copy link
Member

@mrossinek mrossinek left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A few more comments from my side 👍

This is shaping up very nicely! I am skipping the changes done to the QubitConverter on purpose, since it will be refactored again as part of #967 at which point we can revert these unreleased changes and update the QEOM code accordingly. I would still like to get this long-standing PR out before the QubitConverter refactor hits because it allows us to do these two things largely in parallel 👍

(the above is just a comment for a potential other reviewer coming across this)

Comment on lines 874 to 881
qeom_result.m_matrix = h_mat[: len(h_mat) // 2, : len(h_mat) // 2]
qeom_result.v_matrix = s_mat[: len(h_mat) // 2, : len(h_mat) // 2]
qeom_result.q_matrix = h_mat[len(h_mat) // 2 :, : len(h_mat) // 2]
qeom_result.w_matrix = s_mat[len(h_mat) // 2 :, : len(h_mat) // 2]
qeom_result.m_matrix_std = h_mat_std[0, 0]
qeom_result.v_matrix_std = s_mat_std[0, 0]
qeom_result.q_matrix_std = h_mat_std[0, 1]
qeom_result.w_matrix_std = s_mat_std[0, 1]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is good, thank you 👍

@manoelmarques what would the deprecation strategy look like here, if I want to make these read-only properties of the result object. Doing this would allow us to put this computation logic into the property getters and ensure that the matrices stored in the result are always consistent (plus it simplifies the code here a bit).

Copy link
Contributor

@manoelmarques manoelmarques Dec 13, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you put the calculating logic in the init method, then you just need the deprecation msg in the setters. This way the user still can use the deprecated setter which would override the calculation done in the init.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, that's a good idea 👍 @Anthony-Gandon could you do that, please?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As discussed with @mrossinek , I could not put the calculating logic in the init method. I changed the getters instead.

Copy link
Member

@mrossinek mrossinek left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is looking very good, thanks a lot, Anthony!

I have a last round of comments, mostly on some docstring details 👍

Copy link
Member

@mrossinek mrossinek left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay some final (minor) observations but other than that this looks good to me 👍
We will just need to keep in mind that, once we progress on #972 and #999, we should revert the public API changes (as much as possible) done to the QubitConverter in this PR.
We can see about the details of that as part of working on the epic mentioned above.

@Anthony-Gandon
Copy link
Contributor Author

I'm not sure why we did not have a mypy error previously when

if isinstance(self.solver, MinimumEigensolverFactory):
    self._gsc._solver = self.solver.get_solver(problem, self.qubit_converter)

(because self._gscc is GroundStateSolver and does not have a _solver attribute, only GroundStateEigensolver has). Can we add a #type: ignore because anyway this part will be subject to changes in the near future.

Copy link
Member

@mrossinek mrossinek left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am tentatively approving this PR because I think it looks good as it is.

I am not quite sure what you meant in your last comment though, so I will hold off with merging until that is cleared up either here or offline.

EDIT: the questionable type ignore statement is already included in this PR and fine by me 👍

Thanks a lot for all your work, Anthony!

@mrossinek mrossinek merged commit 2f01d20 into qiskit-community:main Dec 22, 2022
@Anthony-Gandon Anthony-Gandon deleted the qeom_anthony branch May 24, 2023 15:50
Anthony-Gandon added a commit to Anthony-Gandon/qiskit-nature that referenced this pull request May 25, 2023
* QEOM refactoring and changes. All grouped under one commit to fix the authoring of the commits v2

* QEOM refactoring and changes. Add new files

* Modify type of argument op_aux_op_dict to pass test

* Make black and type check

* Make black and change name

* Change file name

* small modifs

* Fix faulty tests

* Fix mypy and test

* New unittest and small fixes

* Fix Max comments, change tests, update release not, change groundstateeigensolver behavior

* Add parameter for eigenvalue treshold, make black

* Response to comments and small fixes: ground_state_eigensolver, qeom, qubit_converter

* Fix lint and style

* Fix comments and change docstring

* changes to get_qubit_operator

* changes to get_qubit_operator

* Excitations in QEOM becomes public attribute

* fix doctring qeom

* Update excitation docstring to match UCC docstring
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
4 participants