Solving polynomial equations with Groebner basis in $\mathbb{R}$

I am trying to solve the following system of polynomial equations: $$x^2+y^2+z^2=4\ x^2+2y^2=5\ xz=1$$

I used the following command to get a Groebner basis

P.<x,y,z> = PolynomialRing(QQ,order='lex')
PList = [x^2+y^2+z^2-4, x^2+2*y^2-5, x*z-1]
I = ideal(PList)
B = I.groebner_basis(); B
[x + 2*z^3 - 3*z, y^2 - z^2 - 1, z^4 - 3/2*z^2 + 1/2]


Now I want to use B.subs() to plug the solutions for $z$ to solve for $x,y$. It worked well for $z=\pm 1$.

B.subs(z=1)
[x - 1, y^2 - 2, 0]


but not for the $1/\sqrt{2}$ since this is in polynomial ring $\mathbb{Q}[x,y,z]$. If I change the original QQ to RR, the numbers become all decimals.

B.subs(z=1/sqrt(2))
[x - 1.41421356237310, y^2 - 1.50000000000000, 0]


How can I still get exact solutions when using RR? I know I can compute this example by hands, but I'd like to know how to use Sage to solve this kind of problems.

Thank you for any help!

edit retag close merge delete

Sort by » oldest newest most voted

You can change the ring over which your polynomial ring is defined, to be the field of algebraic numbers (note the QQbar instead of QQ in the first line):

sage: P.<x,y,z> = PolynomialRing(QQbar, order='lex')
sage: PList = [x^2+y^2+z^2-4, x^2+2*y^2-5, x*z-1]
sage: I = ideal(PList)
sage: B = I.groebner_basis(); B
verbose 0 (3369: multi_polynomial_ideal.py, groebner_basis) Warning: falling back to very slow toy implementation.
[x + 2*z^3 + (-3)*z, y^2 - z^2 - 1, z^4 + (-3/2)*z^2 + 1/2]


Then:

sage: B.subs(z=1)
[x - 1, y^2 - 2, 0]

sage: B.subs(z=1/sqrt(2))
[x - 1.414213562373095?, y^2 - 3/2, 0]

more

Thank you for your reply! That looks much better! Is there a way to get $\sqrt{2}$ instead of $x-1.414....$? Sorry I don't have enough points to upvote.

( 2016-05-11 10:48:19 -0500 )edit

Note that 1.414213562373095? is only a screen representation, but it is a genuine algebraic number, not a floating-point approximation. You can see this because of the question mark at the end of the number. You can check it as follows:

sage: c = B.subs(z=1/sqrt(2))[0].constant_coefficient()
sage: c
-1.414213562373095?
sage: c.parent()
Algebraic Field
sage: c^2 == 2
True
sage: c.minpoly()
x^2 - 2


Not every algebraic number has a representation with radicals such as "sqrt(2)", but for the algebraic numbers that do, there are plans to implement such a representation, but it is not done yet.

( 2016-05-11 11:29:51 -0500 )edit

Thank you! That is very helpful!

( 2016-05-11 13:39:08 -0500 )edit

You should not use RR which stands for floating point approximations of real numbers.

The simples to get exact solutions is to use QQbar (= algebraic closure of QQ)

sage: sqrt2 = QQbar(2) ^ (1/2)
sage: sqrt2
1.414213562373095?
sage: sqrt2.n(100)
sage: sqrt2.minpoly()
x^2 - 2


But mixing it with groebner bases I got

sage: B.subs(z=QQbar(2).sqrt())
Traceback (most recent call last):
...
ValueError: Cannot coerce irrational Algebraic Real 1.414213562373095? to Rational

more

Thank you for your reply! I can actually use $z=QQbar(2)^{1/2}$. But I wish they would give the answer $\sqrt{2}$.

( 2016-05-11 10:50:21 -0500 )edit