Wolfram mathematica 避免重复调用插值

Wolfram mathematica 避免重复调用插值,wolfram-mathematica,mathematica-8,Wolfram Mathematica,Mathematica 8,我想在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,

我想在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]时,这只会构造插值!我该如何避免这种情况


谢谢你的阅读

第一步是使用
a
参数化
近似值

approx[a_] := Interpolation[Table[{F[0.1 n,a],0.1 n},{n,-100,100}]]
根据此定义,
G
可以这样定义:

G[x_, a_] := approx[a][x]
但是,正如在问题中所观察到的,每次调用
G
时都会重建插值。避免这种情况的一种方法是使用备忘录重新定义
近似值

m: approx[a_] := m = Interpolation[Table[{F[0.1 n,a],0.1 n},{n,-100,100}]]
现在,
approx
将为任何给定的
a
保存插值函数,避免在后续调用中使用相同的
a
进行重建。当然,这会占用内存,因此如果
a
有大量不同的值,那么内存可能会不足。通过将保存的值与另一个符号相关联(
cache
在这种情况下),可以定位
appro
使用的缓存:

使用此版本的
近似值
缓存
可以使用
进行本地化,例如:

Block[{cache}
, Table[G[x, a], {x, 0, 5}, {a, 0, 1, 0.1}]
]
插值函数仍然临时存储为
a
的每个不同值,但现在在
块退出后,这些保存的定义被释放

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


尝试以下方法:

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
时对其求值。您可以使用我发布的缓存索引的定义。使用此函数的一个好处是,您可以缓存值或部分代码,而无需定义新函数(尽管我们在这里这样做是为了与示例保持一致)

我添加了Pause[3]只是为了明确插值的定义在计算一次后,会缓存每个a

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

DeleteCachedValues[CacheIndex] (*or*) 
DeleteCachedValues[CacheIndex,1].
我调整了Cache和CacheIndex函数,使它们与使用块中定义的单独符号的花环思想兼容。这里不实用的一点是,您必须为用作缓存的符号定义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]
ClearAll[cache] 
SetAttributes[cache,HoldRest]
CacheIndexSymbol[cache,2+2,Pause[3];2+2]
?cache
CacheIndexSymbol[cache,2+2,Pause[3];2+2]
以下是CacheSymbolIndex的定义

SetAttributes[CacheIndexSymbol,HoldAll];
CacheIndexSymbol[cacheSymbol_,index_,expr_]:=cacheSymbol[index,expr]/.(_cacheSymbol:>(cacheSymbol[index,expr]=expr));
您可以使用以下指令测试此实现,在一个实际示例中,缓存将在块中定义

ClearAll[cache]
SetAttributes[cache,HoldFirst] 
CacheSymbol[cache,Pause[3];2+2]
?cache
CacheSymbol[cache,Pause[3];2+2]
ClearAll[cache] 
SetAttributes[cache,HoldRest]
CacheIndexSymbol[cache,2+2,Pause[3];2+2]
?cache
CacheIndexSymbol[cache,2+2,Pause[3];2+2]
类似于花环的例子,我们会有

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

与提供的其他方法相比,此方法似乎是最简单的方法。在其他答案中所描述的显式缓存上,可能会有一个对该方案的回退。但我不是足够的专家,不知道其中的区别。其他的答案是关于当缓存符号变得太大时如何释放存储在缓存符号中的内存。这些缓存的想法与此答案中的相同。如果您的代码不是太占用内存,那么不必真正关心释放当前会话的内存,但是如果您进行大型计算,它可能会很有用。谢谢您的回答,它激励我去学习更多的mathematica!