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

Incorrect behaviour for solve_poly_system #26682

Open
mohammedehab2002 opened this issue Jun 6, 2024 · 6 comments · May be fixed by #26695
Open

Incorrect behaviour for solve_poly_system #26682

mohammedehab2002 opened this issue Jun 6, 2024 · 6 comments · May be fixed by #26695

Comments

@mohammedehab2002
Copy link

mohammedehab2002 commented Jun 6, 2024

from sympy import symbols,sympify,groebner
from sympy.solvers.polysys import solve_poly_system
s=symbols("s")
c=symbols("c")
eqns=[c**2 + s**2 - 1, -1.98079646822393*c - 0.887785747630113*s - 0.15634896910398]
print(solve_poly_system(eqns,s,c))

This code raises NotImplementedError: only zero-dimensional systems supported (finite number of solutions), but the system is indeed zero-dimensional. Furthermore, if the order of the generators is changed to c,s instead, the code works as expected.

I've been generally running into a lot of trouble with this function claiming the system is not zero-dimensional or returning no solutions when there are solutions for systems generated by intersecting a circle with a random affine line like the one above.

@oscarbenjamin
Copy link
Collaborator

As a workaround you can use solve_poly_system(eqns,s,c,domain=QQ)

@oscarbenjamin
Copy link
Collaborator

Somehow the Groebner basis comes out as

In [14]: groebner(eqns)
Out[14]:
             ⎛⎡                                                     2                                               ⎤                           ⎞
GroebnerBasis⎝⎣2.23116497816229⋅c + 1.0⋅s + 0.176111150152324, 1.0⋅c  + 0.131457559146912⋅c - 0.162089179364897, 1.0⎦, s, c, domain=ℝ, order=lex⎠

In [15]: groebner(eqns)[-1]
Out[15]: 1.00000000000000

That shouldn't happen because if 1 is in the Groebner basis then it should be the whole basis.

skirpichev added a commit to skirpichev/diofant that referenced this issue Jun 10, 2024
@oscarbenjamin
Copy link
Collaborator

The problem is here:

def normal(g, J):
h = g.rem([ f[j] for j in J ])
if not h:
return None

We get a small h that should be zero but is not quite zero because of floating point rounding error:

103  	    def normal(g, J):
104  	        h = g.rem([ f[j] for j in J ])
105  	        breakpoint()
106  	
107  ->	        if not h:
108  	            return None
109  	        else:
110  	            h = h.monic()
111  	
112  	            if h not in I:
(Pdb) p h
-1.11022302462516e-16

@oscarbenjamin
Copy link
Collaborator

Possibly the algorithms used for groebner cannot handle inexact arithmetic and so inexact domains should be converted to exact ones.

@mohammedehab2002
Copy link
Author

Using solve_poly_system(eqns,s,c,domain=QQ) seems slow because of all the rational computations, and I need to solve many of these systems. Any work around for that?

@oscarbenjamin
Copy link
Collaborator

Using solve_poly_system(eqns,s,c,domain=QQ) seems slow because of all the rational computations

The algorithm needs to use exact calculations to work properly. Please open a separate issue about slowness and give an example of a case that is slow.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants