Avoid repeated calls to Interpolation

穿精又带淫゛_ 提交于 2019-12-09 16:50:20

问题


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.


回答1:


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.




回答2:


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, e.g.:

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




回答3:


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}]
]


来源:https://stackoverflow.com/questions/7781981/avoid-repeated-calls-to-interpolation

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!