I want to mimic the functionality of Collect[expr, {vars}, func], but with the following modification: The function f that is applied to each coefficient is different, and depends on which variable it is a coefficient of. The vars are expressions of predetermined known heads (which in the example below are _e, _f, _g, _h).
Example:
expr = -2 x e[x] + x e[y] + x^2 e[x] + y e[x] + y e[y] + x^2 f[x] + y^2 f[x] + x^2 g[x] + y^2 h[x]
I need to collect
exprbye[_],f[_],g[_]andh[_].Apply
simpEto the coefficients ofe[_], andsimpFto the coefficients off[_], andsimpGento the coefficient of everything else.This needs to work even when certain terms are absent from
expr. e.g. ifexprdoesn't have anye[_]etc.
My idea (which doesn't work) is to do this in two steps:
First collect the expression:
Collect[expr, {_f, _e, _g, _h}]Then replace with the rule that makes the transformation on each coefficient.
rule = (Plus[ Optional[Times[exprE_., funcE_e]], Optional[Times[exprF_., funcF_f]], rest_.]) :> (simpE[exprE] funcE + simpF[exprF] funcF + Collect[rest,{_g, _h}, simpRest])
The (not quite correct) result is:
Collect[expr, {_f, _e, _g, _h}] /. rule
e[x] simpE[-2 x + x^2 + y] + f[x] simpF[x^2 + y^2] + g[x] simpRest[x^2] + h[x] simpRest[y^2] + simpRest[(x + y) e[y]]
But this doesn't work because
the
rulegroupse[y]with the rest of the terms and incorrectly appliessimpRestto it (see last term of output), instead ofsimpE[x+y] e[y].If certain terms are absent, then the
ruledoesn't even match. Considerexpr2below which is absent off[_]:expr2 = -2 x e[x] + x^2 e[x] + y e[x] + x e[y] + y e[y] + x^2 g[x] + y^2 h[x]The rule doesn't match:
Collect[expr, {_f, _e, _g, _h}] /. rule(-2 x + x^2 + y) e[x] + (x + y) e[y] + x^2 g[x] + y^2 h[x]
I need help with this particular modification of Collect. Is there a sexy way to get this done?
myCollectin this thread http://mathematica.stackexchange.com/questions/85479/collect-without-grouping-terms could help. It modifies collect to use a function not just of the coefficient but also of the term itself. You could then just use an if statement in the function you apply to differentiate the different terms. Don't know how sexy this is though. – Jansen Dec 28 '15 at 14:29