0
$\begingroup$

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.

$\endgroup$
4
  • 8
    $\begingroup$ g[z_]:=Times@@f[z] $\endgroup$
    – ciao
    Aug 12, 2020 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, 2020 at 23:17
  • $\begingroup$ @BobHanlon sorry, that was a typo. $\endgroup$ Aug 12, 2020 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$ Aug 13, 2020 at 1:27

1 Answer 1

4
$\begingroup$

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
$\endgroup$
3
  • $\begingroup$ This is a neat way to profile, but couldn’t one also just use Trace? $\endgroup$ Aug 13, 2020 at 1:22
  • $\begingroup$ Sure, but Trace is not always easy to follow. Echo is simple. $\endgroup$
    – Mat
    Aug 13, 2020 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$ Aug 13, 2020 at 1:30

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.