سؤال

Suppose I have a Matlab matrix A(x,y) which is square matrix with size N+1.

I want a new matrix B, whose element B(x,z) is A(x,N-x-z), and in case x+z>N, B(x,z) is just zero.

Of course I can do it using a 2-level for loop, but for the sake of performance, I want to know if there is a 'vectorized' method to finish this job.

Edit 1:

All indices mention above start from 0.

Edit 2:

If the indices start from 1 instead of 0, the question can reformulated as follows:

I have a Matlab matrix A(i,j) which is a square matrix with size N+1.

I want a new matrix B, whose element B(i,k) is A(i,N+3-i-k), and in case i+k>N+2, B(i,k) is just zero.

هل كانت مفيدة؟

المحلول

Hoping this is what you are looking for -

N = size(A,1)

B = A

B(fliplr(triu(ones(N)))~=1)=NaN
B = fliplr(B)

[~,col1] = sort(~isnan(B),2,'descend')
row1 = repmat(1:N,N,1)'; %%//'
restructured_indices = sub2ind(size(B),row1(:),col1(:))
B = reshape(B(restructured_indices),N,N)
B(isnan(B))=0

Version 2:

N = size(A,1)

col1 = bsxfun(@minus,repmat(N:-1:1,N,1),[0:N-1]');%%//'
row1 = repmat([1:N]',1,N) %%//'

valid_ind = find(col1>0);
col1 = col1(valid_ind);
row1 = row1(valid_ind);

ind2 = sub2ind(size(A),row1(:),col1(:))

B= zeros(size(A));
B(valid_ind)= A(ind2)

Version 2 (Shorter Form):

B = zeros(size(A));
N = size(A,1)

col1 = bsxfun(@minus,repmat(N:-1:1,N,1),[0:N-1]') %%//'
remapped_ind = bsxfun(@plus,N.*(col1-1),[1:N]') %%//'

normal_ind = 1:N*N;
B(normal_ind(remapped_ind>0)) = A(remapped_ind(remapped_ind>0))
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top