首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >在Mathematica中实现动态,不需要重复代码

在Mathematica中实现动态,不需要重复代码
EN

Stack Overflow用户
提问于 2012-02-12 21:06:03
回答 3查看 277关注 0票数 2

我试着创建三个独立的图,这段代码会给你一个想法:

代码语言:javascript
运行
复制
f[t_] := Sin[10 t] + Cos[15 t];
Slider[Dynamic[dx], {0.01, 1}]
var = Dynamic[Fourier[Table[f[t], {t, 0, 100, dx}]]];
ListLinePlot[Abs[var]]
ListLinePlot[Re[var]]
ListLinePlot[Im[var]]

这不会起作用,因为var还没有被计算,所以ListLinePlot/Abs/Re/Im不会将它识别为一个数字列表。Dynamic必须包装ListLinePlot。

用Dynamic works包装ListLinePlot和其他所有东西。但然后我必须计算傅立叶[表[...每个图一次。根据原则,我不想有这种重复的代码。

这是一种避免代码重复的方法,但不像我上面提出的不起作用的示例那样具有语义,而且它将所有系列放在一个图中,而不是放在三个单独的图中:

代码语言:javascript
运行
复制
Dynamic[
 ListLinePlot[
  (#[Fourier[
       Table[f[t], {t, 0, 100, dx}]
       ]]) & /@ {Abs,Re,Min}, DataRange -> {0, 100}
  ]
 ]

希望你现在能看到我想要实现的目标。类似于我的第一段代码,但它应该可以工作。我该怎么做呢?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2012-02-13 15:55:42

在大多数情况下,您只需要将需要重新计算的表达式包装成Dynamic即可。正如您所注意到的,如果您将Dynamic包装在var的内容中,它将无法工作,因为当您向ListPlot传递var时,它将看到一个Dynamic头,而不是列表。在这种情况下,需要重新计算的是完整的ListPlot

正确的解决方案是使用var的延迟定义(即:=而不是=),并将Dynamic包装在ListPlot周围

代码语言:javascript
运行
复制
f[t_] := Sin[10 t] + Cos[15 t];
Slider[Dynamic[dx], {0.01, 1}]

var := Fourier[Table[f[t], {t, 0, 100, dx}]];

Dynamic@ListLinePlot[Abs[var]]
Dynamic@ListLinePlot[Re[var]]
Dynamic@ListLinePlot[Im[var]]

人们经常对Dynamic感到困惑,因为它有时在表达式中表现得很深,例如在你的Slider示例中。但是Dynamic有一个不同的功能:设置一个值。

通常,除非用于设置值,否则Dynamic始终需要是表达式中最外层的头部。(有一些例外,特别是当我们处理的表达式直接对应于屏幕上显示的内容,并由前端处理时,例如图形基元:Slider[Dynamic[x], {0, 5}]Graphics[{Disk[], Dynamic@Disk[{x, 0}]}]将起作用。)

Dynamic只会影响表达式在前端的显示方式,而不会影响内核看到它们的方式。下面是一个例子:

代码语言:javascript
运行
复制
x=1
arr = {Dynamic[x], 2, 3}

前端将arr显示为{1, 2, 3},但内核仍将其视为{Dynamic[x], 2, 3}。因此,如果我们计算Total[arr],前端会将其显示为1 + 5,但内核将看到if为Dynamic[x] + 5。我希望这能澄清一点情况。

注意:我不想在这个解决方案中使用Manipulate,因为OP也没有使用它。Manipulate只是一个高级的、方便的函数,它所做的一切都可以通过Dynamic和一些控件来实现,比如Slider

票数 4
EN

Stack Overflow用户

发布于 2012-02-12 22:01:35

你可能想要这样的东西:

代码语言:javascript
运行
复制
f[t_] := Sin[10 t] + Cos[15 t]

DynamicModule[{var},
 Manipulate[
  var = Fourier[Table[f[t], {t, 0, 100, dx}]];
  {ListLinePlot[Abs[var]],
   ListLinePlot[Re[var]],
   ListLinePlot[Im[var]]},
  {dx, 0.01, 1}
]]

票数 2
EN

Stack Overflow用户

发布于 2012-02-12 21:18:27

未经测试:

代码语言:javascript
运行
复制
f[t_] := Sin[10 t] + Cos[15 t];
Slider[Dynamic[dx], {0.01, 1}]
Dynamic[var = Fourier[Table[f[t], {t, 0, 100, dx}]]];
Dynamic[ListLinePlot[Abs[var]]]
Dynamic[ListLinePlot[Re[var]]]
Dynamic[ListLinePlot[Im[var]]]

我认为这应该只计算一次Fourier。根据我的理解,ListLinePlots应该是在计算Fourier之后由var的变化触发的(注意,var的赋值是在Dynamic内部进行的)。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/9249020

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档