8
$\begingroup$

Suppose I have two functions defined as follows:

a = #+3&
b = #^2 + 3&

So when I call a[2] and b[1] the output is exactly what I would expect.

a[2]
5
b[1]
4

Now I want to create another function let's call it c that is the sum of the functions a and b.

How do I do that?

$\endgroup$
  • 5
    $\begingroup$ c = a[#] + b[#]& $\endgroup$ – Kuba Nov 26 '16 at 12:48
  • $\begingroup$ @Kuba that is the obvious solution, but in my code a and b are being created in different parts, and when I create a I have no idea what b is going to be. $\endgroup$ – Vahagn Tumanyan Nov 26 '16 at 12:49
  • $\begingroup$ sorry, I misunderstood, a moment. It worked. Fantastic thank you. $\endgroup$ – Vahagn Tumanyan Nov 26 '16 at 12:50
  • 1
    $\begingroup$ Related: (28056) $\endgroup$ – Mr.Wizard Nov 26 '16 at 14:25
  • 1
    $\begingroup$ I am still trying to figure out why b[1] = 1 :| $\endgroup$ – polfosol Nov 27 '16 at 6:55
8
$\begingroup$

Haven't found a duplicate nor it is rtfm question so I will leave this cw answer:

c = a[#] + b[#]&

which should be clear but feel free to ask otherwise.

$\endgroup$
8
$\begingroup$

For simple expressions like a sum, there is Through. The following kind of use is shown in the docs:

a[3] + b[3]
Through[(a + b)[3]]
(*
  18
  18
*)

It works for simple homogeneous expressions like a + b or a * b, in which all the elements of level 1 are functions. To get a function as a result instead of a value, one can use # and & instead of 3 as shown below. One might use Evaluate to evaluate the body. Beware that symbolic parameters would have their values substituted, if any, when Evaluate is used. One can see from the output below that the unevaluated construction still depends on the definitions of a and b, and in the evaluated construction, we have a definite function that does not depend on any external values or definitions. One should consider which is most appropriate in a given use case.

c = Through[(a + b)[#]] &
c = Evaluate@Through[(a + b)[#]] &
(*
  Through[(a + b)[#1]] &
  6 + #1 + #1^2 &
*)

Sometimes it happens that a more complicated combination of functions is desired. Let's say the expression has been generated programmatically, either in the symbolic form 1 + 5 x + y^2 or more awkwardly in the form 1 + 5 a + b^2, with the Function expressions substituted

1 + 5 a + b^2
(*  1 + 5 (#1 + 3 &) + (#1^2 + 3 &)^2  *)

Then ReplaceAll (/.) will be your friend. Again the same advantages and disadvantages of Evaluate should be considered.

1 + 5 a + b^2 /. {a -> a[3], b -> b[3]}
(*  175  *)

c = 1 + 5 a + b^2 /. {a -> a[#], b -> b[#]} &
c = Evaluate[1 + 5 a + b^2 /. {a -> a[#], b -> b[#]}] &
(*
  1 + 5 a + b^2 /. {a -> a[#1], b -> b[#1]} &
  1 + 5 (3 + #1) + (3 + #1^2)^2 &
*)

Here's a simple function that operates somewhat like Through on a functional expression (expr)[x]. A second argument specifies the functions to be replaced in the operation. They can be rules that substitute a function for a symbol. if it is Automatic, the expressions in Variables[expr] are treated as functions. (I was surprised Automatic works for expressions in terms of the OP's a and b, which are pure functions.)

plugin[expr_[x___], fns_: Automatic] := 
  expr /. Replace[
    Flatten[{fns} /. Automatic :> Variables[expr]], (* construct replacements:          *)
    {HoldPattern[f_ -> g_] :> f :> g[x],            (*   rule for f:  f :> plug into g  *)
     f_ :> f :> f[x]},                              (*   function f:  f :> plug into f  *)
    1];

Examples:

plugin[(1 + 5 a + b^2)[3]]                                (* Automatic substitution *)
(*  175  *)

Evaluate@plugin[(1 + 5 a + b^2)[#]] &                     (* Automatic substitution *)
(*  1 + 5 (3 + #1) + (3 + #1^2)^2 &  *)

Evaluate@plugin[(1 + 5 a + b^2)[#], {a, b}] &             (* Specified functions *)
(*  1 + 5 (3 + #1) + (3 + #1^2)^2 &  *)

Evaluate@plugin[(1 + 5 x + y^2)[#], {x -> a, y -> b}] &   (* Substitution via rules *)
(*  1 + 5 (3 + #1) + (3 + #1^2)^2 &  *)

Simplify@plugin[(x^2 + y^2)[t], {x -> Cos, y -> Sin}]
(*  1   *)

plugin[(x^2 - 3 y^2 + z)[u, v]]
(*  x[u, v]^2 - 3 y[u, v]^2 + z[u, v]  *)
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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