3
$\begingroup$

Suppose I have defined a numerical function F[x] that for each entry x, it takes a long time to calculate.

Suppose that now I want to define a new function using the previous one, say, G[x_] := F[x]^2 + 2*F[x] + 1.

My first question is, does Wolfram Mathematica calculate twice the value of F[x] to use it in G[x]? that is, first calculate the F[x] for F[x]^2 and then the F[x] for the 2*F[x]?

And if this is the case, how could I improve the way I define G[x] so that it only calculates F[x] once?

$\endgroup$
1
  • 1
    $\begingroup$ You can use memoization to evaluate it only once (F[x_] := F[x] = ...). $\endgroup$ Commented Oct 17, 2019 at 10:50

2 Answers 2

6
$\begingroup$

Yes, putting the function call in twice will cause it to be evaluated twice. You can visualize this by putting a Print inside the function, for example:

f[x_] := (Print["In f"]; x)

g[x_] := f[x]^2 + 2*f[x] + 1

g[2]
 (* In f *)
 (* In f *)
 (* 2    *)

You can see that it went to f twice. To avoid that, you can assign a temp variable:

g2[x_] := Module[{t = f[x]}, t^2 + 2*t + 1]

g2[2]
 (* In f *)
 (* 2    *)

Changing f to something slow, to illustrate the difference in timing:

f[a_] := NIntegrate[{Sin[x + y]/(1 + x^4 + y^4), (Sin[x] + Cos[y])/(
   1 + x^4 + y^4)}, {x, 0, \[Infinity]}, {y, 0, \[Infinity]}]

g[1] // AbsoluteTiming
 (* {22.6585, {3.56334, 6.79898}} *)
g2[1] // AbsoluteTiming
 (* {11.2694, {3.56334, 6.79898}} *)
$\endgroup$
5
  • $\begingroup$ With instead of Module can give additional speed-up. $\endgroup$ Commented Oct 17, 2019 at 2:12
  • $\begingroup$ @Alx With RepeatedTiming I get exactly the same answer using g3[x_] := With[{t = f[x]}, t^2 + 2*t + 1] and g2[x_] := Module[{t = f[x]}, t^2 + 2*t + 1]. Is there a better way to write it? $\endgroup$ Commented Oct 17, 2019 at 3:23
  • $\begingroup$ I meant general advice to use With as it does just direct replacement and does not create additional variables $smth like Module. But you are right, in this case there is no difference. $\endgroup$ Commented Oct 17, 2019 at 4:45
  • $\begingroup$ WOW it never clicked until now! WHAT! This is AN AWESOME ANSWER👏 $\endgroup$ Commented Oct 18, 2019 at 23:04
  • $\begingroup$ @CATrevillian Thanks! $\endgroup$ Commented Oct 19, 2019 at 21:26
4
$\begingroup$

You could do something like

G[x_] := a^2 + 2 a + 1 /. a -> F[x]

or

G[x_] := #^2 + 2 # + 1 &@F[x]
$\endgroup$

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.