6
$\begingroup$

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.

$\endgroup$

5 Answers 5

3
$\begingroup$

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)

$\endgroup$
2
  • $\begingroup$ Thanks, this can take care of the minus sign if any. $\endgroup$
    – Fred G
    Commented Dec 1, 2012 at 6:21
  • $\begingroup$ @FredG haha. What about the edited code? $\endgroup$
    – Rojo
    Commented Dec 1, 2012 at 7:00
8
$\begingroup$

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

$\endgroup$
4
$\begingroup$

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) *)
$\endgroup$
3
  • $\begingroup$ BTW, how do you make a pattern for {c_ x1 - c_ x2 -> c (x1 - x2)} ? It won't recognize the minus sign. $\endgroup$
    – Fred G
    Commented Dec 1, 2012 at 5:58
  • $\begingroup$ In the simple cases you don't need much; expr = c x1 - c x2; expr//Simplify will do. $\endgroup$ Commented Dec 1, 2012 at 9:15
  • $\begingroup$ @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. $\endgroup$
    – Artes
    Commented Dec 2, 2012 at 2:52
1
$\begingroup$

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

$\endgroup$
1
$\begingroup$

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.

$\endgroup$
1
  • $\begingroup$ 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... $\endgroup$
    – Fred G
    Commented Nov 16, 2012 at 1:07

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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