Pre-evaluating functions and referencing them after

*Edited version

Hi all,

Suppose I have a certain function:

g[aa_, bb_, cc_, dd_] :=
Sum[Sum[Sum[Sum[If[a == c + d, f[a, b, c, d], 0],
{d, dd}], {c, cc}], {b, bb}], {a, aa}]

where individual elements of f take a verly long time to compute. I want to pre-compute them beforehand, and then apply their result in function g. What I can use is:

ff = Table[f[a, b, c, d], {a, aa}, {b, bb}, {c, cc}, {d, dd}];
gnew[aa_, bb_, cc_, dd_] :=
Sum[Sum[Sum[Sum[If[a == c + d, ff[[a, b, c, d]], 0],
{d, dd}], {c, cc}], {b,bb}], {a, aa}]

i.e take values from a table where the position the value I want in the table corresponds to input parameters of f. However it is highly inefficient, as I my If condition renders a good portion of that table to be useless and with f computationally expensive I want to avoid computing these terms. What I thought of doing was to run an initial loop collecting input indicies I would need and computing f at those only:

invals = {}

Do[Do[Do[Do[
If[a == c + d,
If[MemberQ[invals, {a, b, c, d}], 0,
invals = Append[invals, {a, b, c, d}]]
, 0]
, {d, dd}]
, {c, cc}]
, {b, bb}]
, {a, aa}]

tab = f @@@ invals;

The issue I have now though, is that I cannot simply relate elements of tab to specific f[a, b, c, d] that I call in function g. What would be an optimal solution to this problem?

A thing to keep in mind is that the actual function g I have has 11 summations, not 4, calls multiple functions I want to pre-calculate most of which are time-expensive and the condition If is a little more complicated than that, which is why it is critical to me to pre-calculate their values, and apply them later.

I'd like to also mention that I will run this program on a server with 8 cores. So what I'd ideally like to do, is to have separate programs (notebooks) generating these arrays and saving them to a separate files, and a separate program accessing that file and plugging it into the summation.

Thank you

• This question is too vague as it now stands. Please frame it in terms of a specific example and show the Mathematica code for the example. – m_goldberg Aug 2 '17 at 10:11
• You are probably after memoization. See, for example, tutorial/FunctionsThatRememberValuesTheyHaveFound – MikeLimaOscar Aug 2 '17 at 10:21
• How large are the ranges for the sums? 10 elements? 1000? larger? – FalafelPita Aug 2 '17 at 13:10
• The actual function has 6 inputs which define ranges of 6 of the sums, the rest are calculated as combinations of these 6 variables and the iterators of the previous sums. The first two inputs are fixed at 20, the others I will have to play around with such that the time of computation is not unreasonable – Slava K. Aug 2 '17 at 13:28

As @MikeLimaOscar mentioned in the comments, you could memoize the down-values of f for which it is non-zero.

f[a_, b_, c_, d_] /; Equal[a, c + d] :=
f[a, b, c, d] = 1 (*replace with function definition*);
f[a_, b_, c_, d_] /; ! Equal[a, c + d] := 0;

g[aa_, bb_, cc_, dd_] :=
Sum[Sum[Sum[Sum[f[a, b, c, d],
{d, dd}], {c, cc}], {b, bb}], {a, aa}]

Update

As for calculating the results in advance, taking advantage of parallelization, and saving them to a file, how about

Clear[possInputTab, posOfNeeded, neededInputTab, fOfList, makeRule,
fAssoc];
possInputTab =
Table[{a, b, c, d}, {a, aMin, aMax}, {b, bMin, bMax}, {c, cMin,
cMax}, {d, dMin, dMax}];
needValQ[{a_, b_, c_, d_}] := Equal[a, c + d];
posOfNeeded = Position[possInputTab, _?needValQ];
neededInputTab = Extract[possInputTab, posOfNeeded];

fOfList[{a_, b_, c_, d_}] := a + b/c*d;(*function definition here*);
makeRule = (# -> fOfList[#] &);

fAssoc = Association[
ParallelCombine[
makeRule /@ # &,
neededInputTab,
Join]
];

DumpSave["(*path and file name*).mx", fAssoc];

Then, to use the results

Get["(*path and file name*).mx"]
f[a_, b_, c_, d_] /; Equal[a, c + d] := Lookup[fAssoc, {{a, b, c, d}}][];
f[a_, b_, c_, d_] /; ! Equal[a, c + d] := 0;
• I can execute my task on a server with 8 cores available. I'd like to parallelize the computation lists/arrays of values of f[a,b,c,d] save their results to a file, and then in a separate program use these results in the fat sum. – Slava K. Aug 2 '17 at 13:31