2

我是物理系的学生。我必须对数据列表执行一个简单的松弛循环,并且我使用一个看起来像这样的简单 while 循环来完成它

i = 1;
While[i < Limit, 
data[[i]]  = f[ data[[i]] , data[[i+1]], data[[i-1]] ];
i = i+2;

i = 2;
While[i < Limit, 
data[[i]]  = f[ data[[i]] , data[[i+1]], data[[i-1]] ];
i = i+2;

如您所见,我首先在列表的奇数位置执行操作,然后在偶数位置执行操作。问题是,我必须这样做一万次才能使解决方案收敛,这需要太多时间。所以我想知道这是否可以使用嵌套以更快的方式完成,但是我如何在计算中使用 data[[i+1]] 和 data[[i-1]] ?

也许这是一个微不足道的问题,所以我提前道歉,

谢谢你

4

2 回答 2

0

使用Mathematica 的面向列表的函数可能可以轻松完成此操作,但我不能完全说出您想要什么,因为您的代码不完整(语法错误和缺少数据)。

你应该看看这些函数:Partition, MovingAverage, ListCorrelate, FoldList.

这里有几种可能的解释。列表相关:

data = CharacterRange["a", "i"];

ListCorrelate[{1, 1, 1}, data, {1, -1}, {}, Times, f]
{f[a,b,c],f[b,c,d],f[c,d,e],f[d,e,f],f[e,f,g],f[f,g,h],f[g,h,i]}

分区和Riffle:

Riffle[Take[data, {1, -1, 2}], f @@@ Partition[data, 3, 2]]
{a,f[a,b,c],c,f[c,d,e],e,f[e,f,g],g,f[g,h,i],i}

如果您遵循SSCCE原则并在这里提出您的问题,您可能会得到更好的答案:

在此处输入图像描述

于 2013-08-26T22:55:23.390 回答
0

首先,您应该注意,放松方法本质上是缓慢的。所以不要指望使用它获得超快的结果。对于现实生活中的问题,还有其他(非常快的)方法。

无论如何,我有几个建议可能会影响你的表现。

第一:我认为函数f应该足够简单来编译它;就这样做吧!我想像

f=Compile[{{a,_Real},{b,_Real},{c,Real}},"Write f[a,b,c] explicitly",CompilationTarget->"C"]

应该管用。

第二:尝试使用FixedPoint. 为了做到这一点,我可能会做一些类似的事情(或者可能会做一些更好的事情:-):

g[data,_List]:=Block[{i = 1},
    While[i < Length[data], 
    data[[i]]  = f[ data[[i]] , data[[i+1]], data[[i-1]] ];
    i = i+2;
    ]
    i = 2;
    While[i < Length[data], 
    data[[i]]  = f[ data[[i]] , data[[i+1]], data[[i-1]] ];
    i = i+2;
    data];
FixedPoint[g,"initialdata",SameTest->((#1-#2).(#1-#2)<10^(-4)&)]

此外,您必须自己处理边界条件。

于 2013-08-24T07:22:03.210 回答