-
-
Notifications
You must be signed in to change notification settings - Fork 4.3k
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
Minor Interval fixes #18426
Minor Interval fixes #18426
Conversation
Sympy `Interval`s are purely real and hence `._contains()` rejects e.g. S.Infinity. This commit fixes the following two results that were not quite consistent with this definition: In [1]: c = Symbol('c', real=False) In [2]: Interval(m, m + 1).contains(c) Out[2]: c ≥ m ∧ c ≤ m + 1 # should be False In [3]: e = Symbol('e', extended_real=True) In [4]: Interval(-oo, oo).contains(e) Out[4]: True # is in fact unknown!
✅ Hi, I am the SymPy bot (v149). I'm here to help you write a release notes entry. Please read the guide on how to write release notes. Your release notes are in good order. Here is what the release notes will look like:
This will be added to https://github.com/sympy/sympy/wiki/Release-Notes-for-1.6. Note: This comment will be updated with the latest check if you edit the pull request. You need to reload the page to see it. Click here to see the pull request description that was parsed.
Update The release notes on the wiki have been updated. |
@@ -917,7 +917,8 @@ def __new__(cls, start, end, left_open=False, right_open=False): | |||
|
|||
inftys = [S.Infinity, S.NegativeInfinity] | |||
# Only allow real intervals (use symbols with 'is_extended_real=True'). | |||
if not all(i.is_extended_real is not False or i in inftys for i in (start, end)): | |||
if not all(i.is_extended_real is not False or i in inftys | |||
for i in (start, end, end - start)): | |||
raise ValueError("Non-real intervals are not supported") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Which cases benefit from checking end - start
?
Could use fuzzy_and/or/not
here (and in other places).
if fuzzy_not(fuzzy_and(i.is_extended_real for s in (start, end, end-start))):
Tri-valued logic is confusing so I like to keep it as close as possible to normal logic:
if not all(is_real(i) for i in (start, end, end-start)):
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok, changed.
sympy/sets/sets.py
Outdated
other is S.ComplexInfinity) or other.is_extended_real is False: | ||
other is S.ComplexInfinity or | ||
other.is_extended_real is False or | ||
other.is_real is False): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It should not be necessary to check is_real
and is_extended_real
. The assumptions system computes implications like is_real -> is_extended_real
and the contrapositive ! is_extended_real -> ! is_real
so these are consistent across all of Expr
(actually all of Basic
...).
The infinities would all be covered by the is_real is False
check as well.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The assumptions system computes implications like
is_real -> is_extended_real
Thanks for the reminder; changed. (I suppose the explicit checks for the infinities were intended as a kind of micro-optimization, but I guess the assumption system does its best, e.g. caching, to make these quick exits not really worthwhile.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Classes like Infinity
have things like is_real = False
as class attributes. The ManagedProperties
metaclass computes all of the implications of this at class definition time so that is_real
becomes a property that returns False
. That means that looking up is_real
there is probably as efficient as looking up an attribute on S
especially if you look up multiple attributes on S
.
We should shun using is
checks for speed reasons and write code that is simple and clean until an actual profile/benchmark makes the benefit measurable.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should shun using
is
checks for speed reasons and write code that is simple and clean until an actual profile/benchmark makes the benefit measurable
Agreed. (And thanks for the assumptions internals.)
On a side-note: I was a bit astonished that S.NaN.is_real
evaluates to None
. I'd have expected False
. (I think I can see where it's coming from, but expressions that are yielding NaN are almost by definition neither real nor complex. They may have a limit, but that requires the presence of variables and such.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think of nan as often representing a failed computation. Possibly calculating in a different way would have given a sensible result but we can't be sure. That means we should not really say anything definitive that it is or is not real etc.
if not other.is_extended_real is None: | ||
return other.is_extended_real | ||
if not other.is_real is None: | ||
return other.is_real |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
x is not None
is better than not x is None
as there is no ambiguity in the precedence
Codecov Report
@@ Coverage Diff @@
## master #18426 +/- ##
==============================================
- Coverage 75.317% 64.317% -11.001%
==============================================
Files 637 637
Lines 167069 167070 +1
Branches 39417 39417
==============================================
- Hits 125833 107455 -18378
- Misses 35702 53521 +17819
- Partials 5534 6094 +560 |
Looks good. Thanks |
References to other Issues or PRs
none
Brief description of what is fixed or changed
Sympy
Interval
s are purely real and hence._contains()
rejects e.g.S.Infinity
. This commit fixes the following two results that were not quite consistent with this definition:The second commit makes
Interval
reject some obvious non-real intervals.Other comments
Release Notes
Interval.contains()