# Rewriting algebraic expressions as combinations of other expressions

I would like to write x^5 + 1/x^5 in terms of x^2 + 1/x^2, x^3 + 1/x^3 and x + 1/x or express x^6 + 1/x^6 in terms of x^2 + 1/x^2 and x^4 + 1/x^4 etc.

How can I do that in Mathematica?

There is a special approach with Solve eliminating appropriate variables, e.g. in the following x should be eliminated

a/. Solve[{x^5 + 1/x^5 == a, x^3 + 1/x^3 == b, x^2 + 1/x^2 == c, x + 1/x == d},
{a, b, d}, {x}]

{-Sqrt[2 + 5 c - 5 c^3 + c^5], Sqrt[2 + 5 c - 5 c^3 + c^5]}


or e.g.

Solve[{ x^5 + 1/x^5 == a, x^3 + 1/x^3 == b, x^2 + 1/x^2 == c, x + 1/x == d},
{a, b, c}, {x}]

{{a -> d (5 - 5 d^2 + d^4), b -> d (-3 + d^2), c -> -2 + d^2}}


The above demonstrates that there is no unique method providing the best solution unless we define precisely what the best approach means. We can express a in terms of c only as well as in terms of d only. Nevertheless one can easily observe that

a == b c - d /.First @ Solve[{x^5 + 1/x^5 == a, x^3 + 1/x^3 == b,
x^2 + 1/x^2 == c, x + 1/x == d},
{a, b, c}, {x}] // Simplify

True


as well as e.g.

a == d (c^2 - c - 1)/.First @ Solve[{x^5 + 1/x^5 == a, x^3 + 1/x^3 == b,
x^2 + 1/x^2 == c, x + 1/x == d},
{a, b, c}, {x}] // Simplify

True


Another way is a standard approach with Eliminate, e.g.

Eliminate[{x^6 + 1/x^6 == e, x^4 + 1/x^4 == f, x^2 + 1/x^2 == c},
{x, f}]

e == -3 c + c^3


and it appears that with Solve we can produce another representation of e:

e == f c - c /.First @ Solve[{ x^6 + 1/x^6 == e, x^4 + 1/x^4 == f,
x^2 + 1/x^2 == c}, {e, f}, {x} // Simplify

True


These methods work quite satisfactory when the list of equations is rather short and we expect one can improve solutions if we appropriately restrict the solution space.

@Artes lready showed how one might use Solve or Eliminate for this task. Since it involves algebraic rewriting of a rational expression, a standard method from computational algebra involves Groebner bases. Technical-sounding, yes, but also quite powerful.

The idea is to write the inputs as polynomials. I use y as the reciprocal of x and add a polynomial relation x*y-1 to enforce this. I equate each target polynomial to a new "marker" (or "tag") variable. The code for this is written in a way that is intended to be readily automated, that is, to systems with more relations, different variables, etc.

basepolys = {x^3 + y^3, x^2 + y^2, x + y};
avars = Array[a, Length[basepolys]];
allpolys = Join[avars - basepolys, {x*y - 1}];
allvars = Join[Variables[basepolys], avars];


Next compute a Groebner basis using a term order that places the original variables "larger" than the marker variables. This will make rewrites favor the marker variables over the polynomial variables.

gb = GroebnerBasis[polys, allvars];


Now we can rewrite that input x^5+1/x^5 like so:

PolynomialReduce[x^5 + y^5, gb, allvars][]

(* Out= 5 a - 5 a^3 + a^5 *)


I left out a couple of niceties. One can programatically (as in, exercise for the reader) replace negative powers of x, for example. Or replace the result with explicit uses of the original expressions x^3+1/x^3,...`.