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]]]

However, a minus sign in the parenthesis would yield

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

instead of the expected

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

What can I do about it?


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?

  • $\begingroup$ 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. $\endgroup$ Commented Mar 1, 2017 at 16:27

2 Answers 2


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]]]

  • $\begingroup$ 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? $\endgroup$ Commented Mar 1, 2017 at 17:12
  • $\begingroup$ What exactly did you try? $\endgroup$
    – Carl Woll
    Commented Mar 1, 2017 at 17:18
  • $\begingroup$ 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? $\endgroup$ Commented Mar 1, 2017 at 17:32
  • $\begingroup$ Why don't you add this to your question, along with desired outputs when the Composition is applied to a variable? $\endgroup$
    – Carl Woll
    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]]] *)

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.