4
$\begingroup$

As the documentation says the command Through works as it follows:

f[x_]=x;
g[x_]=x^2;
Through[(f+g)[x]]

--> x + x^2

Like this, I also expect it works as below:

Through[(f-g)[x]]

--> x - x^2

It, however, returns:

Through[(f-g)[x]]

--> x + (-g)[x]

Do you guys know how to make Mathematica return as I expect for the subtraction?

I use Mathematica11.1 on Windows10 64bit.

$\endgroup$
2
  • $\begingroup$ Taiki, you might want to use SetDelayed (:=) instead of Set (=) when defining f and g (i.e., ClearAll[f, g]; f[x_]:= x and g[x_]:= x^2 ) if you want Through[(f + g)[z]] to give z+z^2 (not f[z]+g[z]). $\endgroup$
    – kglr
    Jul 8, 2019 at 20:42
  • $\begingroup$ @kglr I don't see any difference between SetDelayed(:=) and Set(=) in this case. I understand general definitions of SetDelayed(:=) and Set(=) $\endgroup$ Jul 8, 2019 at 20:52

3 Answers 3

5
$\begingroup$

To understand what's happening always check the FullForm of your expresion.

FullForm[(f - g)[x]]

(* Plus[f,Times[-1,g]] *)

That is the expression Mathematica is working with internally. Probably you were expecting Subtract[f, g][x], but that is not the case.

You could ReplaceAll (/.) the Times[-1,#] with Composition[Minus,#].

Through[(f-g)[x]]/.Times[-1,q_]->Composition[Minus,q]
(* f[x]-g[x] *)

%//FullForm
(* Plus[f[x],Times[-1,g[x]]] *)
$\endgroup$
5
$\begingroup$

You can compose Minus with g use it with Plus:

Through[(f + Minus @* g)[x]]

x - x^2

Other ways:

Through[(f + (-g @ # &))[x]]

x - x^2

Through[(f + (-#&) @* g)[x]]

x - x^2

$\endgroup$
3
$\begingroup$

I sometimes want to apply a linear combination of functions to an argument. This can be more difficult if the linear combinations are generated by code, so that rewriting them some form to make Through convenient is difficult. So I usually use a utility like the following:

linearThrough[(Optional[a_?NumericQ] f_ + Optional[b_?NumericQ] g_)[x__]] :=
  a f[x] + b g[x];

OP's example:

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

You can also use Subtract if you prevent it from evaluating to Plus[f, Times[-1, g]] prematurely:

Through[Unevaluated@Subtract[f, g][x]]
(*  f[x] - g[x]  *)

Since I somewhat broadened the scope by bring in linear combinations of functions, here is a similar utility, in which the linear operators are specified as a argument, everything else is assumed to be constant:

linearOperate[heads_List][comb_[x__]] :=
  (comb /. F : Alternatives @@ heads :> F[x]) /;
   Internal`LinearQ[comb, heads] || FreeQ[comb, Alternatives @@ heads];

Examples:

linearOperate[{f, g}][(f - g)[x]]
(*  f[x] - g[x]  *)

linearOperate[{f, g, h}][(a f - g + h - b + 9)[x]]
(*  9 - b + a f[x] - g[x] + h[x]  *)

linearOperate[{f, g, h}][(a f)[x]]
(*  a f[x]  *)

linearOperate[{f, g, h}][(3)[x]]
(*  3  *)

This last example is the reason for the extra test, ... || FreeQ[comb, Alternatives @@ heads]: Internal`LinearQ says a constant is not linear:

Internal`LinearQ[3, {f, g, h}]
(*  False  *)
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.