ListPlot是Mathematica而不存储列表

时间:2012-02-28 06:16:59

标签: wolfram-mathematica

我正在寻找一种在不存储实际数据的情况下生成和绘制数据的方法。作为一个基本的例子:

list = {}; idim = 40; ndiag = 100; grpSize = 4; m = idim/grpSize;
For[rank = 0, rank < grpSize, rank++,
 For[j = rank*m, j < (rank + 1)*m, j++,
  For[k = 0, k < ndiag, k++,
   For[l = 0, l < ndiag, l++,
    AppendTo[list, {k + ndiag*j, l + ndiag*j}]
    ]]]]
ListPlot[list]

实际上,这需要相当长的时间。大概是因为必须存储的列表的不断添加。它开始很快,但随着列表变长,它会变慢。我真的只想看到填充的模式。有没有办法避免存储列表,只是一次一个地添加点到情节?它没有显示它更新,一个完成它的情节很好。编辑:我确实找到了Reap and Sow,它确实对速度问题有所帮助,但出于纯粹的好奇心,我仍然想知道如何避免存储数据(除了情节)。

2 个答案:

答案 0 :(得分:2)

在开始与动画情节之类的摔跤之前,我建议你重新编写生成数据集的行。您已经使用Mathematica编写了似乎是C程序的内容,并选择了创建数据列表的最慢方法。

我没有在这台机器上使用Mathematica,所以没有测试以下内容,但是有一个声明:

tabl = Table[{k + ndiag*j, l + ndiag*j}, {l,0,ndiag-1},{k,0,ndiag-1},{j,rank*m,(rank+1)*m},{rank,0,grpSize-1}]

将比你的循环嵌套运行得更快(我的意思是,更快)。你会发现Table执行的输出需要一点Flatten - ing。顺便说一下,我还注意到Mathematica使用1作为索引库比使用0更自然。

我认为您确定使用Append作为使代码变慢的罪魁祸首是正确的。这是一个已经在SO上多次讨论的主题,我认为Mathematica每次Append到现有列表时都会重新分配内存

我认为Table命令运行得足够快,以至于你逐步产生情节的愿望将会消失。但如果不是,你可以看看Animate或其中一个表兄弟。但是,如果你不小心,你可能会发现你为每个阶段的数据点列表记忆,所以你发现自己有一系列大小为1, 2, 3, ..., N的表,而不是具有N个项目的表。不会有太大的优化。

我认为你为了节省内存而一次一个地添加点的想法是错误的 - 在你显示之前,情节的信息将存储在哪里(以及如何)?看一下简单图形的FullForm

如果您仍然关注内存使用情况,那么Remove您在完成后创建的变量,或者只是在ListPlot[]语句周围包裹Table,在这种情况下table将没有名称,因此当Mathematica绕过它时将被垃圾收集。我不相信Mathematica在垃圾收集方面非常出色,但我也很少担心它。

答案 1 :(得分:1)

下面的屏幕截图中的数据和情节是否与您的目标相符?

   list = Table[Table[Table[{k + ndiag j, l + ndiag j}, {k, 0, ndiag}, {l, 0, ndiag}], 
   {j, rank m , (rank + 1) m}], 
   {rank, 0, grpSize}] //  Flatten[#, 3] &

生成数据

data

  ListPlot[list]

给出

enter image description here