With Mathematica I would like collect terms from (1 + a开发者_运维问答 + x + y)^4
according to the exponents of x
and y
, so
(1 + a + x + y)^4 = (...)x^0 y^0 + (...)x^1 y^0 + (...)x^0 y^1 + ...
The Mathematica help has a nice example which I tried to imitate:
D[f[Sqrt[ x^2 + 1 ]], {x, 3}]
Collect[%, Derivative[ _ ][ f ][ _ ], Together]
This collects derivative terms of the same order (and the same argument for f)
Can anyone explain why the following imitation does not work?
Collect[(1 + a + x + y)^4, x^_ y^_]
gives
(1 + a + x + y)^4
Any suggestions for a solution?
As per Sasha, you have to Expand
the polynomial to use Collect
. However, even then it isn't that simple of a problem. Using Collect
you can group by two variables, but it depends on how you order them:
In[1]:= Collect[ (1 + a + x + y)^4 // Expand, {x, y}]
Out[1]:= 1 + 4 a + 6 a^2 + 4 a^3 + a^4 + x^4 +
(4 + 12 a + 12 a^2 + 4 a^3) y + (6 + 12 a + 6 a^2) y^2 +
(4 + 4 a) y^3 + y^4 + x^3 (4 + 4 a + 4 y) +
x^2 (6 + 12 a + 6 a^2 + (12 + 12 a) y + 6 y^2) +
x (4 + 12 a + 12 a^2 + 4 a^3 + (12 + 24 a + 12 a^2) y +
(12 + 12 a) y^2 + 4 y^3)
which pulls out any common factor of x
resulting in coefficients that are polynomials in y
. If you used {y,x}
instead, Collect
would pull out the common factors of y
and you'd have polynomials in x
.
Alternatively, you could supply a pattern, x^_ y^_
instead of {x,y}
, but at least in v.7, this does not collect anything. The issue is that the pattern x^_ y^_
requires an exponent to be present, but in terms like x y^2
and x^2 y
the exponent is implicit in at least one of the variables. Instead, we need to specify that a default value is acceptable, i.e. use x^_. y^_.
which gives
Out[2]:= 1 + 4 a + 6 a^2 + 4 a^3 + a^4 + 4 x + 12 a x + 12 a^2 x + 4 a^3 x +
6 x^2 + 12 a x^2 + 6 a^2 x^2 + 4 x^3 + 4 a x^3 + x^4 + 4 y +
12 a y + 12 a^2 y + 4 a^3 y + (12 + 24 a + 12 a^2) x y +
(12 + 12 a) x^2 y + 4 x^3 y + 6 y^2 + 12 a y^2 + 6 a^2 y^2 +
(12 + 12 a) x y^2 + 6 x^2 y^2 + 4 y^3 + 4 a y^3 + 4 x y^3 + y^4
But, this only collects terms where both variables are present. Truthfully, I can't seem to come up with a pattern that would make Collect
function like you want, but I have found an alternative.
I'd use CoefficientRules
instead, although it does require a little post-processing to put the result back into polynomial form. Using your polynomial, you get
In[3]:= CoefficientRules[(1 + a + x + y)^4, {x, y}]
Out[3]:= {{4, 0} -> 1, {3, 1} -> 4, {3, 0} -> 4 + 4 a, {2, 2} -> 6,
{2, 1} -> 12 + 12 a, {2, 0} -> 6 + 12 a + 6 a^2, {1, 3} -> 4,
{1, 2} -> 12 + 12 a, {1, 1} -> 12 + 24 a + 12 a^2,
{1, 0} -> 4 + 12 a + 12 a^2 + 4 a^3, {0, 4} -> 1, {0, 3} -> 4 + 4 a,
{0, 2} -> 6 + 12 a + 6 a^2, {0, 1} -> 4 + 12 a + 12 a^2 + 4 a^3,
{0, 0} -> 1 + 4 a + 6 a^2 + 4 a^3 + a^4}
Now, if you're only interested in the coefficients themselves, then you're done. But, to transform this back into a polynomial, I'd use
In[4]:= Plus @@ (Out[3] /. Rule[{a_, b_}, c_] :> x^a y^b c)
Out[4]:= 1 + 4 a + 6 a^2 + 4 a^3 + a^4 +
(4 + 12 a + 12 a^2 + 4 a^3) x +
(6 + 12 a + 6 a^2) x^2 + (4 + 4 a) x^3 + x^4 +
(4 + 12 a + 12 a^2 + 4 a^3) y + (12 + 24 a + 12 a^2) x y +
(12 + 12 a) x^2 y + 4 x^3 y + (6 + 12 a + 6 a^2) y^2 +
(12 + 12 a) x y^2 + 6 x^2 y^2 + (4 + 4 a) y^3 +
4 x y^3 + y^4
Edit: After thinking about it, there is one more simplification that can be done. Since the coefficients are polynomials in a
, they may be factorable. So, instead of using what CoefficientRules
gives directly, we use Factor
to simplify:
In[5]:= Plus @@ (Out[3] /. Rule[{a_, b_}, c_] :> x^a y^b Factor[c])
Out[5]:= (1 + a)^4 + 4 (1 + a)^3 x + 6 (1 + a)^2 x^2 + 4 (1 + a) x^3 + x^4 +
4 (1 + a)^3 y + 12 (1 + a)^2 x y + 12 (1 + a) x^2 y + 4 x^3 y +
6 (1 + a)^2 y^2 + 12 (1 + a) x y^2 + 6 x^2 y^2 + 4 (1 + a) y^3 +
4 x y^3 + y^4
As can be seen, the coefficients are considerably simplified by using Factor
, and this result could have been anticipated by thinking of (1 + a + x + y)^4
as a simple trinomial with variables (1 + a)
, x
, and y
. With that in mind and replacing 1+a
with z
, CoefficientRules
then gives:
In[6]:= CoefficientRules[(z + x + y)^4, {x, y, z}]
Out[6]:= {{4, 0, 0} -> 1, {3, 1, 0} -> 4, {3, 0, 1} -> 4,
{2, 2, 0} -> 6, {2, 1, 1} -> 12, {2, 0, 2} -> 6,
{1, 3, 0} -> 4, {1, 2, 1} -> 12, {1, 1, 2} -> 12,
{1, 0, 3} -> 4, {0, 4, 0} -> 1, {0, 3, 1} -> 4,
{0, 2, 2} -> 6, {0, 1, 3} -> 4, {0, 0, 4} -> 1}
Or, in polynomial form
Out[7]:= x^4 + 4 x^3 y + 6 x^2 y^2 + 4 x y^3 + y^4 + 4 x^3 z +
12 x^2 y z + 12 x y^2 z + 4 y^3 z + 6 x^2 z^2 + 12 x y z^2 +
6 y^2 z^2 + 4 x z^3 + 4 y z^3 + z^4
which when you replace z
with (1 + a)
gives the identical result shown in Out[5]
.
Collect
is a structural operation, so you need to expand first.
Collect[(1 + a + x + y)^4 // Expand, x^_ y^_]
This works:
In[1]:= Collect[(1 + a + x + y)^4 // Expand, {x^_ y^_, x^_ y, x y^_, x y, x, y}]
Out[1]= 1 + 4 a + 6 a^2 +
4 a^3 + a^4 + (4 + 12 a + 12 a^2 + 4 a^3) x + (6 + 12 a + 6 a^2) x^2 + (4 +
4 a) x^3 + x^4 + (4 + 12 a + 12 a^2 + 4 a^3) y + (12 + 24 a +
12 a^2) x y + (12 + 12 a) x^2 y +
4 x^3 y + (6 + 12 a + 6 a^2) y^2 + (12 + 12 a) x y^2 +
6 x^2 y^2 + (4 + 4 a) y^3 + 4 x y^3 + y^4
Alternatively you can use Default
as suggested by rcollyer:
In[2]:= Collect[(1 + a + x + y)^4 // Expand, {x^_. y^_., x, y}]
Out[2]= 1 + 4 a + 6 a^2 +
4 a^3 + a^4 + (4 + 12 a + 12 a^2 + 4 a^3) x + (6 + 12 a + 6 a^2) x^2 + (4 +
4 a) x^3 + x^4 + (4 + 12 a + 12 a^2 + 4 a^3) y + (12 + 24 a +
12 a^2) x y + (12 + 12 a) x^2 y +
4 x^3 y + (6 + 12 a + 6 a^2) y^2 + (12 + 12 a) x y^2 +
6 x^2 y^2 + (4 + 4 a) y^3 + 4 x y^3 + y^4
Plus @@ MonomialList[(1 + a + x + y)^4, {x, y}]
This may be what you were looking for
In[1]:= TraditionalForm[Collect[(1 + a + x + y)^4 // Expand, {x, y}],
ParameterVariables :> {a}]
Out[1]:= x^4+x^3 (4 y+4 a+4)+x^2 (6 y^2+(12 a+12) y+6 a^2+12 a+6)+
x (4 y^3+(12 a+12) y^2+ (12 a^2+24 a+12) y+4 a^3+12 a^2+12 a+4)+
y^4+(4 a+4) y^3+(6 a^2+12 a+6) y^2+(4 a^3+12 a^2+12 a+4) y+
a^4+4 a^3+6 a^2+4 a+1
精彩评论