# Problem with Distribute and Composition

I'm having trouble with the following. When I try to expand an expression like

Through[Distribute[g@*(f@*g + g@*f), Plus]@x]


I get what I would expect. That is,

g[f[g[x]]] + g[g[f[x]]]


g[f[g[x]]] + g[(-(g@*f))[x]]


g[f[g[x]]] - g[g[f[x]]]


What can I do about it?

Edit:

As suggested by Carl Woll, one can solve this by doing:

comp = g @* Inactive[Subtract][f@*g, g@*f];
Activate @* Through @* Distribute[comp, Inactive@Subtract] @ x

(*g[f[g[x]]] - g[g[f[x]]]*)


However, I'm still having trouble with the slightly more complicated issue of simplifying the following

fcomm[a_, b_] := Inactive[Subtract][a@*b, b@*a];
Nest[fcomm[#, g] &, f, 2]

(*Inactive[Subtract][Inactive[Subtract][f@*g, g@*f]@*g,g@*Inactive[Subtract][f@*g, g@*f]]*)


If I now try to do

Distribute[Nest[fcomm[#, g] &, f, 2], Inactive[Subtract]]

(* Inactive[Subtract][Inactive[Subtract][Inactive[Subtract][f@*g, g@*f]@*g,g@*Inactive[Subtract][f@*g, g@*f]]] *)


The expression does not simplify and picks up an Inactive[Subtract] with a single argument. What am I missing here?

• To get one step closer, you could use Through[Distribute[g@*(f@*g + Minus@*g@*f), Plus][x]]. Now you still need to specify that the minus sign has to fall through g, though. I guess you could do that with a replacement rule. Commented Mar 1, 2017 at 16:27

Maybe you can use Inactive and Subtract? For example:

comp = g @* Inactive[Subtract][f@*g, g@*f];

Activate @* Through @* Distribute[comp, Inactive@Subtract] @ x


g[f[g[x]]] - g[g[f[x]]]

• Thanks a lot. That works nicely in that case. Nonetheless, let fcomm[a_,b_]:=a@*b-b@*a and try to apply the same to simplify Nest[fcomm[#,g]&,f,2]. This returns the error message >Subtract::argr: Subtract called with 1 argument; 2 arguments are expected. What am I missing here? Commented Mar 1, 2017 at 17:12
• What exactly did you try? Commented Mar 1, 2017 at 17:18
• Let us say that fcomm[a_,b_]:=Inactive[Subtract][a@*b, b@*a]. Then, Nest[fcomm[#, g] &, f, 2] gives Inactive[Subtract][Inactive[Subtract][f@*g, g@*f]@*g, g@*Inactive[Subtract][f@*g, g@*f]]. Now, while e.g. Distribute[Nest[fcomm[#, g] &, f, 2][[1]], Inactive@Subtract] works as you show in your example (i.e. yielding Inactive[Subtract][f@*g@*g, g@*f@*g]), Distribute[Nest[fcomm[#, g] &, f, 2], Inactive@Subtract] does this: Inactive[Subtract][ Inactive[Subtract][Inactive[Subtract][f@*g, g@*f]@*g, g@*Inactive[Subtract][f@*g, g@*f]]]. Why could this be? Commented Mar 1, 2017 at 17:32
• Why don't you add this to your question, along with desired outputs when the Composition is applied to a variable? Commented Mar 1, 2017 at 18:19

After reading the answer to this other question, I figured out a simple solution by defining a CompositionSimplify function as follows:

CompositionSimplify[expr_] := (expr //. {
Composition[x_, y_ - z_] :> Composition[x, y] - Composition[x, z],
Composition[y_ - z_, x_] :> Composition[y, x] - Composition[z, x],
Times[x_, Composition[y_, z_]] :> Composition[Times[#, x] &, Composition[y, z]]
})


I can then apply this to e.g.:

Through@CompositionSimplify[Nest[fcomm[#, g] &, f, 2]]@x


and get the right result

(* ==> f[g[g[x]]] - 2 g[f[g[x]]] + g[g[f[x]]] *)