-
-
Notifications
You must be signed in to change notification settings - Fork 4.5k
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
Implemented inequation solver for continous functions with finite number of solutions #2736
Conversation
|
||
for x in solns: | ||
end = x | ||
if rel.subs(sym, (start + end)/2): |
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 2
here doesn't have anything inherently special. The function just needs to check if the relation is satisfied somewhere in the interval (start, end)
.
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.
You have to watch out for +/-oo otherwise you might generate a nan after substitution, e.g. x + abs(x) < 3 has the solution (-oo, 3/2) but the average is -oo and substitution gives a nan. So you have to be smarter about this test, maybe:
if start == -oo and end == oo:
test = 0
elif start == -oo:
test = end - 1
elif end == oo:
test = start + 1
else:
test = (start + end)/2
Btw, solve stumbles on this equation and reduce_inequalities
doesn't like (x + abs(x) < 3, assume=Q.real(x))
so the changes you are making are needed, they should just be incorporated somehow into the solve and perhaps other inequalities solvers.
Also, if the input is True (e..g. var('x', real=True); isolve(x**2+1>0,x)
then (-oo, oo)
should be returned; if the input is False then the empty set should be returned.
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 the way to go is to put isolve into inequalities.py and make sure it return inequalites, not ranges then in _solve_inequality
make it look like this:
...
try:
p = Poly(expr, s)
if p.degree() != 1:
raise NotImplementedError
except (PolynomialError, NotImplementedError):
return isolve(expr, s)
...
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.
...and I would name your solver solve_continuous_inequality
.
While you are editing such files, you might remove references to solve_poly_inequalities
or else write an appropriate function; looks like an author oversight that it's not there.
But what's wrong with the current solve? For example:
See sympy.solvers.inequalities module. |
Maybe all that is needed is a method to turn an inequality into an interval, e.g. |
Or |
I'm a little embarrassed to admit it but I didn't know solve could handle relational inputs. I have went through solvers documentation in past but somehow the fact that it can solve relational input slipped from my mind. I had this idea of solving inequalities and I implemented it right away. Sorry for being reckless. The current solve can handle only polynomial or rational functions with rational coefficients.
My algorithm can handle inequalities with any continuous univariate function that can be handled by
Extending the implementation to discontinuous functions will be easy if we can efficiently extract the points of discontinuities. I guess I work on should improving the current solve for relationals, rather than making a new procedure. |
The current online documentation doesn't have references for |
This functionality exists, it's just hard to find. It would be nice to have a standard inequality->set function somewhere in sets. In [1]: from sympy.solvers.inequalities import reduce_rational_inequalities
In [2]: reduce_rational_inequalities([[x >= 0]], x, relational=False)
Out[2]: [0, ∞) |
Oh, I see now that @smichr suggested a In [7]: Interval(-oo, 0) + FiniteSet(1, 2, 3)
Out[7]: (-∞, 0] ∪ {1, 2, 3}
In [8]: _.as_relational(x)
Out[8]: x = 1 ∨ x = 2 ∨ x = 3 ∨ x ≤ 0 |
There's also the rewrite framework. |
I sent a PR (my isolve branch) to this that incorporates isolve into solve and makes corrections that I recommended above. |
variable name changes and remove comment in test
The travis test SHA1 that passes doesn't match the last-showing SHA1 above and when I pull your branch I get the df9... version. I made the necessary modification and will push from here if the tests pass. |
Thanks for upgrading the solver with this routine. This is in. |
I added |
No description provided.