6
$\begingroup$

Suppose I have two functions $f,g:\mathbb{R}^2 \to \mathbb{R}^2$ and that I want to compute $g(f(x,y))$. As an example, let's take $f(x,y)=(x+y, x-y)$ and $g(x,y)=(y^2,x^2)$. Then, $g(f(1,2))=(1,9)$.

I have tried implementing this in Mathematica as follows.

f[x_, y_] = {x + y, x - y}

g[x_, y_] = {y^2, x^2}

g[f[1, 2]]

But instead of getting {1, 9} back, I'm getting g[{3, -1}]

If I change my definitions to f[{x_, y_}] = {x + y, x - y} and g[{x_, y_}] = {y^2, x^2}, I get the right thing back, but then I have to call g[f[{1, 2}]].

Is there a way to make this work without having to pass in curly braces to g[f[ ]]?

$\endgroup$

3 Answers 3

7
$\begingroup$

You must use SetDelayed (:=) in your function definitions

Without the curly braces:

Clear[f, g]

f[x_, y_] := {x + y, x - y}

g[x_, y_] := {y^2, x^2}

g @@ f[1, 2]

{1, 9}

Also:

Clear[f, g]

f[x_, y_] := {x + y, x - y}

Because Power is a listable function:

g[x_] := Reverse[x^2]

g[f[1, 2]]

{1, 9}

Or

g @ f[1, 2]

{1, 9}

$\endgroup$
2
  • $\begingroup$ Thank you. This seems to be the closest to what I want, with @@. (The power is not really part of what I want to do, it was just to have something relatively simple to work with) $\endgroup$ Commented Jun 16 at 18:03
  • $\begingroup$ Thank you for the acceptance :) $\endgroup$
    – eldo
    Commented Jun 16 at 18:07
3
$\begingroup$

but then I have to call g[f[{1, 2}]]

Why is that a problem? It's really the "right" way to do it. With your current definitions, your functions each map two arguments to a single output value (that happens to be a pair). So you're not going to be able to compose them directly.

But if you must, @eldo's suggestion of g @@ f[1, 2] is the most straightforward. But just for variety's sake...

(Apply[g]@*f)[1, 2]

...also works.

And you could also overload your functions:

f[x_, y_] := f[{x, y}];
f[{x_, y_}] := {x + y, x - y};
g[x_, y_] := g[{x, y}];
g[{x_, y_}] := {y^2, x^2};
$\endgroup$
1
  • $\begingroup$ The problem is code clarity. What I want to express is a function of two variables that has an output in R^2. Yes, it works with overloads, etc., but the goal is to have something natural to work with that does the right thing. $\endgroup$ Commented Jun 16 at 18:01
2
$\begingroup$
{#2^2, #1^2} & @@ {#1 + #2, #1 - #2} & @@ {1, 2}

(* {1, 9} *) 

Or

Function[{x, y}, {y^2, x^2}] @@ Function[{x, y}, {x + y, x - y}] @@ {1, 2}

(* {1, 9} *)

Or, perhaps:

Composition[{#2^2, #1^2} &, Sequence @@ {#1 + #2, #1 - #2} &][1, 2]

(* {1, 9} *)

In addition:

{#2^2, #1^2} &[#1 + #2, #1 - #2] &[1, 2]

(* {1,9} *)
$\endgroup$

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.