How to organize expression by symbols (like Collect), but apply different functions to each coefficient
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?
Answer
Maybe the following. Simplifying a left-over constant term along with the other coefficients seems hard to comprise in a single, simple function.
forms = {_f, _e, _g, _h};
funcs = {simpF, simpE, simpG, simpH};
simpConstant[c_] := simpC[c];
Times[c_simpAll, form_] ^:= (c /. simpAll -> (form /. Thread[forms -> funcs])) form;
Collect[2 + expr, {_f, _e, _g, _h}, simpAll] /. simpAll -> simpConstant
Collect[2 + expr2, {_f, _e, _g, _h}, simpAll] /. simpAll -> simpConstant
Collect[2 + x, {_f, _e, _g, _h}, simpAll] /. simpAll -> simpConstant
(*
simpC[2] + e[y] simpE[x + y] + e[x] simpE[-2 x + x^2 + y] +
f[x] simpF[x^2 + y^2] + g[x] simpG[x^2] + h[x] simpH[y^2]
simpC[2] + e[y] simpE[x + y] + e[x] simpE[-2 x + x^2 + y] +
g[x] simpG[x^2] + h[x] simpH[y^2]
simpC[2 + x]
*)
Comments
Post a Comment