6

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.

Fred G
  • 63
  • 1
  • 5

5 Answers5

8

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 
obtained. 

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

Artes
  • 57,212
  • 12
  • 157
  • 245
4

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) *)
b.gates.you.know.what
  • 20,103
  • 2
  • 43
  • 84
  • 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 01 '12 at 05:58
  • In the simple cases you don't need much; expr = c x1 - c x2; expr//Simplify will do. – b.gates.you.know.what Dec 01 '12 at 09: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 02 '12 at 02:52
3

Perhaps replacing with dummies for simplification?

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

So

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

gives

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

Rojo
  • 42,601
  • 7
  • 96
  • 188
1

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.

Artes
  • 57,212
  • 12
  • 157
  • 245
Nasser
  • 143,286
  • 11
  • 154
  • 359
  • 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... –  Nov 16 '12 at 01:07
1

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))

Artes
  • 57,212
  • 12
  • 157
  • 245
Alexei Boulbitch
  • 39,397
  • 2
  • 47
  • 96