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 abs function to parameterexpression #7497

Closed
wants to merge 12 commits into from

Conversation

czachow
Copy link
Contributor

@czachow czachow commented Jan 7, 2022

Summary

  • added an abs function to the class ParameterExpression

Details and comments

@czachow czachow requested a review from a team as a code owner January 7, 2022 10:37
@coveralls
Copy link

coveralls commented Jan 7, 2022

Pull Request Test Coverage Report for Build 1722151454

  • 3 of 5 (60.0%) changed or added relevant lines in 1 file are covered.
  • 157 unchanged lines in 8 files lost coverage.
  • Overall coverage decreased (-0.0002%) to 83.141%

Changes Missing Coverage Covered Lines Changed/Added Lines %
qiskit/circuit/parameterexpression.py 3 5 60.0%
Files with Coverage Reduction New Missed Lines %
qiskit/assembler/run_config.py 1 95.45%
qiskit/utils/run_circuits.py 1 30.79%
qiskit/test/base.py 5 83.17%
qiskit/compiler/assembler.py 6 96.2%
qiskit/execute_function.py 6 90.63%
qiskit/qobj/qasm_qobj.py 20 83.01%
qiskit/qobj/pulse_qobj.py 39 76.79%
qiskit/utils/quantum_instance.py 79 69.49%
Totals Coverage Status
Change from base Build 1714460551: -0.0002%
Covered Lines: 51997
Relevant Lines: 62541

💛 - Coveralls

qiskit/circuit/parameterexpression.py Outdated Show resolved Hide resolved
else:
return self._symbol_expr.__lt__(other._symbol_expr)
elif isinstance(other, numbers.Number):
return len(self.parameters) == 0 and float(self._symbol_expr) < other
Copy link
Contributor

Choose a reason for hiding this comment

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

If len(self.parameters) !=0 this returns False, but it should raise an exception.

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 think the __eq__ method should also have this behaviour. What do you think?

test/python/circuit/test_parameters.py Show resolved Hide resolved
qiskit/circuit/parameterexpression.py Outdated Show resolved Hide resolved
Copy link
Member

@jakelishman jakelishman left a comment

Choose a reason for hiding this comment

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

Thanks for looking at this! The addition of abs looks fine to me, though it needs a release note to go with it.

I'm not sure it's a good idea to add the comparison operators, though. The class is called ParameterExpression, but in general between two instances of it, the comparison is unknowable. Storing the result of < or so turns it into a "relation" not an "expression". For example, see one of the comments below about how sympy doesn't usually return Booleans in comparisons. At the very least, I think adding the comparison operators should be a separate PR, but honestly, I think it would be better to leave them undefined; I don't see any use-cases for them working only very occasionally.

Comment on lines 523 to 529
if len(self.parameters) == 0:
return float(self._symbol_expr) < other
else:
raise TypeError(
"'<' not supported between instances of {type(self)} "
"with unbound parameters {self.parameters} and {type(other)}."
)
Copy link
Member

Choose a reason for hiding this comment

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

I feel like there will be situations where an expression might not have a single numerical value, but can be bound for certain comparisons. For example, abs(x) >= 0 is knowable.

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 moved the implementation to #7539, please have a look there.

qiskit/circuit/parameterexpression.py Outdated Show resolved Hide resolved
qiskit/circuit/parameterexpression.py Outdated Show resolved Hide resolved
def test_raise_if_compare_not_supported(self):
"""Verify raises if compare to object."""
x = Parameter("x")
y = object
Copy link
Member

Choose a reason for hiding this comment

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

You probably meant to instantiate an object here (y = object()), rather than use the type object. It'll work the same, but the way it's written is slightly confusing.

Comment on lines 1192 to 1193
with self.assertRaisesRegex(TypeError, "not supported"):
x.__lt__(y)
Copy link
Member

Choose a reason for hiding this comment

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

It'd be clearer to write x < y if that's what you mean; it's good to test the exact paths you expect to be used.

Comment on lines 1183 to 1185
self.assertTrue(bound_expr < 3.0)
self.assertTrue(bound_expr > 1.0)
self.assertEqual(abs(bound_expr), 2.3)
Copy link
Member

Choose a reason for hiding this comment

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

If we keep the comparison operators __le__ and __ge__, we'd need to those here too.

Comment on lines 519 to 521
return sympify(self._symbol_expr).__lt__(sympify(other._symbol_expr))
else:
return self._symbol_expr.__lt__(other._symbol_expr)
Copy link
Member

Choose a reason for hiding this comment

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

These don't do what you think they do; they don't always return Boolean values. Also, in general it's better to use the Python operations, and let Python handle the numerics; this way can fail if the left-hand side doesn't evaluate __lt__, but the right hand does evaluate __gt__, whereas if you'd used < in that situation, Python would evaluate it correctly.

For not returning a Boolean, see:

In [1]: import sympy
   ...: x = sympy.Symbol("x")
   ...: x + 1 > x
Out[1]: x + 1 > x

Copy link
Member

@jakelishman jakelishman 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 better as the simpler PR - it will be safe to add this functionality without issue. Please could you add some more rigorous tests, and also add a release note (see the contributing guide).

self.assertEqual(bound_expr, 2.3)
self.assertEqual(abs(bound_expr), 2.3)
Copy link
Member

Choose a reason for hiding this comment

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

I think it would be best to separate out the tests of abs into their own function; they're not really related to this.

Also, I think we could do with more stringent tests of it; at the moment, if abs is implemented incorrectly this test can still fail. We need to actually test the mathematical properties of abs, for example that it makes negative numbers positive, and complex numbers positive-real. We should also test that it works for symbolic expressions, such as abs(< -x >).

Copy link
Contributor Author

@czachow czachow Jan 19, 2022

Choose a reason for hiding this comment

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

As suggested, I added more tests to the implementation. What do you mean by testing symbolic expressions, such as abs(< -x >)?

@HuangJunye HuangJunye added the Community PR PRs from contributors that are not 'members' of the Qiskit repo label Jun 21, 2022
@king-p3nguin
Copy link
Contributor

Dear @czachow ,
I want to use the method you created for ParameterExpression. Since your comment on Jan 20th, have you updated the program? If not, I would like to continue your work and make a new pull request.

@czachow
Copy link
Contributor Author

czachow commented Dec 20, 2022

Dear @king-p3nguin, thanks for working on this old PR that would have been forgotten otherwise. In my memory most of the implementation is done. You only need to add more tests like @jakelishman suggested. Feel free to do so!

@king-p3nguin
Copy link
Contributor

Thank you very much!

@Cryoris
Copy link
Contributor

Cryoris commented Dec 21, 2022

Closing this as duplicate of #9309.

@Cryoris Cryoris closed this Dec 21, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Community PR PRs from contributors that are not 'members' of the Qiskit repo
Projects
Status: Done
Development

Successfully merging this pull request may close these issues.

Add support for abs to ParameterExpression
7 participants