mar*_*ark 8 wolfram-mathematica mathematica-8
我想在mathematica中插入一个函数.
函数取决于一个参数a
,实际上它是一个函数的反函数F
,它也取决于a
,所以我建立我的近似如下,
approx = Interpolation[Table[{F[0.1 n, a], 0.1 n}, {n, -100, 100}]]
Run Code Online (Sandbox Code Playgroud)
现在我可以简单地调用一点approx[x]
来评估反函数.
相反,我想做这样的事情:定义一个带参数的函数,
G[x_,a_] = "construct the interpolating function,
and return the value of the function at x"
Run Code Online (Sandbox Code Playgroud)
然后写G [x,a]来评估函数.否则我将不得不为我感兴趣的所有参数重复插值并且有很多变量.我已经尝试将Interpolation []调用放在一个模块中,但每次调用G [x,a]时都只构造插值!我怎么能避免这个?
谢谢阅读.
WRe*_*ach 12
第一步是参数化approx
与a
:
approx[a_] := Interpolation[Table[{F[0.1 n,a],0.1 n},{n,-100,100}]]
Run Code Online (Sandbox Code Playgroud)
有了这个定义,G
就可以这样定义:
G[x_, a_] := approx[a][x]
Run Code Online (Sandbox Code Playgroud)
但是,正如在问题中所观察到的,这最终会在每次G
调用时重建插值.避免这种情况的一种方法是approx
使用memoization 重新定义:
m: approx[a_] := m = Interpolation[Table[{F[0.1 n,a],0.1 n},{n,-100,100}]]
Run Code Online (Sandbox Code Playgroud)
现在,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}]])
Run Code Online (Sandbox Code Playgroud)
有了这个版本approx
,cache
可以使用本地化Block
,例如:
Block[{cache}
, Table[G[x, a], {x, 0, 5}, {a, 0, 1, 0.1}]
]
Run Code Online (Sandbox Code Playgroud)
插值函数仍然为每个不同的值临时存储a
,但现在这些已保存的定义在Block
退出后释放.
有关Mathematica中带内存函数的更多信息,请参阅SO问题:
Mathematica中的动态编程:如何自动定位和/或清除memoized函数的定义
尝试这些方面:
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 *)
Run Code Online (Sandbox Code Playgroud)
您只会G
在第一次为每个特定值调用它时进行评估a
.
您可以使用我在Mathematica工具包中的内容中发布的CacheIndex的定义?.使用此函数的一个好处是,您可以缓存值或代码的一部分,而无需定义新函数(尽管我们这里做的是与示例一致).
G[x_,a_] :=
CacheIndex[a,
Pause[3];
Interpolation[Table[{F[0.1 n,a],0.1 n},{n,-100,100}]]
][x];
Run Code Online (Sandbox Code Playgroud)
我添加了Pause [3]只是为了清楚地表明Interpolation的定义是在计算一次之后为每个a缓存的.
然后,您可以使用缓存删除CacheIndex中的缓存插值
DeleteCachedValues[CacheIndex] (*or*)
DeleteCachedValues[CacheIndex,1].
Run Code Online (Sandbox Code Playgroud)
我调整了我的Cache和CacheIndex函数,使它们与WReach使用块中定义的单独符号的想法兼容.这里不实用的一件事是你必须为用作缓存的符号定义Hold属性,但这个想法仍然很有趣.
这是CacheSymbol的定义
SetAttributes[CacheSymbol,HoldAll];
CacheSymbol[cacheSymbol_,expr_]:=cacheSymbol[expr]/.(_cacheSymbol:>(cacheSymbol[expr]=expr));
Run Code Online (Sandbox Code Playgroud)
您可以使用以下指令测试此实现,在实例中,将在块中定义缓存.
ClearAll[cache]
SetAttributes[cache,HoldFirst]
CacheSymbol[cache,Pause[3];2+2]
?cache
CacheSymbol[cache,Pause[3];2+2]
Run Code Online (Sandbox Code Playgroud)
这是CacheSymbolIndex的定义
SetAttributes[CacheIndexSymbol,HoldAll];
CacheIndexSymbol[cacheSymbol_,index_,expr_]:=cacheSymbol[index,expr]/.(_cacheSymbol:>(cacheSymbol[index,expr]=expr));
Run Code Online (Sandbox Code Playgroud)
您可以使用以下指令测试此实现,在实例中,将在块中定义缓存.
ClearAll[cache]
SetAttributes[cache,HoldRest]
CacheIndexSymbol[cache,2+2,Pause[3];2+2]
?cache
CacheIndexSymbol[cache,2+2,Pause[3];2+2]
Run Code Online (Sandbox Code Playgroud)
和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}]
]
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
735 次 |
最近记录: |