# Eliminating variables from a system of equations?

I'm (very) new to Sage, but am confused about why I can't get it to solve a simple system like this:

var('x, y, z')
eqns = [ x^2 + y^2 == z, x == y]

but solve(eqns, z) gives an empty list back instead of my desired z = 2y^2

edit retag close merge delete

Sort by » oldest newest most voted

Also:

sage: var('x, y, z')
(x, y, z)
sage: maxima.eliminate([x^2 + y^2 == z, x == y],[x])
[2*y^2-z]
more

Hmm, should we wrap this? How robust is it?

( 2012-11-29 03:42:43 -0500 )edit

@kcrisman: Having someting like [Mathematica's Eliminate](http://reference.wolfram.com/mathematica/ref/Eliminate.html) would be great. I find that using the above code, turning this maxima result back into a sage expression is at least not obvious. A wrapper might take care of that. An alternative would be providing a variable elimination only for polynomials, which should be a lot more reliable I guess. the above approach applied to elements of a polynomial ring gave a bogus answer the one time I tried it.

( 2013-07-08 00:40:11 -0500 )edit

Yes, you'd have to use the symbolic ring, I suppose - not sure about poly rings. O course, there are presumably more sophisticated algorithms in the algebraic geometry part of Sage, but they may not apply in general.

( 2013-07-08 03:33:56 -0500 )edit

When you do solve(eqns,z), Sage is trying to find z that satisfies both equations and finds that there is no such z. However, if you use solve(eqns,[x,z]), it can find a solution and gives the one you want.

solve(eqns,[x,z])

gives

[[x == y, z == 2*y^2]]

For the simple elimination you suggest in your question, you could just do a substitution.

eq=x^2+y^2==z
eq.subs(x=y)

gives

z==2*y^2
more

My actual system of equations was a bit more complicated, but this seems to reproduce my issue. I guess I see what you're getting at. If I have m equations containing m+n free variables, then I need to "solve()" for at least m variables and, for each solution set, each variable will appear once on the left hand side, expressed in terms of the remaining n variables on the right hand side? So if I want to eliminate k variables from my system of m equations (in m+n unknowns), I should just "solve" for those k along with an arbitrary k-m other variables, and if I get a unique solution then I can replace my original system with the k-m equations corresponding to the non-eliminated variables?? Is there a way to ask Sage what variables are mentioned in an equation?

( 2012-12-06 08:24:27 -0500 )edit

If your equation is named eqns, you can get the variables in it using eqns.variables().

( 2012-12-06 16:11:49 -0500 )edit

If eqns is a list of equations, you'll need to use eqns[i].variables() to get the variables in the ith equation.

( 2012-12-06 16:14:03 -0500 )edit

The best approach I've found so far is to define an eliminate(vars, eqns) procedure (see below) which attempts to remove all the listed vars from the system, so that:

var('x, y, z')
eqns = [ x^2 + y^2 == z, x == y]
view(eliminate([x], eqns))

gives [2y^2 == z] and solve(eliminate([x], eqns), z) gives me what I was after originally. But I figure I must be missing something obvious.

def eliminate(vars, eqns):
"""Eliminate the listed variables from the system of equations"""
if type(vars) is not list: vars = [vars]
if type(eqns) is not list: eqns = [eqns]

# for each variable to be eliminated,
# look for an equation that contains it
# and that we can solve uniquely for it
for var in vars:
soln = None
for eqn in eqns:
if var in eqn.args():
soln = solve(eqn,var)
if len(soln) == 1: break

# if we found an equation determining the variable to be eliminated
# substitute its value throughout, and omit the defining equation
if soln:
val = soln[0].rhs()
eqns = [e.subs({var : val}) for e in eqns if e is not eqn]

# give back whatever we ended up with
return eqns
more

You can use the resultant to eliminate a single variable from a system of two polynomials. Unfortunately it seems that these polynomials can't use coefficients from the symbolic ring, so your equations will have to be polynomials over some number field like QQ.

sage: var('x, y, z')
sage: eqns = [ x^2 + y^2 == z, x == y]
sage: vars = union(flatten([e.variables() for e in eqns]))
sage: R = PolynomialRing(QQ, vars)
sage: p1, p2 = [R(e.rhs() - e.lhs()) for e in eqns]
sage: SR(p1.resultant(p2, R(z))) == 0
-x + y == 0
sage: SR(p1.resultant(p2, R(x))) == 0
-2*y^2 + z == 0

The first two lines are the input as you provided it. The third line collects all the variables occuring in your equations. We use them to construct a multivariate polynomial ring over the rational numbers. We then turn your expressions into polynomials in this ring: each polynomial will be zero iff the corresponding equation holds.

Then we compute the resultant of the two polynomials, with respect to the variable you want to eliminate (z in your question, but x in some other answers). The resultant will be zero exactly if the two polynomials have a common zero. Which in this case means that there is a value for z resp. x which satisfies both equations. So the condition of this polynomial being zero corresponds to the two original equations with that one variable eliminated.

I'm not sure how to generalize this to more than two equations without explicitely solving one equation for one variable.

more

I tried Eliminate on this system of equations: eqns = [ xy/z == K1, vx/y == K2, ux/v == K3, tw/s == Kb, wx == Kw, x + t == w + y + 2v + 3u, z + y + v +u == A0, s + t == B0] I tried to eliminate the following variables: [s,t,u,v,y,w,z] This should gave me a polynomial of degree 6 in x. There should have been a constant term, but none showed up. All the coefficients agreed with what I had previously determined through paper slog, but the constant term was missing. The constant term should be -K1K2K3Kw^2. What can be happening? Can anyone help? Could there be a problem with the Eliminate function?

more

Posting a question as an answer is unlikely to result in useful information. Please delete this “answer” and post it as a separate question, referencing the original one.

( 2016-11-11 04:35:03 -0500 )edit