Avoid repeated calls to Interpolation

I want to interpolate a function in mathematica.

The function depends on a parameter a , in fact it is the inverse of a function F which also depends on a , so I build my approximation as follows,

approx = Interpolation[Table[{F[0.1 n, a], 0.1 n}, {n, -100, 100}]]

now I can simply call approx[x] to evaluate the inverse function at a point.

Instead I would like to do something like this: Define a function which takes a parameter,

G[x_,a_] = "construct the interpolating function,
            and return the value of the function at x"

Then write G[x,a] to evaluate the function. Otherwise I would have to repeat the interpolation for all the parameters I am interested in and have lots of variables lying around. I have tried putting the Interpolation[] call inside a module but that just constructs the interpolation every time I call G[x,a]! How would I avoid this?

Thanks for reading.


Try something along these lines:

G[a_]:=G[a]=Interpolation[Table[{F[0.1 n, a], 0.1 n}, {n, -100, 100}]]

G[0.2]  (* particular value of G[a] *)

G[0.2][0.3] (* the value you want *)

You will only evaluate G the first time you call it for each particular value of a .


The first step is to parameterize approx with a :

approx[a_] := Interpolation[Table[{F[0.1 n,a],0.1 n},{n,-100,100}]]

With this definition, G can then be defined thus:

G[x_, a_] := approx[a][x]

But, as observed in the question, this ends up reconstructing the interpolation every time G is called. One way to avoid this is to redefine approx using memoization:

m: approx[a_] := m = Interpolation[Table[{F[0.1 n,a],0.1 n},{n,-100,100}]]

Now, approx will save the interpolation function for any given a , avoiding reconstruction in subsequent calls with the same a . Of course, this uses up memory so if there are a large number of distinct values of a then memory could run short. It is possible to localize the cache used by approx by associating the saved values with another symbol ( cache in this case):

approx[a_] := cache[a] /.
  _cache :> (cache[a] = Interpolation[Table[{F[0.1` n,a],0.1` n},{n,-100,100}]])

With this version of approx , cache can be localized using Block , eg:

Block[{cache}
, Table[G[x, a], {x, 0, 5}, {a, 0, 1, 0.1}]
]

The interpolation functions are still temporarily stored for each distinct value of a , but now those saved definitions are released after the Block exits.

For more information about functions with memory in Mathematica, see the SO questions:

The best way to construct a function with memory

Dynamic Programming in Mathematica: how to automatically localize and / or clear memoized function's definitions


You could use the definition of CacheIndex I posted in What is in your Mathematica tool bag?. One good thing about using this function is that you can cache values or portions of code without having to define a new function (although we do here to be in line with the example).

G[x_,a_] :=
   CacheIndex[a,
      Pause[3];
      Interpolation[Table[{F[0.1 n,a],0.1 n},{n,-100,100}]]
   ][x];

I added Pause[3] just to make it clear that the definition of Interpolation is cached for each a after it has been computed once.

You could then delete the cached Interpolation values in CacheIndex using

DeleteCachedValues[CacheIndex] (*or*) 
DeleteCachedValues[CacheIndex,1].

I adapted my Cache and CacheIndex functions to make them compatible with the idea of WReach of using a separate symbol defined in a Block. One thing not practical here is that you have to define Hold attributes to the symbol used as cache, but the idea is still interesting.

Here is the definition of CacheSymbol

SetAttributes[CacheSymbol,HoldAll];
CacheSymbol[cacheSymbol_,expr_]:=cacheSymbol[expr]/.(_cacheSymbol:>(cacheSymbol[expr]=expr));

You can test this implementation using the following instructions, in a real example cache would be defined in a Block.

ClearAll[cache]
SetAttributes[cache,HoldFirst] 
CacheSymbol[cache,Pause[3];2+2]
?cache
CacheSymbol[cache,Pause[3];2+2]

Here is the definition of CacheSymbolIndex

SetAttributes[CacheIndexSymbol,HoldAll];
CacheIndexSymbol[cacheSymbol_,index_,expr_]:=cacheSymbol[index,expr]/.(_cacheSymbol:>(cacheSymbol[index,expr]=expr));

You can test this implementation using the following instructions, in a real example cache would be defined in a Block.

ClearAll[cache] 
SetAttributes[cache,HoldRest]
CacheIndexSymbol[cache,2+2,Pause[3];2+2]
?cache
CacheIndexSymbol[cache,2+2,Pause[3];2+2]

and similarly to the example of WReach we would have

G[x_,a_] :=
   CacheIndexSymbol[cache,a,
      Print["Caching"];
      Interpolation[Table[{F[0.1 n,a],0.1 n},{n,-100,100}]]
   ][x]

Block[{cache}, 
   SetAttributes[cache,HoldRest];
   Table[G[x, a], {x, 0, 5}, {a, 0, 1, 0.1}]
]
链接地址: http://www.djcxy.com/p/35516.html

上一篇: 使用Mathematica收集/正确收集

下一篇: 避免重复调用Interpolation