开发者

concatenation of N^2 3x3 matrixes into a 3Nx3N matrix

I have N^2 matrixes. Each one is a 3x3 matrix. One way to concatenati开发者_运维技巧on them to a 3Nx3N matrix is to write A(:,:,i)= # 3x3 matrix i=1:N^2

concatenation of N^2 3x3 matrixes into a 3Nx3N matrix

B=[A11 A12 ..A1N;A21 ...A2N;...] But When N is large is a tedious work. What do you offer?


Here's a really fast one-liner that only uses RESHAPE and PERMUTE:

B = reshape(permute(reshape(A,3,3*N,N),[2 1 3]),3*N,3*N).';

And a test:

>> N=2;
>> A = rand(3,3,N^2)
A(:,:,1) =
    0.5909    0.6571    0.8082
    0.7118    0.6090    0.7183
    0.4694    0.9588    0.5582
A(:,:,2) =
    0.1791    0.6844    0.6286
    0.4164    0.4140    0.5833
    0.1380    0.1099    0.8970
A(:,:,3) =
    0.2232    0.2355    0.1214
    0.1782    0.6873    0.3394
    0.5645    0.4745    0.9763
A(:,:,4) =
    0.5334    0.7559    0.9984
    0.8454    0.7618    0.1065
    0.0549    0.5029    0.3226

>> B = reshape(permute(reshape(A,3,3*N,N),[2 1 3]),3*N,3*N).'
B =
    0.5909    0.6571    0.8082    0.1791    0.6844    0.6286
    0.7118    0.6090    0.7183    0.4164    0.4140    0.5833
    0.4694    0.9588    0.5582    0.1380    0.1099    0.8970
    0.2232    0.2355    0.1214    0.5334    0.7559    0.9984
    0.1782    0.6873    0.3394    0.8454    0.7618    0.1065
    0.5645    0.4745    0.9763    0.0549    0.5029    0.3226


Try the following code:

N = 4;
A = rand(3,3,N^2);                     %# 3-by-3-by-N^2

c1 = squeeze( num2cell(A,[1 2]) );
c2 = cell(N,1);
for i=0:N-1
    c2{i+1} = cat(2, c1{i*N+1:(i+1)*N});
end

B = cat(1, c2{:});                     %# 3N-by-3N


Another possibility involving mat2cell and reshape

N = 2;
A = rand(3,3,N^2);  

C = mat2cell(A,3,3,ones(N^2,1));
C = reshape(C,N,N)'; %'# make a N-by-N cell array and transpose

%# catenate into 3N-by-3N cell array
B = cell2mat(C);

Here's the same in one line if you like that better

B = cell2mat(reshape(mat2cell(A,2,2,ones(N^2,1)),N,N)');

For N=2

>> A = rand(3,3,N^2)
A(:,:,1) =
      0.40181      0.12332      0.41727
     0.075967      0.18391     0.049654
      0.23992      0.23995      0.90272
A(:,:,2) =
      0.94479      0.33772       0.1112
      0.49086      0.90005      0.78025
      0.48925      0.36925      0.38974
A(:,:,3) =
      0.24169      0.13197      0.57521
      0.40391      0.94205      0.05978
     0.096455      0.95613      0.23478
A(:,:,4) =
      0.35316     0.043024      0.73172
      0.82119      0.16899      0.64775
     0.015403      0.64912      0.45092

B =
      0.40181      0.12332      0.41727      0.94479      0.33772       0.1112
     0.075967      0.18391     0.049654      0.49086      0.90005      0.78025
      0.23992      0.23995      0.90272      0.48925      0.36925      0.38974
      0.24169      0.13197      0.57521      0.35316     0.043024      0.73172
      0.40391      0.94205      0.05978      0.82119      0.16899      0.64775
     0.096455      0.95613      0.23478     0.015403      0.64912      0.45092


Why not do the old fashioned pre-allocate and loop? Should be pretty fast.

N = 4;
A = rand(3,3,N^2);  % Assuming column major order for Aij
8
B = zeros(3*N, 3*N);
for j = 1:N^2
    ix = mod(j-1, N)*3 + 1;
    iy = floor((j-1)/N)*3 + 1;
    fprintf('%02d - %02d\n', ix, iy);
    B(ix:ix+2, iy:iy+2) = A(:,:,j);
end

EDIT: For the speed junkies out here are the rankings:

N = 200;
A = rand(3,3,N^2);  % test set

@gnovice solution: Elapsed time is 0.013069 seconds.
@Amro    solution: Elapsed time is 0.203308 seconds.
@Rich C  solution: Elapsed time is 0.887077 seconds.
@Jonas   solution: Elapsed time is 7.065174 seconds.
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜