-
Notifications
You must be signed in to change notification settings - Fork 65
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
Evaluate Relationals when casting to bool #354
Open
qthequartermasterman
wants to merge
9
commits into
symengine:master
Choose a base branch
from
qthequartermasterman:relational_bool
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
9 commits
Select commit
Hold shift + click to select a range
a96e507
Override __bool__ in Relational, so that it returns whatever the bool…
qthequartermasterman 290f916
Update test_eval.py
qthequartermasterman 8709957
Improved speed of boolean evaluation.
qthequartermasterman 4090967
Added tests for Equality
qthequartermasterman f81c74a
Added Tests for Unequality, Less than, and Greater Than.
qthequartermasterman afa4925
Fixed boolean evaluation for Less Than and Greater Than.
qthequartermasterman feaeca0
Include workaround for environments without sympy.
qthequartermasterman 1d4d0e9
Fix tests so that they will accept a ValueError for hard relational e…
qthequartermasterman cf784eb
Eliminated all approximations in Relational boolean evaluation. Raise…
qthequartermasterman File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,138 @@ | ||
from symengine.utilities import raises | ||
from symengine import (Symbol, sympify, Eq, Ne, Lt, Le, Ge, Gt, sqrt, pi) | ||
|
||
from unittest.case import SkipTest | ||
|
||
try: | ||
import sympy | ||
HAVE_SYMPY = True | ||
except ImportError: | ||
HAVE_SYMPY = False | ||
|
||
|
||
def assert_equal(x, y): | ||
"""Asserts that x and y are equal. This will test Equality, Unequality, LE, and GE classes.""" | ||
assert bool(Eq(x, y)) | ||
assert not bool(Ne(x, y)) | ||
assert bool(Ge(x, y)) | ||
assert bool(Le(x, y)) | ||
|
||
|
||
def assert_not_equal(x, y): | ||
"""Asserts that x and y are not equal. This will test Equality and Unequality""" | ||
assert not bool(Eq(x, y)) | ||
assert bool(Ne(x, y)) | ||
|
||
|
||
def assert_less_than(x, y): | ||
"""Asserts that x is less than y. This will test Le, Lt, Ge, Gt classes.""" | ||
assert bool(Le(x, y)) | ||
assert bool(Lt(x, y)) | ||
assert not bool(Ge(x, y)) | ||
assert not bool(Gt(x, y)) | ||
|
||
|
||
def assert_greater_than(x, y): | ||
"""Asserts that x is greater than y. This will test Le, Lt, Ge, Gt classes.""" | ||
assert not bool(Le(x, y)) | ||
assert not bool(Lt(x, y)) | ||
assert bool(Ge(x, y)) | ||
assert bool(Gt(x, y)) | ||
|
||
|
||
def test_equals_constants_easy(): | ||
assert_equal(3, 3) | ||
assert_equal(4, 2 ** 2) | ||
|
||
|
||
def test_equals_constants_hard(): | ||
# Short and long are symbolically equivalent, but sufficiently different in form that expand() does not | ||
# catch it. Ideally, our equality should still catch these, but until symengine supports as robust simplification as | ||
# sympy, we can forgive failing, as long as it raises a ValueError | ||
short = sympify('(3/2)*sqrt(11 + sqrt(21))') | ||
long = sympify('sqrt((33/8 + (1/24)*sqrt(27)*sqrt(63))**2 + ((3/8)*sqrt(27) + (-1/8)*sqrt(63))**2)') | ||
assert_equal(short, short) | ||
assert_equal(long, long) | ||
if HAVE_SYMPY: | ||
assert_equal(short, long) | ||
else: | ||
raises(ValueError, lambda: bool(Eq(short, long))) | ||
|
||
|
||
def test_not_equals_constants(): | ||
assert_not_equal(3, 4) | ||
assert_not_equal(4, 4 - .000000001) | ||
|
||
|
||
def test_equals_symbols(): | ||
x = Symbol("x") | ||
y = Symbol("y") | ||
assert_equal(x, x) | ||
assert_equal(x ** 2, x * x) | ||
assert_equal(x * y, y * x) | ||
|
||
|
||
def test_not_equals_symbols(): | ||
x = Symbol("x") | ||
y = Symbol("y") | ||
assert_not_equal(x, x + 1) | ||
assert_not_equal(x ** 2, x ** 2 + 1) | ||
assert_not_equal(x * y, y * x + 1) | ||
|
||
|
||
def test_not_equals_symbols_raise_typeerror(): | ||
x = Symbol("x") | ||
y = Symbol("y") | ||
raises(TypeError, lambda: bool(Eq(x, 1))) | ||
raises(TypeError, lambda: bool(Eq(x, y))) | ||
raises(TypeError, lambda: bool(Eq(x ** 2, x))) | ||
|
||
|
||
def test_less_than_constants_easy(): | ||
assert_less_than(1, 2) | ||
assert_less_than(-1, 1) | ||
|
||
|
||
def test_less_than_constants_hard(): | ||
# Each of the below pairs are distinct numbers, with the one on the left less than the one on the right. | ||
# Ideally, Less-than will catch this when evaluated, but until symengine has a more robust simplification, | ||
# we can forgive a failure to evaluate as long as it raises a ValueError. | ||
if HAVE_SYMPY: | ||
assert_less_than(sqrt(2), 2) | ||
assert_less_than(3.14, pi) | ||
else: | ||
raises(ValueError, lambda: bool(Lt(sqrt(2), 2))) | ||
raises(ValueError, lambda: bool(Lt(3.14, pi))) | ||
|
||
|
||
def test_greater_than_constants(): | ||
assert_greater_than(2, 1) | ||
assert_greater_than(1, -1) | ||
|
||
|
||
def test_greater_than_constants_hard(): | ||
# Each of the below pairs are distinct numbers, with the one on the left less than the one on the right. | ||
# Ideally, Greater-than will catch this when evaluated, but until symengine has a more robust simplification, | ||
# we can forgive a failure to evaluate as long as it raises a ValueError. | ||
if HAVE_SYMPY: | ||
assert_greater_than(2, sqrt(2)) | ||
assert_greater_than(pi, 3.14) | ||
else: | ||
raises(ValueError, lambda: bool(Gt(2, sqrt(2)))) | ||
raises(ValueError, lambda: bool(Gt(pi, 3.14))) | ||
|
||
|
||
def test_less_than_raises_typeerror(): | ||
x = Symbol("x") | ||
y = Symbol("y") | ||
raises(TypeError, lambda: bool(Lt(x, 1))) | ||
raises(TypeError, lambda: bool(Lt(x, y))) | ||
raises(TypeError, lambda: bool(Lt(x ** 2, x))) | ||
|
||
|
||
def test_greater_than_raises_typeerror(): | ||
x = Symbol("x") | ||
y = Symbol("y") | ||
raises(TypeError, lambda: bool(Gt(x, 1))) | ||
raises(TypeError, lambda: bool(Gt(x, y))) | ||
raises(TypeError, lambda: bool(Gt(x ** 2, x))) |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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.
This will return
True
for2*(x + 1) - 2
which is different from what we get for2*x
which is a TypeError.