Vectorization of Assignment of Values ​​to a 3D Array

Here is a simple code:

A=zeros(60,60,30);
a=rand(28,28,30);

for i=1:30
    m=round(rand*32)+1; %because 60-28=32
    n=round(rand*32)+1;
    A(m:m+27,n:n+27,i)=a(:,:,i);
end

What is it - just take a 28 * 28 random matrix and "plant" it in a large (zero) matrix and repeat 30 times. Each time, he randomly chooses a different angular position (ie, “M” and “n”) to place the small matrix inside the larger one. I'm sure I can do this without a loop for- just not sure how to do this.

+4
source share
1 answer

- , MATLAB. , . , 3D- A, 3D-. offset2D offset3D . , , m n.

, m n, 1D , m_arr n_arr, bsxfun -

%// Say you have the m,n arrays are created like this -
m_arr = round(rand(30,1)*32)+1;
n_arr = round(rand(30,1)*32)+1;

%// Get linear indices with m,n
mn_arr = (n_arr-1)*size(A,1) + m_arr;

%// Calculate offset indices for 2D and then 3D versions
offset2D = bsxfun(@plus,[0:27]',[0:27]*size(A,1));  %//'
offset3D = bsxfun(@plus,offset2D(:),[0:30-1]*numel(A(:,:,1)));

%// Incorporate m,n indices into offset to get final linear indices to index into A
lidx = bsxfun(@plus,mn_arr(:).',offset3D);  %//'

%// Initialize output array and then index into A to values from a
A = zeros(60,60,30);
A(lidx) = a;

-

%// Parameters
M = 4;
D = 3;
mx = 3;

%// For-loop code
A = zeros(M+mx,M+mx,D);
a = rand(M,M,D);
m_arr = round(rand(D,1)*mx)+1;
n_arr = round(rand(D,1)*mx)+1;
for i=1:D
    m = m_arr(i);
    n = n_arr(i);
    A(m:m+M-1,n:n+M-1,i) = a(:,:,i);
end

%// Vectorized code
mn_arr = (n_arr-1)*size(A,1) + m_arr;
offset2D = bsxfun(@plus,[0:M-1]',[0:M-1]*size(A,1));  %//'
offset3D = bsxfun(@plus,offset2D(:),[0:D-1]*numel(A(:,:,1)));
lidx = bsxfun(@plus,mn_arr(:).',offset3D);  %//'
A_vectorized = zeros(M+mx,M+mx,D);
A_vectorized(lidx) = a;

, -

>> max(abs(A(:)-A_vectorized(:)))
ans =
     0
+4

Source: https://habr.com/ru/post/1606774/


All Articles