Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

ordering of multivariate polynomial terms

114 views
Skip to first unread message

Stefan Porubsky

unread,
Mar 15, 2008, 4:12:20 AM3/15/08
to
Hello,

how it is possible to rearrange the terms of a multivariate polynomial
in Standard or Traditional Form in such a way that the terms are ordered
according to the number of their variables, i.e. first the constant
term, then the group of terms depending on one of the variables, then
the group of terms depening on two variables, then the group of those
with three variables, etc.?

Thank

Stefan


Andrzej Kozlowski

unread,
Mar 16, 2008, 5:40:46 AM3/16/08
to
Another way to do this is by using the function
GroebnerBasis`DistributedTermsList, which accepts as an option an
arbitrary monomial order. So, using the DegreeLexicographic monomial
order we get:

First[GroebnerBasis`DistributedTermsList[f, {x, y, z},
MonomialOrder -> DegreeLexicographic]] /.
{(l_)?VectorQ, m_} :> m*Times @@ ({x, y, z}^l)

{x^4, 4*x^3*y, 6*x^2*y^2, 4*x*y^3, y^4, 5*x^3,
9*x^2*y, 15*x*y^2, 3*y^3, 7*x^2, 16*x*y, 10*y^2,
5*x, 4*y, 2}

One can also use this with other monomial orders including user
defined ones.

Andrzej Kozlowski

On 15 Mar 2008, at 23:46, Szabolcs Horv=E1t wrote:

> It is not possible to do this because Plus has the Attribute
> orderless.
> This means that Mathematica will automatically sort the terms of any
> sum using its built-in ordering rules.
>
> Here's a function that returns a list of the terms sorted by degree:
>
> sortPoly[poly_, vars_] := Module[{x, exp},
> exp[term_] := Exponent[term /. Alternatives @@ vars -> x, x];
> Sort[List @@ poly, exp[#1] >= exp[#2] &]
> ]
>
> (The exp[] function returns the degree of a term.)
>
> For example:
>
> f = 2 + 5 x + 7 x^2 + 5 x^3 + x^4 + 4 y + 16 x y + 9 x^2 y + 4 x^3 y =
+
> 10 y^2 + 15 x y^2 + 6 x^2 y^2 + 3 y^3 + 4 x y^3 + y^4
>
> sortPoly[f, {x, y}]
>
> {x^4, 4 x^3 y, 6 x^2 y^2, 4 x y^3, y^4, 5 x^3, 9 x^2 y,
> 15 x y^2, 3 y^3, 7 x^2, 16 x y, 10 y^2, 5 x, 4 y, 2}
>
> Now we can convert the list back to a sum, and use Hold to prevent
> automatic reordering.
>
> Hold@Plus[##] & @@ %
>
> Hold[x^4 + 4 x^3 y + 6 x^2 y^2 + 4 x y^3 + y^4 + 5 x^3 + 9 x^2 y +
> 15 x y^2 + 3 y^3 + 7 x^2 + 16 x y + 10 y^2 + 5 x + 4 y + 2]
>
> ...
>
> I'm not sure if I interpreted your request correctly. Here's and
> alternative "exp" function that returns the number of different
> variables present in a term:
>
> exp[term_] := Count[FreeQ[term, #] & /@ vars, False]
>
> The full sortPoly:
>
> sortPoly[poly_, vars_] := Module[{x, exp},
> exp[term_] := Count[FreeQ[term, #] & /@ vars, False];
> Sort[List @@ poly, exp[#1] <= exp[#2] &]
> ]
>
> Now sortPoly[f, {x,y}] returns
>
> {2, 5 x, 7 x^2, 5 x^3, x^4, 4 y, 10 y^2, 3 y^3, y^4, 16 x y, 9 x^2 y,
> 4 x^3 y, 15 x y^2, 6 x^2 y^2, 4 x y^3}
>


Szabolcs Horvát

unread,
Mar 16, 2008, 6:50:45 AM3/16/08
to

It is not possible to do this because Plus has the Attribute orderless.

This means that Mathematica will automatically sort the terms of any
sum using its built-in ordering rules.

Here's a function that returns a list of the terms sorted by degree:

sortPoly[poly_, vars_] := Module[{x, exp},
exp[term_] := Exponent[term /. Alternatives @@ vars -> x, x];
Sort[List @@ poly, exp[#1] >= exp[#2] &]
]

(The exp[] function returns the degree of a term.)

For example:

f = 2 + 5 x + 7 x^2 + 5 x^3 + x^4 + 4 y + 16 x y + 9 x^2 y + 4 x^3 y +

da...@wolfram.com

unread,
Mar 17, 2008, 1:22:36 AM3/17/08
to
> Hello,
>
> how it is possible to rearrange the terms of a multivariate polynomial
> in Standard or Traditional Form in such a way that the terms are ordered
> according to the number of their variables, i.e. first the constant
> term, then the group of terms depending on one of the variables, then
> the group of terms depening on two variables, then the group of those
> with three variables, etc.?
>
> Thank
>
> Stefan

The approach below might do what you want. The idea is to recast the
polynomial into a list with elements of the form
{exponent vector, coefficient}
(this uses the function GroebnerBasis`DistributedTermsList).

But to achieve your desired ordering we rig the vectors so that they only
have ones, that is, we make terms behave as though they were multilinear.
We also must keep track of the original terms. I'll do this by replacing
each variable to a power, x^j, with x^j*newx (no power associated to that
newx) and keep the original variables in coefficients, only using the new
ones in exponent vectors.

I also will return the result in a dummy head, myPlus, to which I attach a
formatting rule to print like the usual Plus, only without evaluating as
Plus and reordering terms in the process.

Finally, I will note that the code below assumes the input is a polynomial
in some "obvious" set of variables, and that it is in expanded form.

Format[myPlus[ee__]] := Infix[myPlus[ee], "+"]

orderByNumberVariables[poly_Plus] := Module[
{vars = Variables[poly], x, n, newvars, ruls, new},
n = Length[vars];
newvars = Array[x, n];
ruls = Table[vars[[j]]^n_. -> vars[[j]]^n*newvars[[j]], {j, n}];
new = GroebnerBasis`DistributedTermsList[poly /. ruls, newvars,
MonomialOrder -> DegreeLexicographic];
Apply[myPlus, Map[Last, Reverse[First[new]]]]
]

Here is a short example.

In[95]:= x^2*y + x*y*z + z^2
Out[95]= x^2 y + x y z + z^2

In[97]:= orderByNumberVariables[x^2*y + x*y*z + z^2]
Out[97]= 2 2
(z )+(x y)+(x y z)

The formatting is a bit awkward because I had to convert to OutputForm to
get the cut-paste to give anything legible.

It is not hard to code variants that take a variable list into account in
deciding, say, whether x comes before or after z.

There is a project afoot to improve on TraditionalForm, in part by making
it more configurable. A side effect of this project is that we might
(finally) promote DistributedTermsList-- and its sibling
FromDistributedTermsList-- to prime time, that is, System` context
functions.

Daniel Lichtblau
Wolfram Research

0 new messages