避免重复调用 Interpolation

发布于 2024-12-10 07:16:48 字数 576 浏览 1 评论 0原文

我想在mathematica 中插入一个函数。

该函数依赖于参数a,实际上它是函数F的反函数,而函数F也依赖于a,所以我构建了我的近似值如下所示,

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

现在我可以简单地调用approx[x]来计算某个点的反函数。

相反,我想做这样的事情:定义一个带有参数的函数,

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

然后编写 G[x,a] 来评估该函数。否则,我将不得不对我感兴趣的所有参数重复插值,并且周围有很多变量。我尝试将 Interpolation[] 调用放入模块内,但每次我调用 G[x,a] 时都会构造插值!我该如何避免这种情况?

感谢您的阅读。

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

人疚 2024-12-17 07:16:48

第一步是用 a 参数化 approx

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

通过这个定义,G 可以这样定义:

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

但是,正如问题中所观察到的,这最终会在每次调用 G 时重建插值。避免这种情况的一种方法是使用记忆化重新定义 approx

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

现在,approx 将为任何给定的 a 保存插值函数,从而避免在后续中重建使用相同的 a 进行调用。当然,这会消耗内存,因此如果 a 有大量不同的值,那么内存可能会不足。可以通过将保存的值与另一个符号(本例中为 cache)关联来本地化 approx 使用的缓存:

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

使用此版本的 approx >,cache可以使用Block进行本地化,例如:

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

对于a的每个不同值,插值函数仍然临时存储,但现在那些保存的定义在Block之后发布退出。

有关 Mathematica 中具有内存的函数的更多信息,请参阅 SO 问题:

构建具有内存的函数的最佳方法

Mathematica 中的动态编程:如何自动本地化和/或清除记忆函数的定义

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

会发光的星星闪亮亮i 2024-12-17 07:16:48

尝试按照以下方式进行操作:

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 *)

您只会在第一次为 a 的每个特定值调用 G 时评估它。

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.

離人涙 2024-12-17 07:16:48

您可以使用我在 您的 Mathematica 工具包里有什么?。使用此函数的一个好处是,您可以缓存值或部分代码,而无需定义新函数(尽管我们在这里这样做是为了与示例保持一致)。

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

我添加 Pause[3] 只是为了清楚地表明,插值的定义在计算一次后会为每个 a 进行缓存。

然后,您可以使用我调整的 Cache 和 CacheIndex 函数来删除 CacheIndex 中缓存的插值值,

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

以使它们与使用块中定义的单独符号的 WReach 的想法兼容。这里不切实际的一件事是您必须为用作缓存的符号定义 Hold 属性,但这个想法仍然很有趣。

这是 CacheSymbol 的定义,

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

您可以使用以下指令测试此实现,在实际示例中,缓存将在块中定义。

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

这是 CacheSymbolIndex 的定义,

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

您可以使用以下指令测试此实现,在实际示例中,缓存将在块中定义。

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

与 WReach 的例子类似,我们会有

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

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}]
]
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文