# Applying function to both coefficients and variables in Collect

I am dealing with expressions schematically of the form

expr = c[1] G[1] + c[3,8] G[3,8] + ... + c[3] G[1] + ...


where the Gs are fixed objects, and the cs some messy coefficients. I would like to collect this term by term in the Gs, getting something of the form

Sum[d[i__] G[i__], {i, some_set}]


and then perform operations on both the ds and the Gs. If I just wanted to do something to the ds, I believe

Collect[expr, G[__], operation_d]


would be the appropriate, and presumably most efficient, function to use. Is there some (in-built) way to act simultaneously on the Gs as well? I believe the process necessarily carries all required data during the process of collecting.

Of course I can generate a list of the relevant Gs (Collect[expr, G[__], 1&]) and a list of corresponding coefficients, then act on them and recombine them. However this splits the problem in two parts externally rather than internally, and for the case that can be handled by just Collect[] in one step this is definitely less efficient. I am basically wondering if there is something more "Mathematica-like" to do. Thanks!

Note: I am aware of the related but not identical five year old question How to organize expression by symbols (like Collect), but apply different functions to each coefficient.

• Collect[expr, G[__], h1] /. G :> Composition[h2, G] May 11, 2020 at 19:25
• Thanks! that's an elegant way of writing it. However, if I'm not mistaken it still means mathematica has to pattern match the G's "twice", which I was hoping to avoid. Maybe it's just not possible though.. May 12, 2020 at 13:36
• Would it make sense to use Collect[...] in that third argument? May 12, 2020 at 14:38
• I think (the first) Collect allows me to specify an action on the "coefficients", but no way to obviously act on the "variables", so then I think adding a further Collect cannot directly help. May 13, 2020 at 15:06

expr = Sum[Sqrt[n] G[n], {n, 1, 5}] - Sum[Log[n] G[n + 1], {n, 1, 5}]

Collect[expr, G[__]] /. c_.*G[x__] :> f[c] h[G[x]]