объединение матриц N^2 3x3 в матрицу 3Nx3N

У меня есть матрицы N^2. Каждый из них представляет собой матрицу 3x3. Один из способов объединить их в матрицу 3Nx3N — написать A(:,:,i)= # 3x3 matrix i=1:N^2

matrix

B=[A11 A12 ..A1N;A21 ...A2N;...] Но когда N велико, это утомительная работа. Что вы предлагаете?


person Abolfazl    schedule 04.02.2011    source источник
comment
У меня был связанный с этим вопрос, который привел к этому: уравнения   -  person Abolfazl    schedule 04.02.2011


Ответы (4)


Вот очень быстрый однострочный код, в котором используются только RESHAPE и ПЕРМЕТИРОВАТЬ:

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

И тест:

>> 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
person gnovice    schedule 04.02.2011
comment
Я могу подтвердить, что это на порядок быстрее +1 - person Amro; 04.02.2011

Попробуйте следующий код:

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
person Amro    schedule 04.02.2011

Другая возможность с участием mat2cell и 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);

Вот то же самое одной строкой, если вам так больше нравится

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

Для 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
person Jonas    schedule 04.02.2011

Почему бы не использовать старомодное предварительное выделение и цикл? Должно быть довольно быстро.

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

РЕДАКТИРОВАТЬ: Для любителей скорости вот рейтинг:

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.
person Rich C    schedule 04.02.2011