The best way to construct a function with memory

前端 未结 2 1466
悲哀的现实
悲哀的现实 2020-11-28 21:13

Good day,

I have some very slooooow and complicated function, say f[x,y]. And I need to construct detailed ContourPlot of it. Moreover the

2条回答
  •  旧时难觅i
    2020-11-28 21:45

    The simplest and possibly most efficient way to do this is just to set up the cached values as special case definitions for your function. The lookup is fairly fast due to hashing.

    A function:

    In[1]:= f[x_, y_] := Cos[x] + Cos[y]
    

    Which points are used during a ContourPlot?

    In[2]:= points = Last[
       Last[Reap[
         ContourPlot[f[x, y], {x, 0, 4 Pi}, {y, 0, 4 Pi}, 
          EvaluationMonitor :> Sow[{x, y}]]]]];
    
    In[3]:= Length[points]
    
    Out[3]= 10417
    

    Set up a version of f with precomputed values for 10000 of the evaluations:

    In[4]:= Do[With[{x = First[p], y = Last[p]}, precomputedf[x, y] = f[x, y];], {p, 
       Take[points, 10000]}];
    

    In the above, you would use something like precomputedf[x, y] = z instead of precomputed[x, y] = f[x, y], where z is your precomputed value that you have stored in your external file.

    Here is the "else" case which just evaluates f:

    In[5]:= precomputedf[x_, y_] := f[x, y]
    

    Compare timings:

    In[6]:= ContourPlot[f[x, y], {x, 0, 4 Pi}, {y, 0, 4 Pi}]; // Timing
    
    Out[6]= {0.453539, Null}
    
    In[7]:= ContourPlot[precomputedf[x, y], {x, 0, 4 Pi}, {y, 0, 4 Pi}]; // Timing
    
    Out[7]= {0.440996, Null}
    

    Not much difference in timing because in this example f is not an expensive function.

    A separate remark for your particular application: Perhaps you could use ListContourPlot instead. Then you can choose exactly which points are evaluated.

提交回复
热议问题