Linear maximum index of a multidimensional matrix - MATLAB

Let's say I have a 3-dimensional matrix and calculated max from the second size and want to get linear indices of maximum values. However, max-function returns indices in only one dimension.

 A = randn([5,5,5]); % Generate random matrix [M, Ind] = max(A,[],2); % Take the max along dimension 2 

How to pass index to linear indexing so that

 M == A(Ind) 

becoming true?

My intention in this problem is that I have two multi-dimensional matrices and need to calculate max in first . Then I want to access the values ​​in the second matrix exactly at the positions where I found max in first .

+5
source share
4 answers

One way is to use sub2ind :

 A = randn([5,5,5]); [M, col] = max(A,[],2); [m,n,o] = size(A); dim1 = mod((0:m*o-1)', m)+1; dim2 = col(:); dim3 = ceil((1:m*o)/m)'; ind = sub2ind(size(A), dim1, dim2, dim3) 

check that it works with

 isequal(M(:), A(ind)) 

so that they have the same shape as M :

 reshape(ind, m, 1, o) 
+2
source

Create indexes for other dimensions.

In dim 1, the index should change rapidly: [1,2,...,size(A,1)] and size(A,3) times:

 idx1 = repmat((1:size(A,1))',size(A,3),1); 

In dim 2, the index is given by Ind .

In dim 3, the index should change more slowly: [1,1,...,1] for size(A,1) times, and then [2,2,...,2] , etc. to size(A,3) .

 idx3 = ones(size(A,1),1)*(1:size(A,3)); 

Access to individual values:

  M_ = A(sub2ind(size(A),idx1(:),Ind(:),idx3(:))); 

For comparison:

 M(:) == M_ 
+1
source

3-dimensional case :

 [m, n, p] = size(A); [M, Ind] = max(A,[],2); LinInd = bsxfun(@plus, (1:m).', (0:p-1)*m*n); %'// LinInd = LinInd(:) + (Ind(:)-1)*m; 

Required LinInd linear index. This gives

 A(LinInd) == M(:) 

with all entries true (note that you need (:) on the right side so that the comparison makes sense).

Total multidimensional size :

 d = 3; %// dimension along which max will be computed s = size(A); sLow = prod(s(1:d-1)); sHigh = prod(s(d+1:end)); [M, Ind] = max(A,[],d); LinInd = bsxfun(@plus, (1:sLow).', (0:sHigh-1)*sLow*s(d)); %'// LinInd = LinInd(:) + (Ind(:)-1)*sLow; 
+1
source

Suppose A and B are the two matrices you have, and you need to get the max indices from A and use these indices to index in B for the desired output. One way to achieve the same result could be:

 %// Your code to get Ind A = randn([5,5,5]); % Generate random matrix [M, Ind] = max(A,[],2); % Take the max along dimension 2 %// ------- Solution code ------------- %// Get the size of A [n1,n2,n3] = size(A) %// Linear indices corresponding to column and third dimension indices col_dim3_lin_idx = bsxfun(@plus,(Ind-1)*n1,permute([0:n3-1]*n1*n2,[1 3 2])) %// Finally get the overall linear indices linear_index = bsxfun(@plus,col_dim3_lin_idx,[1:n1]') %//' %// Get the corresponding elements from B out = B(linear_index) 

A slightly different way to get the desired linear indexes in the form of a 2D array:

 [n1,n2,n3] = size(A) %// Get the size of A idx = bsxfun(@plus,bsxfun(@plus,squeeze((Ind-1)*n1),[0:n3-1]*n1*n2),[1:n1]') 

idx(:) will be a column vector of linear indices with this new approach, which can be indexed in B ie B(idx(:)) to get the desired result as a column vector.

0
source

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


All Articles