8

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

该函数取决于一个参数a,实际上它是一个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] 时构建插值!我将如何避免这种情况?

谢谢阅读。

4

3 回答 3

12

第一步是参数approxa

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那么内存可能会不足。approx可以通过将保存的值与另一个符号(cache在本例中)相关联来本地化所使用的缓存:

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 中的动态规划:如何自动定位和/或清除记忆函数的定义

于 2011-10-16T04:30:24.197 回答
6

尝试以下方式:

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

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

于 2011-10-16T04:34:38.707 回答
6

您可以使用我在您的 Mathematica 工具包中的内容中发布的CacheIndex的定义?. 使用此函数的一个好处是您可以缓存值或部分代码,而无需定义新函数(尽管我们在此与示例保持一致)。

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

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

然后,您可以使用 CacheIndex 删除缓存的插值值

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

我调整了我的 Cache 和 CacheIndex 函数,使它们与 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}]
]
于 2011-10-16T14:42:58.287 回答