0
$\begingroup$

*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

$\endgroup$
  • $\begingroup$ 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. $\endgroup$ – m_goldberg Aug 2 '17 at 10:11
  • 1
    $\begingroup$ You are probably after memoization. See, for example, tutorial/FunctionsThatRememberValuesTheyHaveFound $\endgroup$ – MikeLimaOscar Aug 2 '17 at 10:21
  • $\begingroup$ How large are the ranges for the sums? 10 elements? 1000? larger? $\endgroup$ – FalafelPita Aug 2 '17 at 13:10
  • $\begingroup$ 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 $\endgroup$ – Slava K. Aug 2 '17 at 13:28
1
$\begingroup$

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}}][[1]];
f[a_, b_, c_, d_] /; ! Equal[a, c + d] := 0;
$\endgroup$
  • $\begingroup$ 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. $\endgroup$ – Slava K. Aug 2 '17 at 13:31

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.