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.

  • 1
    $\begingroup$ Collect[expr, G[__], h1] /. G :> Composition[h2, G] $\endgroup$
    – Bob Hanlon
    Commented May 11, 2020 at 19:25
  • $\begingroup$ 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.. $\endgroup$
    – Stijn
    Commented May 12, 2020 at 13:36
  • 1
    $\begingroup$ Would it make sense to use Collect[...] in that third argument? $\endgroup$ Commented May 12, 2020 at 14:38
  • $\begingroup$ 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. $\endgroup$
    – Stijn
    Commented May 13, 2020 at 15:06

1 Answer 1


How about this?

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

G[1] + Sqrt[2] G[2] + Sqrt[3] G[3] + 2 G[4] + Sqrt[5] G[5] - G[3] Log[2] - G[4] Log[3] - G[5] Log[4] - G[6] Log[5]

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

f[1] h[G[1]] + f[Sqrt[2]] h[G[2]] + f[Sqrt[3] - Log[2]] h[G[3]] + f[2 - Log[3]] h[G[4]] + f[Sqrt[5] - Log[4]] h[G[5]] + f[-Log[5]] h[G[6]]

  • $\begingroup$ If I am not mistaken this still involves doing pattern matching (or similar) "twice", once for the Collect, and once for the replacement. I would like to avoid doing this "double work", since in principle in the first Collect Mathematica already knows which coefficients and Gs it is dealing with, and how they are paired. $\endgroup$
    – Stijn
    Commented May 13, 2020 at 15:09

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.