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
expr
bye[_]
,f[_]
,g[_]
andh[_]
.Apply
simpE
to the coefficients ofe[_]
, andsimpF
to the coefficients off[_]
, andsimpGen
to the coefficient of everything else.This needs to work even when certain terms are absent from
expr
. e.g. ifexpr
doesn'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
rule
groupse[y]
with the rest of the terms and incorrectly appliessimpRest
to it (see last term of output), instead ofsimpE[x+y] e[y]
.If certain terms are absent, then the
rule
doesn't even match. Considerexpr2
below 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?
myCollect
in this thread mathematica.stackexchange.com/questions/85479/… 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. $\endgroup$