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

Add support for non-hermitian operators in AerPauliExpectation #7857

Merged
merged 17 commits into from
Apr 8, 2022

Conversation

Anthony-Gandon
Copy link
Contributor

Summary

QEOM creates a dictionary of operators to evaluate on the groundstate.
When using the noisy simulators (qasm_simulator or aer_simulator), one
could either use PauliExpectation (with noise) or AerPauliExpectation
(without noise). PauliExpectation works with non-hermitian operators
but internal methods of AerPauliExpectation raised an Error.
This is a workaround to this limitation.
Note that using include_custom=True on qasm allows the VQE to use a
local AerPauliExpectation without using the "expectation" input.
This does not apply to QEOM and one should explicitly define the
"expectation" input of the VQE for it to apply globally.

Fixes Qiskit#415

QEOM creates a dictionary of operators to evaluate on the groundstate.
When using the noisy simulators (qasm_simulator or aer_simulator), one
could either use PauliExpectation (with noise) or AerPauliExpectation
(without noise). PauliExpectation works with non-hermitian operators
but internal methods of AerPauliExpectation raised an Error.
This is a workaround to this limitation.
Note that using include_custom=True on qasm allows the VQE to use a
local AerPauliExpectation without using the "expectation" input.
This does not apply to QEOM and one should explicitly define the
"expectation" input of the VQE for it to apply globally.
@CLAassistant
Copy link

CLAassistant commented Apr 1, 2022

CLA assistant check
All committers have signed the CLA.

@Cryoris
Copy link
Contributor

Cryoris commented Apr 1, 2022

Hi Anthony, could you add a test that checks that the AerPauliExpectation now works with non-hermitian observables and returns the same value as the other expectation converters? 🙂 Also, could you add a releasenote? See here on how to do that.

@Cryoris Cryoris added Changelog: New Feature Include in the "Added" section of the changelog mod: opflow Related to the Opflow module labels Apr 1, 2022
Fixes Qiskit#415

QEOM creates a dictionary of operators to evaluate on the groundstate.
When using the noisy simulators (qasm_simulator or aer_simulator), one
could either use PauliExpectation (with noise) or AerPauliExpectation
(without noise). PauliExpectation works with non-hermitian operators
but internal methods of AerPauliExpectation raised an Error.
This is a workaround to this limitation.
Note that using include_custom=True on qasm allows the VQE to use a
local AerPauliExpectation without using the "expectation" input.
This does not apply to QEOM and one should explicitly define the
"expectation" input of the VQE for it to apply globally.
… into qeom_commit_aerpauliexpectation

# Conflicts:
#	qiskit/opflow/expectations/aer_pauli_expectation.py
… into qeom_commit_aerpauliexpectation

# Conflicts:
#	qiskit/opflow/expectations/aer_pauli_expectation.py
… into qeom_commit_aerpauliexpectation

# Conflicts:
#	test/python/opflow/test_aer_pauli_expectation.py
Anthony-Gandon and others added 2 commits April 4, 2022 10:25
Co-authored-by: Julien Gacon <gaconju@gmail.com>
Use a generator instead of list
@Anthony-Gandon
Copy link
Contributor Author

I changed the line giving the pylint error (I thought It was only a warning at first). Basically just all(k.is_hermitian() for k in ...) instead of all([k.is_hermitian() for k in ...])

@coveralls
Copy link

coveralls commented Apr 4, 2022

Pull Request Test Coverage Report for Build 2115065714

  • 9 of 9 (100.0%) changed or added relevant lines in 1 file are covered.
  • 3 unchanged lines in 1 file lost coverage.
  • Overall coverage decreased (-0.001%) to 83.94%

Files with Coverage Reduction New Missed Lines %
qiskit/pulse/library/waveform.py 3 89.36%
Totals Coverage Status
Change from base Build 2109982282: -0.001%
Covered Lines: 54195
Relevant Lines: 64564

💛 - Coveralls

Copy link
Contributor

@Cryoris Cryoris left a comment

Choose a reason for hiding this comment

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

That's a great feature to support, I left some comments below!

qiskit/opflow/expectations/aer_pauli_expectation.py Outdated Show resolved Hide resolved
"""pauli expect state vector with non hermitian operator test"""
states_op = ListOp([One, Zero, Plus, Minus])

op = np.array([[0, 1], [2, 3]])
Copy link
Contributor

Choose a reason for hiding this comment

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

Should we add a test for other primitives than MatrixOp? What about e.g. 1j * Y as non-hermitian operator?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

A test case was added with the primitive PauliOp (I used 1jX because with 1jY all the expected values for Plus, Minus, 0, 1 were null). The names of the two test cases were adapted consequently.

Anthony-Gandon and others added 3 commits April 7, 2022 18:45
Co-authored-by: Julien Gacon <gaconju@gmail.com>
…ation-653d8e16de4eca07.yaml

Co-authored-by: Julien Gacon <gaconju@gmail.com>

op = 1j * X

converted_meas = self.expect.convert(~StateFn(op) @ states_op)
Copy link
Contributor

Choose a reason for hiding this comment

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

Using ~ will complex conjugate the observable, which we don't really want

Suggested change
converted_meas = self.expect.convert(~StateFn(op) @ states_op)
converted_meas = self.expect.convert(StateFn(op, is_measurement=True) @ states_op)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I agree with the commit and I changed the expected result from [0, 0, -1j, 1j] to [0, 0, 1j, -1j] to match this modification.

op_mat = np.array([[0, 1], [2, 3]])
op = MatrixOp(op_mat)

converted_meas = self.expect.convert(~StateFn(op) @ states_op)
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
converted_meas = self.expect.convert(~StateFn(op) @ states_op)
converted_meas = self.expect.convert(StateFn(op, is_measurement=True) @ states_op)

@mergify mergify bot merged commit d8b4fdc into Qiskit:main Apr 8, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Changelog: New Feature Include in the "Added" section of the changelog mod: opflow Related to the Opflow module
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants