我想在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]时都只构造插值!我怎么能避免这个?
感谢阅读。
答案 0 :(得分:12)
第一步是使用approx
参数化a
:
approx[a_] := Interpolation[Table[{F[0.1 n,a],0.1 n},{n,-100,100}]]
通过这个定义,可以定义G
:
G[x_, a_] := approx[a][x]
但是,正如在问题中所观察到的,每次调用G
时,这最终都会重建插值。避免这种情况的一种方法是使用memoization重新定义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问题:
答案 1 :(得分: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
。
答案 2 :(得分:6)
您可以使用我在What is in your Mathematica tool bag?中发布的 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}]
]