Mathematica Stack Exchange is a question and answer site for users of Mathematica. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

For example, I have the following expression :

A( 2 x1 + B(y1 + y2) + 2 x2 )

How do I make the output look like this (grouping (x1 + x2) and (y1 + y2) terms together) ?

2A (x1 + x2) + A B (y1 + y2)

I don't know why Simplify doesn't group (x1 + x2) together but just gives:

A (2 x1 + 2 x2 + B (y1 + y2))

I can use Collect to get (y1 + y2) after Simplify but how about (x1 + x2) ?

Remember this is just a simple example, I would have a much more complicated terms involving (x1 + x2) and (y1 + y2), so a method with no operation on the constants (2A and A B) would be great.

share|improve this question

migrated from Nov 16 '12 at 15:27

This question came from our site for professional and enthusiast programmers.

up vote 3 down vote accepted

Perhaps replacing with dummies for simplification?

doThat[expr_, vars_List] := 
    expr /. Flatten[
      Solve[# == ToString@#, First@Variables@#] & /@ vars]], 
   Alternatives @@ ToString /@ vars] /. 
  Thread[ToString /@ vars -> vars]


doThat[c a (x1 + x2) + d a (x1 + x2) + a (y1 + y2), {x1 + x2, 
  y1 + y2}]


a (c + d) (x1 + x2) + a (y1 + y2)

share|improve this answer
Thanks, this can take care of the minus sign if any. – Fred G Dec 1 '12 at 6:21
@FredG haha. What about the edited code? – Rojo Dec 1 '12 at 7:00

One can apply a proper function as the third argument of Collect:

From documentation :

Collect[expr,var,h]  applies h to the expression that forms the coefficient of each term 

Here we can use B as var and Factor as h :

Collect[ A( 2x1 + B(y1 + y2) + 2x2), B, Factor]
2 A (x1 + x2) + A B (y1 + y2)

Instead of Factor one can use here Simplify or FullSimplify, and {B, A} instead of B. In full generality we cannot say what is the most appropriate function, it depends rather on a case-by-case basis. Sometimes one can get expected forms using only appropriate options in Simplify and FullSimplify like : ComplexityFunction, ExcludedForms, TransformationFunctions. More can be found in tutorials e.g. Simplification or Simplification Control in Algebraic Transformations

share|improve this answer

Maybe this will get you started :

expr = A*(2*x1 + B*(y1 + y2) + 2*x2) ;

rules = {c_ x1 + c_ x2 -> c (x1 + x2), d_ y1 + d_ y2 -> d (y1 + y2)} ;

(expr // Expand) //. rules 

(* 2 A (x1 + x2) + A B (y1 + y2) *)
share|improve this answer
BTW, how do you make a pattern for {c_ x1 - c_ x2 -> c (x1 - x2)} ? It won't recognize the minus sign. – Fred G Dec 1 '12 at 5:58
In the simple cases you don't need much; expr = c x1 - c x2; expr//Simplify will do. – b.gatessucks Dec 1 '12 at 9:15
@FredG If you don't know the recommended way (as well as the most general) to solve the problem is based on this approach Collect[expr,var, h]. You can apply it for much more involved algebraic expressions not worrying to play around with rules or whatever else. Look at my answer carefully. – Artes Dec 2 '12 at 2:52

I do not know how to make it more directly, but you can hack it like this

expr = A ( 2x1 + B (y1 + y2) + 2x2);
Collect[ expr, B];
Plus @@ { Simplify[ %[[1]]] , %[[2]]}

which gives

(*  2 A ( x1 + x2) + A B ( y1 + y2)  *)

not too pretty. I am sure there is a better way.

share|improve this answer
Thanks for the answer but as stated above, I have much more complicated expressions than just that B. I can't Collect each then simplify again and look again to see what to Collect next... – Fred G Nov 16 '12 at 1:07

Consider this as an additional rule-based approach:

 expr = A (2 x1 + B (y1 + y2) + 2 x2);
(expr /. {x1 -> X - x2, y1 -> Y - y2} // Simplify) /. {X -> (x1 + x2),
   Y -> (y1 + y2)}

yielding the answer: A (2 (x1 + x2) + B (y1 + y2))

share|improve this answer

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.