-
-
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
make all_close more robust #26708
make all_close more robust #26708
Conversation
Instead of doing an O(n^2) search for a matching term, an optimization is made to handle the exact matching terms using coefficients_dict and then a fallback to searching is made for any more complicated terms.
✅ Hi, I am the SymPy bot. I'm here to help you write a release notes entry. Please read the guide on how to write release notes.
Click here to see the pull request description that was parsed.
|
Benchmark results from GitHub Actions Lower numbers are good, higher numbers are bad. A ratio less than 1 Significantly changed benchmark results (PR vs master) Significantly changed benchmark results (master vs previous release) Full benchmark results can be found as artifacts in GitHub Actions |
Why are from sympy import *
from sympy.core.numbers import all_close
eps = 0.00000001
x = Symbol('x')
print(all_close(1*x, (1 + eps)*x))
print(all_close(0*x, (0 + eps)*x)) I don't exactly know if this is intended by the design, Even between If the difference between |
They are different because they have different structure, one is a Mul and the other a constant, one depends on x and the other does not. The purpose of the function is to test whether coefficients of like terms is small according to the rtol and atol parameters. |
There are two parts to the numerical test: The only exception I am trying to provide in this PR is to recognize the multiplicative and additive identities. The multiplicative is dropped when it is Rational instead of Float (so
|
>>> all_close(x, x + 1e-10) | ||
True | ||
>>> all_close(x, 1.0*x) | ||
True | ||
>>> all_close(x, 1.0*x + 1e-10) | ||
True |
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 is definitely not what I wanted when creating this function or whenever I have used it. Its purpose was to be used in tests where these sorts of differences should generally show up as test failures.
That now means that I want a different function for use in tests because this one does not do what is actually needed there any more.
Brief description of what is fixed or changed
all_close
is more efficient in testing whether two expressions differ trivially in terms of literal numbers (not symbolic values).Other comments
all_close
is not a publically imported routine, but it is not underscore-named innumbers
. It attempts to free the user from tedious analysis of two expressions to see if they are the same when, in fact, they might only differ trivially in numerical values used. It is currently only used in tests.One thing that would make it fail in master is the inability to recognize that
x
and1.0*x
are trivially the same since they do not have the expected identical structure; one is a Symbol and the other a Mul.It is also recognized in master that searching for matching terms between two Add is very inefficient since a search for a given term is made factor by factor:
Here are a few simple tests:
It might make more sense to have this somewhere other than in the
core.numbers
since it really has more to do with testing (and testing expressions) than it does with testing numbers.Release Notes
NO ENTRY