# Collect and simplify both the coefficents and the matched patterns

(This is a far tighter version of a previous question I asked) The problem with Collect is that while Collect[exp, pattern, Simplify] will simplify the coefficients, it does nothing to the matched patterns themselves. If one then calls FullSimplify on the result of the collection, it frequently undoes the collect. This is especially important when collecting and matching with complicated non-integer exponents or exponentials.

To solve this, what do you think of the following solution? Is there any way I could lose parts of the expression tree with this transformation?

CollectFullSimplifyImpl[exp_, pat_]:= If[MatchQ[#,pat], FullSimplify@#, #]& //@ Collect[exp, pat, FullSimplify];
CollectFullSimplify[exp_, pat_]:= FixedPoint[CollectFullSimplifyImpl[#, pat]&, exp]


I think I want to do a depth first MapAll so simplify the expressions from the bottom up if they are recursive and ensure that I don't undo the previous collections as I go through (i.e. calling FullSimplify on a higher level node could mean lower nodes no longer match the pattern). Why have a Fixed point? Want to allow the recollection//further simplification if the exponents have themselves simplified and could be combined, but having trouble finding a minimal example. Might be unncessary... *)

To see the results, try the following tests:

exp = ((b - a)/a - b/a )x^(((b - a)/a) - (b/a)  )+(1 + a)x + (b - 1)x;
exp2 = ((b - a)/a - b/a )x^(((b - a)/a) - (b/a)  )+ x^x^((b - a)/a - b/a-1/x+x^((b - a)/a - b/a)); (* Test out the recursion *)
Print["Collect, then Collect with simplification, then CollectFullSimplify"]
Collect[exp, x^_]
Collect[exp, x^_, FullSimplify]
CollectFullSimplify[exp, x^_]

Print["Collect, then Collect with simplification, then CollectFullSimplify"]
Collect[exp2, x^_]
Collect[exp2, x^_, FullSimplify]
CollectFullSimplify[exp, x^_]


The following is the output

"Collect, then Collect with simplification, then CollectFullSimplify"

(*
==> (1 + a) x + (-1 + b) x + (-(b/a) + (-a + b)/a) x^(-(b/
a) + (-a + b)/a)
*)

(* ==> (a + b) x - x^(-(b/a) + (-a + b)/a) *)

(*
==> -(1/x) + (a + b) x

During evaluation of
*)

"Collect, then Collect with simplification, then CollectFullSimplify"

(*
==> -x^(-(b/a) + (-a + b)/a) + x^x^(-(b/a) + (-a + b)/a - 1/x +
x^(-(b/a) + (-a + b)/a))
*)

(*
==> -x^(-(b/a) + (-a + b)/a) + x^x^(-(b/a) + (-a + b)/a - 1/x +
x^(-(b/a) + (-a + b)/a))
*)

(* ==> -(1/x) + (a + b) x *)


One problem I have found is the following: CollectFullSimplifyImpl[v[l][z_] , z^_] becomes v[l][Pattern[(If[MatchQ[#, z^Blank[]], FullSimplify[#], #]& )[z], Blank[]]] This is ugly since I commonly want to call CollectFullSimplify on rules of the form {v[l][z_] -> COMPLICATED STUFF, and this wrecks it.

-
No, I guess not. Reading again. – Mr.Wizard Aug 26 '13 at 18:38
Thanks. Ignore the fixed point for now, I am starting to rethink whether it is a good idea. But the main code seems to work except when applied to rules. – jlperla Aug 26 '13 at 18:43

Since I'm not sure I understand your desired functionality I'm going to tackle this question from the other end and see if I can fix the problem with your own code. Rather than using MapAll which as the name implies maps a function to all sub-expressions, including those that don't match your pattern pat, you could use Replace with a levelspec of {0, -1}:

 CollectFullSimplifyImpl[exp_, pat_] :=
Replace[
Collect[exp, pat, FullSimplify],
x : pat :> RuleCondition @ FullSimplify @ x,
{0, -1}
]


I added RuleCondition for good measure, in case your pattern matches parts of held expressions. Please test this function and tell me if and where it fails.

-
It seems to work perfectly. It also solves the issue of mashing overtop of the rules. The reason I wanted to put in a fixed point was that after simplifying the matched expressions (e.g. here we simplify ((b - a)/a) - (b/a) in the exponent where it didn't with just Collect...) it may be possible that further terms could be combined with another Collect. But I am having trouble figuring out where I ran into this. Perhaps it should be ignored. – jlperla Aug 26 '13 at 19:02
One protocol question: Is it good form to delete the related question I asked that was worded poorly? – jlperla Aug 26 '13 at 19:05
@jlperla You mean this one? – Mr.Wizard Aug 26 '13 at 19:06
yes, that is it – jlperla Aug 26 '13 at 19:11
@jlperla I see you Accepted this answer. Thanks, but you don't need to be so quick about that; someone else may have a completely different and better way to approach your problem. I suggest you delete the old question as nobody answered it and I'm the only one who even bothered to comment on it, so it's unlikely anyone is currently working on an answer. – Mr.Wizard Aug 26 '13 at 19:49