I have two questions.

So, I have a function g defined in terms of another function, f:

g[z_] := Product[f[z][[i]], { i, 1, Length [f[z] ] }];

My problem is that f[z_] takes a while to compute.

Question 1: When I call g, does it compute f twice?

Question 2: If so, is there a way to make it not do that?

Note: I simplified my code a little bit. g is actually defined in terms of two parameters, so I cannot generate a table of f and have it call the parts of the table.

  • 8
    $\begingroup$ g[z_]:=Times@@f[z] $\endgroup$ – ciao Aug 12 at 22:13
  • 2
    $\begingroup$ You cannot have a pattern object (e.g., z_) on the RHS of a function definition except in a rule. To avoid multiple evaluations use a Module, eg., g[z_] := Module[{ft = f[z]}, ...] $\endgroup$ – Bob Hanlon Aug 12 at 23:17
  • $\begingroup$ @BobHanlon sorry, that was a typo. $\endgroup$ – Descartes Before the Horse Aug 12 at 23:32
  • 1
    $\begingroup$ ciao gives a good example of how one can more simply write what you have shown in your answer, and it is thus likely more efficient—however, it all comes down to your f[z] definition. Are you using SetDelayed ( i.e., := ) or Set ( i.e., = )? In either case, you can use memoization to remember the values you have calculated for some f[z]. This looks something like: ...=f[z]=... where, before the ...=, you have either Set or SetDelayed and f[z_]. $\endgroup$ – CA Trevillian Aug 13 at 1:27

BobHanlon gives a good answer for 2. For question 1, Here's an easy way to test. Define f[z_] using Echo and have it return a known result. Then evaluate g[z].

In[1]:= f[z_]:=(Echo@"f[z] was called";{1,2,3});
In[2]:= g[z_]:=Product[f[z][[i]],{i,1,Length[f[z]]}];
In[3]:= g[1]
>>f[z] was called
>>f[z] was called
>>f[z] was called
f[z] was called
Out[3]= 6
| improve this answer | |
  • $\begingroup$ This is a neat way to profile, but couldn’t one also just use Trace? $\endgroup$ – CA Trevillian Aug 13 at 1:22
  • $\begingroup$ Sure, but Trace is not always easy to follow. Echo is simple. $\endgroup$ – Mat Aug 13 at 1:27
  • $\begingroup$ valid point. I don’t know my way around Echo & Trace is easy to apply after function definition occurs, rather than needing to insert it into the definition. Wood screw versus a machine screw maybe ;) $\endgroup$ – CA Trevillian Aug 13 at 1:30

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.