One could consider a home cooked simplify.
The purpose of the code below is to eliminate any guidance from the user. That is, there is no hard coding or any way to incorporate insight from the user.
The main idea is to find the terms that occur the most in multiplications and collect those.
Using simplify defined below:
expr // simplify
(G3 + G4 + G5 + G7 + G8) P2 + (G1 + G3 + G4 + G5 + G7 + G8) P5 + (G1 + G2 + G4 + G5 + G6 + G8) (P3 + P6)
In LaTeX :
$$(\text{P3}+\text{P6}) (\text{G1}+\text{G2}+\text{G4}+\text{G5}+\text{G6}+\text{G8})+\text{P5} (\text{G1}+\text{G3}+\text{G4}+\text{G5}+\text{G7}+\text{G8})+\text{P2} (\text{G3}+\text{G4}+\text{G5}+\text{G7}+\text{G8})$$
(expr // simplify) == desired
(*True*)
Code:
(code unpacked and mostly explained below)
Note: ⎵=\[UnderBracket]
Note: The code checks that the expression is a sum of products and aborts otherwise.
Edit
Note this version of the code uses ReplaceRepeated
and so it might end up in an infinite loop for some expressions.
I changed the code to use Bob Hanlon's replacement rule as my idea looks silly now. The beginning of the code that did not involve finding multiple occurrences of a factor is the same.
Clear[simplify];
simplify[expression_]:=
Module[{check,var,to⎵collect,
simplified,duplicated,x,renaming⎵rule,
renaming⎵rule⎵inversed,new⎵variables},
check= Head[expression]===Plus &&
(List@@expression//AllTrue[#,MatchQ[_Times]]&);
If[check===False,
Print["simplify is not adapted to this structure"];
Abort[]
];
var=(expression//Variables);
to⎵collect={Count[expression,#*_],#}&/@var
//MaximalBy[First]
//Map[Last];
simplified=Collect[expression, to⎵collect, Simplify]
//. a_*b_+c_*b_:> (a+c)*b
]
Previous version of the code
Clear[simplify];
simplify[expression_]:=
Module[{check,var,to⎵collect,
simplified,duplicated,x,renaming⎵rule,
renaming⎵rule⎵inversed,new⎵variables},
check= Head[expression]===Plus &&
(List@@expression//AllTrue[#,MatchQ[_Times]]&);
If[check===False,
Print["simplify is not adapted to this structure"];
Abort[]
];
var=(expression//Variables);
to⎵collect={Count[expression,#*_],#}&/@var
//MaximalBy[First]
//Map[Last];
simplified=Collect[expression, to⎵collect, Simplify];
(* Find subexpressions that occur
multiple times *)
duplicated=simplified
//Level[#,{2}]&
//Gather
//Select[Length@#>1&]
//Map[DeleteDuplicates]
//Flatten;
Collect[simplified,
duplicated,
Simplify]
]
Explanation
- Step 1
Find the variables:
var = (expr // Variables);
- Step 2
Find which variables occur the most in the multiplications:
{Count[expr, #*_], #} & /@ var // Sort
{{2, G2}, {2, G3}, {2, G6}, {2, G7}, {3, G1}, {4, G4}, {4, G5}, {4, G8}, {5, P2}, {6, P3}, {6, P5}, {6, P6}}
(included transposition to reduce displayed height )
$$\left( \begin{array}{cccccccccccc} 2 & 2 & 2 & 2 & 3 & 4 & 4 & 4 & 5 & 6 & 6 & 6 \\ \text{G2} & \text{G3} & \text{G6} & \text{G7} & \text{G1} & \text{G4} & \text{G5} & \text{G8} & \text{P2} & \text{P3} & \text{P5} & \text{P6} \\ \end{array} \right)$$
- Step 3
Collect the variables that occur the most in multiplications:
simplified = Collect[expr, {P6, P5, P3}, Simplify]
(G3 + G4 + G5 + G7 + G8) P2 + (G1 + G2 + G4 + G5 + G6 + G8) P3 + (G1 + G3 + G4 + G5 + G7 + G8) P5 + (G1 + G2 + G4 + G5 + G6 + G8) P6
$$ \text{P3} (\text{G1}+\text{G2}+\text{G4}+\text{G5}+\text{G6}+\text{G8})+\text{P6} (\text{G1}+\text{G2}+\text{G4}+\text{G5}+\text{G6}+\text{G8})+\text{P5} (\text{G1}+\text{G3}+\text{G4}+\text{G5}+\text{G7}+\text{G8})+\text{P2} (\text{G3}+\text{G4}+\text{G5}+\text{G7}+\text{G8}) $$
- Step 4
collect sub expressions that occur more than once.
One could maybe use
Experimental`OptimizeExpression
(see for example Common subexpression from two expressions )
to find common sub expressions in the expression above but instead I consider a more simple approach for this kind of structure:
simplified // Level[#, {2}] & // Tally
{{G3 + G4 + G5 + G7 + G8, 1}, {P2, 1}, {G1 + G2 + G4 + G5 + G6 + G8, 2}, {P3, 1}, {G1 + G3 + G4 + G5 + G7 + G8, 1}, {P5, 1}, {P6, 1}}
$$\left( \begin{array}{cc} \text{G3}+\text{G4}+\text{G5}+\text{G7}+\text{G8} & 1 \\ \text{P2} & 1 \\ \text{G1}+\text{G2}+\text{G4}+\text{G5}+\text{G6}+\text{G8} & 2 \\ \text{P3} & 1 \\ \text{G1}+\text{G3}+\text{G4}+\text{G5}+\text{G7}+\text{G8} & 1 \\ \text{P5} & 1 \\ \text{P6} & 1 \\ \end{array} \right)$$
G1 + G2 + G4 + G5 + G6 + G8 appears twice we can rename it then simplify then rename again:
Collect[simplified , G1 + G2 + G4 + G5 + G6 + G8]
$$(\text{P3}+\text{P6}) (\text{G1}+\text{G2}+\text{G4}+\text{G5}+\text{G6}+\text{G8})+\text{P5} (\text{G1}+\text{G3}+\text{G4}+\text{G5}+\text{G7}+\text{G8})+\text{P2} (\text{G3}+\text{G4}+\text{G5}+\text{G7}+\text{G8})$$