# Simultaneous sortrows() for all slices of a 3D matrix?

1 view (last 30 days)
Marin Genov on 13 Sep 2022
Commented: Marin Genov on 14 Sep 2022
I need to apply sortrows to every page of a 3D matrix and I was wondering if there is a faster way of doing this than simply looping through all pages. I have the option to execute on a GPU. While I am aware that sortrows also works with GPU arrays, the code appears to execute much faster on the CPU than on the GPU, probably because of the very long loop.
Here is a minimal working example:
% Parameters:
N = 20;
n = 40;
m = 2;
d = 200000;
% Generate an example matrix 'A':
A = randi(N,n,m,d,'uint16'); % generate a 3D matrix with above parameters
% To be vectorized?
tic;
B = zeros(n,d,'double');
for i=1:d
[~,b] = sortrows(A(:,:,i),[1 2]);
B(:,i) = b;
end
toc;
Bruno Luong on 14 Sep 2022

Bruno Luong on 14 Sep 2022
Edited: Bruno Luong on 14 Sep 2022
Code applicable for n == 2 and N < 256 only:
% Parameters:
N = 20;
n = 40;
m = 2;
d = 200000;
% Generate an example matrix 'A':
A = randi(N,n,m,d,'uint16'); % generate a 3D matrix with above parameters
% Original method: To be vectorized?
tic;
B = zeros(n,d,'double');
for i=1:d
[~,b] = sortrows(A(:,:,i),[1 2]);
B(:,i) = b;
end
toc
Elapsed time is 1.019606 seconds.
% Code applicable for n == 2 and N < 256 only
tic
[m,n,p] = size(A);
% Uncomment this sanity test if you are not sure A meets the requirement
% if n ~= 2 && ~all(A<256,'all')
% error('Method 3 not applicable');
% end
C = A(:,1,:)*feval(class(A),2^8) + A(:,2,:);
[~,B3] = sort(C,1);
B3 = reshape(B3,m,d);
toc
Elapsed time is 0.129230 seconds.
isequal(B,B3)
ans = logical
1
Marin Genov on 14 Sep 2022
Thanks for posting this method as well! This helps a lot!

Bruno Luong on 13 Sep 2022
Edited: Bruno Luong on 13 Sep 2022
Somewhat faster
% Parameters:
N = 20;
n = 40;
m = 2;
d = 200000;
% Generate an example matrix 'A':
A = randi(N,n,m,d,'uint16'); % generate a 3D matrix with above parameters
% Original method: To be vectorized?
tic;
B = zeros(n,d,'double');
for i=1:d
[~,b] = sortrows(A(:,:,i),[1 2]);
B(:,i) = b;
end
toc
Elapsed time is 1.090424 seconds.
% No loop but a big permute
tic
[m,n,p] = size(A);
q = repelem((1:p)',m,1);
A3 = reshape(permute(A,[1 3 2]),m*p,n);
A3 = [q,double(A3)];
[~,B2] = sortrows(A3);
B2 = reshape(B2,m,d)-(0:d-1)*m;
toc
Elapsed time is 0.667823 seconds.
isequal(B,B2)
ans = logical
1
Marin Genov on 14 Sep 2022
Thanks, this looks great!

### Categories

Find more on Matrices and Arrays in Help Center and File Exchange

R2022a

### Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!