注意:有关最快的解决方案,请参阅路易斯·门多的回答 https://stackoverflow.com/a/28079457/1011724
因此,首先为此使用 for 循环(特别是如果这些是您的实际尺寸)确实不会很昂贵。除非您使用的是非常旧版本的 Matlab,否则 JIT 编译器(当然还有预分配)会使 for 循环变得便宜。
其次 - 你尝试过 for 循环吗?因为在过早开始优化之前,您确实应该首先尝试简单的实现。
第三——arrayfun
可以使其成为一个衬垫,但它基本上只是一个具有额外开销的 for 循环,并且如果您确实关心速度,则很可能比 for 循环慢。
最后一些代码:
n = 1000;
A = rand(n,1);
l = 100;
for 循环(几乎不庞大,可能很有效):
S = zeros(n-l+1,1); %//Pre-allocation of memory like this is essential for efficiency!
for t = 1:(n-l+1)
S(t) = std(A(t:(t+l-1)));
end
向量化(内存效率低下!)解决方案:
[X,Y] = meshgrid(1:l)
S = std(A(X+Y-1))
可能是更好的矢量化解决方案(和单行),但内存效率仍然低下:
S = std(A(bsxfun(@plus, 0:l-1, (1:l)')))
请注意,使用所有这些方法,您可以替换std
任何函数,只要它适用于矩阵的列(这是 Matlab 中的标准)
进入 2D:
要进入 2D,我们需要进入 3D
n = 1000;
k = 4;
A = rand(n,k);
l = 100;
ind = bsxfun(@plus, permute(o:n:(k-1)*n, [3,1,2]), bsxfun(@plus, 0:l-1, (1:l)')); %'
S = squeeze(std(A(ind)));
M = squeeze(mean(A(ind)));
%// etc...
OR
[X,Y,Z] = meshgrid(1:l, 1:l, o:n:(k-1)*n);
ind = X+Y+Z-1;
S = squeeze(std(A(ind)))
M = squeeze(mean(A(ind)))
%// etc...
OR
ind = bsxfun(@plus, 0:l-1, (1:l)'); %'
for t = 1:k
S = std(A(ind));
M = mean(A(ind));
%// etc...
end
或(取自路易斯·门多的回答 https://stackoverflow.com/a/28079457/1011724- 请注意,在他的回答中,他展示了这个简单循环的更快替代方案)
S = zeros(n-l+1,k);
M = zeros(n-l+1,k);
for t = 1:(n-l+1)
S(t,:) = std(A(k:(k+l-1),:));
M(t,:) = mean(A(k:(k+l-1),:));
%// etc...
end