开发者

Use pattern to collect terms in Mathematica

开发者 https://www.devze.com 2023-03-19 09:27 出处:网络
With Mathematica I would like collect terms from (1 + a开发者_运维问答 + x + y)^4 according to the exponents of x and y, so

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
0

精彩评论

暂无评论...
验证码 换一张
取 消