Wolfram mathematica 是否可以在Sow';或者必须等待它收获';预计起飞时间?

Wolfram mathematica 是否可以在Sow';或者必须等待它收获';预计起飞时间?,wolfram-mathematica,Wolfram Mathematica,我一直在学习播种/收获。它们是很酷的构造。但我需要帮助,看看我是否可以使用它们来做我将在下面解释的事情 我想做的是:在运行时绘制NDSolve的解决方案。我想我可以使用Sow[]收集解决方案(x,y[x]),因为NDSolve使用EvaluationMonitor运行。但我不想等到最后,收获它,然后绘制解决方案,而是想在它运行时执行它 我将展示基本的设置示例 max = 30; sol1 = y /. First@NDSolve[{y'[x] == y[x] Cos[x + y[x]],

我一直在学习播种/收获。它们是很酷的构造。但我需要帮助,看看我是否可以使用它们来做我将在下面解释的事情

我想做的是:在运行时绘制
NDSolve
的解决方案。我想我可以使用
Sow[]
收集解决方案(x,y[x]),因为
NDSolve
使用
EvaluationMonitor
运行。但我不想等到最后,
收获它,然后绘制解决方案,而是想在它运行时执行它

我将展示基本的设置示例

max = 30;
sol1 = y /. 
   First@NDSolve[{y'[x] == y[x] Cos[x + y[x]], y[0] == 1}, 
     y, {x, 0, max}];
Plot[sol1[x], {x, 0, max}, PlotRange -> All, AxesLabel -> {"x", "y[x]"}]

使用Reap/Sow,可以收集数据点,并在最后绘制解决方案,如下所示

sol = Reap[
    First@NDSolve[{y'[x] == y[x] Cos[x + y[x]], y[0] == 1}, 
      y, {x, 0, max}, EvaluationMonitor :> Sow[{x, y[x]}]]][[2, 1]];

ListPlot[sol, AxesLabel -> {"x", "y[x]"}]
Remove["Global`*"];
max = 30;
sol = Reap[
    First@NDSolve[{y'[x] == y[x] Cos[x + y[x]], y[0] == 1}, 
      y, {x, 0, max}, EvaluationMonitor :> Sow[{x, y[x]}]]][[2, 1]];
idx = 1;
Dynamic[idx];
Dynamic[ListPlot[sol[[1 ;; idx]], Joined -> False, 
  PlotRange -> {{0, max}, All}, AxesLabel -> {"x", "y[x]"}]]

Do[++idx; Pause[0.01], {i, 1, Length[sol] - 1}]

好的,到目前为止还不错。但是我想要的是访问部分正在构建的列表,因为它通过
Sow
累积并绘制解决方案。我所知道的唯一一个设置是动态
ListPlot
,当其数据更改时刷新。但我不知道如何使用Sow将部分构建解决方案移动到此数据,以便
ListPlot
更新

我将展示我在没有Sow的情况下是如何做到这一点的,但是您可以看到,我在下面使用了
appeedto[]

ClearAll[x, y, lst];
max = 30;
lst = {{0, 0}};
Dynamic[ListPlot[lst, Joined -> False, PlotRange -> {{0, max}, All}, 
  AxesLabel -> {"x", "y[x]"}]]

NDSolve[{y'[x] == y[x] Cos[x + y[x]], y[0] == 1}, y, {x, 0, max}, 
 EvaluationMonitor :> {AppendTo[lst, {x, y[x]}]; Pause[0.01]}]

我正在考虑一种方法,通过Sow访问部分构建列表,并使用它来刷新绘图,前提是这可能比
AppendTo[]更有效。

我不能这么做:

ClearAll[x, y, lst];
max = 30;
lst = {{0, 0}};
Dynamic[ListPlot[lst, Joined -> False, PlotRange -> All]]

NDSolve[{y'[x] == y[x] Cos[x + y[x]], y[0] == 1}, y, {x, 0, max}, 
 EvaluationMonitor :> {lst = Reap[Sow[{x, y[x]}] ][[2, 1]]; Pause[0.01]}]
因为它现在播种一点,收获一点,所以我只是一次规划一点。就像我刚才做的一样:

NDSolve[{y'[x] == y[x] Cos[x + y[x]], y[0] == 1}, y, {x, 0, max}, 
 EvaluationMonitor :> {lst = Sow[{x, y[x]}]; Pause[0.01]}]
我的问题是,如何在上面使用Sow/Reap,以避免我在这种情况下使用AppendTo来管理lst。(或者使用表进行预分配,但我不知道要分配的大小),因为我假设播种/收获可能更有效?

附言:如果
eaw
可以选择告诉它
eaw
通过
Sow
积累的内容,但不要将其从迄今为止播下的内容中移除,那该多好啊。就像一个被动的收获。嗯,只是一个想法

谢谢

更新时间:上午8:30

谢谢你的回答和评论。我只是想说,问这个问题的主要目的只是想看看是否有一种方法可以在播种时访问部分数据。我需要看更多的
,我以前没有用过

顺便说一句,上面所示的例子,只是给出了这样一种需求可能出现的背景。如果我想在这个特定的情况下模拟解决方案,我甚至不必像以前那样去做,我可以先获得解决方案数据,然后再制作动画

因此,我甚至不需要担心缓冲区的分配,也不需要使用
appeedto
。但在许多其他情况下,由于Sow正在积累数据,访问这些数据可能会更容易。这个例子正是我目前所拥有的

要更直接地执行此特定示例,可以简单地使用
动画[]
,后缀,如下所示:

Remove["Global`*"];
max = 30;
sol = Reap[
    First@NDSolve[{y'[x] == y[x] Cos[x + y[x]], y[0] == 1}, 
      y, {x, 0, max}, EvaluationMonitor :> Sow[{x, y[x]}]]][[2, 1]];

Animate[ListPlot[sol[[1 ;; idx]], Joined -> False, 
  PlotRange -> {{0, max}, All}, AxesLabel -> {"x", "y[x]"}], {idx, 1, 
  Length[sol], 1}]
或者,甚至制作一个国产动画,就像这样

sol = Reap[
    First@NDSolve[{y'[x] == y[x] Cos[x + y[x]], y[0] == 1}, 
      y, {x, 0, max}, EvaluationMonitor :> Sow[{x, y[x]}]]][[2, 1]];

ListPlot[sol, AxesLabel -> {"x", "y[x]"}]
Remove["Global`*"];
max = 30;
sol = Reap[
    First@NDSolve[{y'[x] == y[x] Cos[x + y[x]], y[0] == 1}, 
      y, {x, 0, max}, EvaluationMonitor :> Sow[{x, y[x]}]]][[2, 1]];
idx = 1;
Dynamic[idx];
Dynamic[ListPlot[sol[[1 ;; idx]], Joined -> False, 
  PlotRange -> {{0, max}, All}, AxesLabel -> {"x", "y[x]"}]]

Do[++idx; Pause[0.01], {i, 1, Length[sol] - 1}]
小的后续问题:现在是否可以使用
内部“包”
?由于它位于
内部环境中,是否有可能被删除/更改/etc。。。将来,破译一些代码?我似乎记得在某个地方读到过这样的文章,说这不太可能,但我觉得在
内部环境中使用某些东西并不舒服。如果我们可以使用它,那么为什么它是在内部上下文中呢

(在数学方面需要学习的东西太多,时间太少)


谢谢,

实验表明,
内部“包”和链接列表都比使用
附件要慢。考虑到这一点,我想起了萨沙告诉我的,列表(数组)的创建需要时间

因此,无论是上述方法,还是在每个步骤将结果收集为列表的
Sow
/
Reap
,都不会比
附录
更有效(事实上,效率更低)

我相信在本机Mathematica构造中,只有数组预分配可以更快

以下为旧答案供参考:


我相信这是放置
内部“袋子”
内部“填充袋”
内部“袋子零件”
的地方

我不得不求助于一种笨拙的双变量方法,因为
Bag
内部的
Dynamic
似乎没有按照我预期的方式更新

ClearAll[x, y, lst];
max = 30;
bag = Internal`Bag[];
lst = {{}};

Dynamic@ListPlot[lst, Joined -> False, PlotRange -> All]

NDSolve[{y'[x] == y[x] Cos[x + y[x]], y[0] == 1}, y, {x, 0, max}, 
 EvaluationMonitor :> {Internal`StuffBag[bag, {x, y[x]}];
                       lst = Internal`BagPart[bag, All];
                       Pause[0.01]}
]

您的
版本有什么问题?它似乎与纳赛尔在8.0.4+1版中的
AppendTo
方法一样有效<代码>内部'包
也是我在这里使用的。顺便说一句,AFAIK、eaw`和
Sow
是使用
Internal`Bag
在内部实现的。@Leonid,
AppendTo
不是更好的选择吗<在我的测试中,code>BagPart[bag,All]
AppendTo[lst,x]
慢,那么为什么要使用它呢?@Mr.Wizard可能你是对的,我没有测试。我希望行李更快,但这是一个特例,因为在每一步中,都会查询整个累积列表。另一种选择是,你可以构造一个自定义绘图函数,它只需要最后一点来更新绘图-我认为这应该是可能的。@Leonid我喜欢这个想法。如果你有时间的话,我建议你实现它(我没有)。你认为为
Sow
使用标记,并结合
eaw
的第二个和第三个参数可能会奏效吗?@kguler,好主意,但决不考虑。我刚开始学习播种/收获,但会研究你的建议。谢谢,我认为你的后续问题值得一贴。我可能没有时间回应,但我没有一个明确的答案。