我正在寻找一种在不存储实际数据的情况下生成和绘制数据的方法。作为一个基本的例子:
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,它确实对速度问题有所帮助,但出于纯粹的好奇心,我仍然想知道如何避免存储数据(除了情节)。
答案 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] &
生成数据
和
ListPlot[list]
给出