选择没有循环的滚动行

时间:2012-05-24 08:46:17

标签: performance matlab loops matrix

我有一个问题。 假设我有矩阵 A =

 1     2     3
 4     5     6
 7     8     9
10    11    12

我需要从A中选择n个滚动行,并在行中使用新矩阵C中的转置元素。 我使用的循环是:

n = 3;     %for instance every 3 rows of A

B = []; 

for i = 1:n 

    Btemp = transpose(A(i:i+size(A,1)-n,:)); 

    B = [B;Btemp]; 

end

C=B';

并产生矩阵C,即:

C =

 1     2     3     4     5     6     7     8     9
 4     5     6     7     8     9    10    11    12

这也是我想做的,但是如果没有循环,我可以做同样的工作吗?

计算3280x35尺寸的A矩阵需要4分钟。

3 个答案:

答案 0 :(得分:1)

我认为如果你进行初始化,你可以让它工作得非常快。另一个技巧是先进行转置,因为MATLAB使用列作为第一个索引而不是行。

tic
A =  reshape(1:3280*35,[3280 35])'; %# Generate an example A
[nRows, nCols] = size(A);

n = 3; %for instance every 3 rows of A
B = zeros(nRows-n+1,nCols*n);
At = A';
for i = 1:size(B,1)
    B(i,:) = reshape(At(:,i:i+n-1), [1 nCols*n]); 
end
toc

经过的时间是

Elapsed time is 0.004059 seconds.

答案 1 :(得分:0)

我不会在循环中使用reshape,但是将A转换为第一行(实际上一列也可以工作,无关紧要)

Ar = reshape(A',1,[]); % the ' is important here!

然后从Ar中选择元素非常简单:

[nrows, ncols] = size(A);
new_ncols = ncols*n;
B = zeros(nrows-(n-1),new_ncols);

for ii = 1:nrows-(n-1)
    B(ii,:) = Ar(n*(ii-1)+(1:new_ncols));
end

尽管如此,预先分配B会给您带来最大的改进:更多信息http://www.mathworks.nl/help/techdoc/matlab_prog/f8-784135.html

答案 2 :(得分:0)

我现在没有Matlab,但我认为你可以在没有这样的循环的情况下做到这一点:

reshape(permute(cat(A(1:end-1,:),A(2:end,:),3),[3,2,1]), [2, size(A,2)*(size(A,1) - 1)]);

实际上这不会做你想要的吗?:

A1 = A(1:end-1,:);
A2 = A(2:end,:);
answer = [A1(:) ; A2(:)]