Skip to content

Add ParameterExpression.numeric to cast to number#11109

Merged
ElePT merged 2 commits into
Qiskit:mainfrom
jakelishman:parameterexpression-numeric
Dec 19, 2023
Merged

Add ParameterExpression.numeric to cast to number#11109
ElePT merged 2 commits into
Qiskit:mainfrom
jakelishman:parameterexpression-numeric

Conversation

@jakelishman
Copy link
Copy Markdown
Member

Summary

This is largely a wrap-up of the if ParameterExpression.is_real(): ... logic present in a few places across the library, but a bit more efficient for Symengine because it can re-use cases where it needed to force an evaluation to produce accurate results. Mostly, though, it simplifies a few call sites.

Details and comments

Depends on #11107, because .evalf(real=True) is a symengine-specific extension, and when TemplateOptimization produces mismatched ParameterExpressions it breaks this handling.

The additional handling in numeric to reduce the impact of the spurious imaginary components makes this generally more reliable. I came across problems with global phases during binding in a PR built on top of this - at the moment, the type of the global_phase in QuantumCircuit.assign_parameters isn't validated in the same way, but in a unification PR I had it was, and some deeply nested (but completely valid) assignments were failing.

@jakelishman jakelishman added Changelog: Added Add an "Added" entry in the GitHub Release changelog. mod: circuit Related to the core of the `QuantumCircuit` class or the circuit library labels Oct 25, 2023
@jakelishman jakelishman added this to the 1.0.0pre1 milestone Oct 25, 2023
@jakelishman jakelishman requested a review from a team as a code owner October 25, 2023 11:38
@qiskit-bot
Copy link
Copy Markdown
Collaborator

One or more of the the following people are requested to review this:

  • @Qiskit/terra-core

This is largely a wrap-up of the `if ParameterExpression.is_real(): ...`
logic present in a few places across the library, but a bit more
efficient for Symengine because it can re-use cases where it needed to
force an evaluation to produce accurate results.  Mostly, though, it
simplifies a few call sites.
@jakelishman jakelishman force-pushed the parameterexpression-numeric branch from b3b0a4d to 1c023bd Compare December 18, 2023 16:36
@jakelishman
Copy link
Copy Markdown
Member Author

Now rebased over #11107 and other changes to main (notably #10902) that have merged since this was created. Ready for review / merge.

@coveralls
Copy link
Copy Markdown

coveralls commented Dec 18, 2023

Pull Request Test Coverage Report for Build 7259881506

Warning: This coverage report may be inaccurate.

We've detected an issue with your CI configuration that might affect the accuracy of this pull request's coverage report.
To ensure accuracy in future PRs, please see these guidelines.
A quick fix for this PR: rebase it; your next report should be accurate.

  • 17 of 19 (89.47%) changed or added relevant lines in 3 files are covered.
  • 27 unchanged lines in 3 files lost coverage.
  • Overall coverage increased (+0.02%) to 87.547%

Changes Missing Coverage Covered Lines Changed/Added Lines %
qiskit/circuit/quantumcircuit.py 3 4 75.0%
qiskit/transpiler/passes/basis/basis_translator.py 3 4 75.0%
Files with Coverage Reduction New Missed Lines %
crates/qasm2/src/lex.rs 5 91.67%
crates/qasm2/src/parse.rs 6 97.6%
qiskit/providers/basicaer/unitary_simulator.py 16 80.54%
Totals Coverage Status
Change from base Build 7250858362: 0.02%
Covered Lines: 59173
Relevant Lines: 67590

💛 - Coveralls

Copy link
Copy Markdown
Member

@1ucian0 1ucian0 left a comment

Choose a reason for hiding this comment

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

Looks good to me! Just some comments here and there.

self.assertIsInstance(one_imaginary.numeric(), complex)
self.assertEqual(one_imaginary.numeric(), 1j)

# This is one particular case where symengine 0.9.2 (and probably others) struggles when
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This corner case can be removed with #11315 ?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

I'd leave it in regardless - it still works as a regression test for us.

# Symengine returns `complex` if any imaginary floating-point enters at all, even if
# the result is zero. The best we can do is detect that and decay to a float.
out = complex(self._symbol_expr)
return out.real if out.imag == 0.0 else out
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

should this be a math.isclose? Zero-checking floats is always hard to me...

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Personally I'd say no - the only times we've seen uses where bad imaginary components enter is from bugs within Symengine itself (which this function works around), where the coefficient scales with the operation being done, so could be arbitrarily large. Auto clipping to zero also makes it tricky for people who were expecting to deal with very small numbers (which floating point is good at).

As an interface thing, a user can always clip the output themselves if needed, so I think not clipping is the safer choice.

Comment thread qiskit/circuit/parameterexpression.py Outdated
Comment thread qiskit/transpiler/passes/basis/basis_translator.py Outdated
Comment thread qiskit/circuit/quantumcircuit.py Outdated
Comment thread qiskit/circuit/parameterexpression.py Outdated
Co-authored-by: Elena Peña Tapia <57907331+ElePT@users.noreply.github.com>
Co-authored-by: Luciano Bello <bel@zurich.ibm.com>
@jakelishman jakelishman requested review from 1ucian0 and ElePT December 19, 2023 12:46
Copy link
Copy Markdown
Contributor

@ElePT ElePT left a comment

Choose a reason for hiding this comment

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

LGTM (I'll add it to the queue in the interest of unblocking #11428)

@ElePT ElePT added this pull request to the merge queue Dec 19, 2023
Merged via the queue into Qiskit:main with commit 43c6713 Dec 19, 2023
@jakelishman jakelishman deleted the parameterexpression-numeric branch December 19, 2023 21:37
1ucian0 added a commit that referenced this pull request May 31, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Changelog: Added Add an "Added" entry in the GitHub Release changelog. mod: circuit Related to the core of the `QuantumCircuit` class or the circuit library

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants