MATLAB 2D and 3D matrix sorting and index access

Say you have a 1D matrix

a = rand(1,5); [sa i] = sort(a); 

then sa and a(i) coincide. However, if the size of the matrix increases

 a = rand(3,4); [sa i] = sort(a); 

then sa and a(i) do not coincide. And the same thing happens when I try to sort a 3D matrix by its third dimension.

How to access values โ€‹โ€‹of a through index i ? Or, in other words, how can I calculate sa=a(X) what X should be?

Edit:

Thanks for the solution. However, they do not work when you change the dimension to sort. However, I take this idea and use it to create a common form.

What the algorithm does is build matrix indices. MATLAB indexes cell columns. Therefore, the index is specified

 idx = r + (c-1)*ROWS + (p-1)*ROWS*COLS 

where, idx is the index, r is the position of the row, c is the position of the column, and p is the position of the page.

Therefore, if we sort in the first dimension (normal sort(a) ), then the result is the position in the columns; if we sort in the second dimension, the index of the result is the position in the rows; and if we sort in the third dimension, then the result is the position of the page. Saying this, he only last time creates rows and columns for this case:

 r = repmat((1:rows)',[1 cols pages]); c = repmat(1:cols,[rows 1 pages]); 

Sorting in the first dimension is explained in the solutions given. Then let's sort in the second dimension (row wise) of a two-dimensional array

 a = rand(4,5); [rows cols pages] = size(a); R = repmat((1:rows)',[1 cols pages]); [sa idx] = sort(a,2); nIdx = R + (idx-1)*rows; isequal(sa,a(nIdx)) 

Now, if we use the same idea to sort in the third dimension (per page), we need to do

 a = rand(4,5,3); [rows cols pages] = size(a); R = repmat((1:rows)',[1 cols pages]); C = repmat(1:cols,[rows 1 pages]); [sa idx] = sort(a,3); nIdx = R + (C-1)*rows + (idx-1)*rows*cols; isequal(sa,a(nIdx)) 

And the same logic can be used to expand it to N dimensions. Thanks for your help, you burn the way. :)

+4
source share
4 answers

[sa, i]=sort(a) returns ordered indexes for each column. You just need to get the correct linear indexes for the matrix. So, for a two-dimensional matrix

 A=rand(3,4); [rows,cols]=size(A); [B,index]=sort(A,1); correctedIndex=index+repmat(0:cols-1,rows,1)*rows; 

Now test it:

 A = 0.9572 0.1419 0.7922 0.0357 0.4854 0.4218 0.9595 0.8491 0.8003 0.9157 0.6557 0.9340 B = 0.4854 0.1419 0.6557 0.0357 0.8003 0.4218 0.7922 0.8491 0.9572 0.9157 0.9595 0.9340 A(correctedIndex) ans = 0.4854 0.1419 0.6557 0.0357 0.8003 0.4218 0.7922 0.8491 0.9572 0.9157 0.9595 0.9340 
+4
source
 a = rand(3,5); [sa i] = sort(a); ii=bsxfun(@plus,i,0:size(a,1):numel(a)-size(a,1)); isequal(a(ii),sa) 
+1
source

You can create a common vector solution that will work for any ND matrix or sort size using the IND2SUB and SUB2IND functions . Here I have packaged this solution into a new sort_linear_index function, which will behave the same as the SORT function, except that it will return linear indices so that B = A(IX) always works regardless of size A

 function [sortedA,sortIndex] = sort_linear_index(A,sortDim,sortOrder) %#SORT_LINEAR_INDEX Just like SORT, but returns linear indices sizeA = size(A); %# Get the matrix size if nargin < 2 sortDim = find(sizeA > 1,1); %# Define sortDim, if necessary end if nargin < 3 sortOrder = 'ascend'; %# Define sortOrder, if necessary end [sortedA,sortIndex] = sort(A,sortDim,sortOrder); %# Sort the matrix [subIndex{1:numel(sizeA)}] = ... %# Create a set of matrix subscripts ind2sub(sizeA,reshape(1:prod(sizeA),sizeA)); subIndex{sortDim} = sortIndex; %# Overwrite part of the subscripts with %# the sort indices sortIndex = sub2ind(sizeA,subIndex{:}); %# Find the linear indices end 

And now we can test the function:

 >> A = rand(1,10); >> [B,IX] = sort_linear_index(A); %# Sort a row vector >> isequal(B,A(IX)) ans = 1 >> A = rand(3,4,3); >> [B,IX] = sort_linear_index(A,1); %# Sort a 3-by-4-by-3 matrix along >> isequal(B,A(IX)) %# the first dimension ans = 1 >> [B,IX] = sort_linear_index(A,3); %# Sort a 3-by-4-by-3 matrix along >> isequal(B,A(IX)) %# the third dimension ans = 1 >> [B,IX] = sort_linear_index(A,2,'descend'); %# Sort a 3-by-4-by-3 matrix along >> isequal(B,A(IX)) %# the second dimension ans = %# in descending order 1 
+1
source

from here: http://www.mathworks.com/help/techdoc/ref/sort.html

 sa(:,j) = a(i(:,j),j) 
0
source

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


All Articles