我想问是否有人知道任何问题(性能或其他),如果要定义/放置 Manipulate 表达式使用的模块,就在 Manipulate 表达式本身内部,而不是在初始化部分,通常是在哪里完成的。
两种方法都有效,但是当涉及到从模块直接访问 Manipulatedynamics 时,语义并不相同(相对于它们作为参数传递给模块,这实际上是更好的方法,但我现在正在尝试一些东西)
我不知道这些东西是如何实现的,但我担心如果我把所有模块都放在Manipulate表达式中,那么当有很多模块时Manipulate会变慢,因为每次需要刷新表达式时,Mathematica FE 将向内核发送一个现在更大的表达式来重新评估/解析或任何正确的术语。
现在刷新的 Manipulate 表达式现在要大得多,因为模块现在是 Manipulate 表达式本身的一部分,而不是在初始化部分中,即使其中一些模块可能不会在每次刷新中调用,也会发生这种情况。
为了帮助更多地解释这个问题,我在下面制作了一个小图来展示我的意思,并排比较这两种方法。下面,我还放置了图中使用的小代码示例:
表达式部分方法的代码
Manipulate[
foo[]:=Module[{},
x++
];
ctrl;
foo[],
Button["step",{ctrl++ }],
{{ctrl,0},None},
{{x,0},None},
TrackedSymbols:>{ctrl}
]
模块初始化方法的代码
Manipulate[
ctrl;
foo[],
Button["step", {ctrl++ }],
{{ctrl, 0}, None},
{{x, 0}, None},
TrackedSymbols :> {ctrl},
Initialization :>
{
foo[] := Module[{},
x++
]
}
]
问题是:modules-inside-manipulate 表达式方法会影响性能吗?
添加注释:
顺便说一句,在我当前的小型演示中,我没有注意到这两种方法有任何性能差异,但这只是基于观察演示的响应,没有精确的测量。可能我对 Manipulate 初始化部分的理解一直不正确。从帮助中可以看出:
Initialization is an option for Dynamic, DynamicModule, Manipulate,
and related constructs that specifies an expression to be evaluated when
the construct is first used or displayed.
看来我对它的理解可能与它的含义不同。
也许 Manipulate 每次都会评估所有模块,作为其表达式刷新/更新的一部分?
不管怎样,如果这两种布局没有性能差异,我会很高兴,因为从现在开始,我将把所有模块放在 Manipulate 表达式本身中,而不是放在初始化部分中。
补充 2001 年 12 月 19 日 11 点我查看了下面发布的向导先生解决方案。据我所知,查看 Manipulate 快照,生成的代码相当于显式地将模块放入 Manipulate 表达式中。下面的屏幕截图显示了两种方法以及每个布局的结果代码(通过使用快照选项按钮由 Manipulate 函数生成)。我们可以看到这是相同的代码。
但是Mr Wizard使用的技巧是允许将函数放在Control->None中,即只写foo
代替foo[]
这是我没想到的。我一直认为一个人必须写foo[]:=Module[...]
即使foo
不接受任何争论。 (实际上我从来没有想过,即使不带参数,我也很自然地在每个函数名的末尾写上 [] )。感谢您分享这个技巧。