@Bruno Luong: Yes, you are absolutely right, I was hasty, s was meant to be the length of the vector of unique values. I fixed the code in the original post. Thanks!
Faster way to create a matrix of the unique() of each row of a matrix
4 views (last 30 days)
Show older comments
Let A be a matrix of relatively big size(A,1), say 2000, and relatively small size(A,2), say 20. I am looking for a faster way to construct a matrix B such that the i-th row of B consists of unique(B(i,:)), padded appropriately, say with 0-s, so that all these rows have the same length (in order to fit together as the matrix B).
I am currently using the following code:
[n,m] = size(A); % A is, say, a non-zero uint8 matrix
A = A.'; % it's better to work with columns in MATLAB?
B = zeros(m,n,'uint8');
t = 0; % will truncate B at t;
for i=1:n % loop through the columns of A.'
col = unique(A(:,i));
s = length(col);
B(1:s,i) = col;
t = max(t,s);
end
B = B.'; % go back to the original form
B = B(:,1:t);
When size(A,1) is big, the long loop is perhaps suboptimal. Moreover, A and B are actually GPU arrays, so the code is supposed to run on the GPU. So is there perhaps a faster/smarter (vectorized) way to do this?
Accepted Answer
Bruno Luong
on 7 Aug 2022
Edited: Bruno Luong
on 7 Aug 2022
% Test example
A=randi(4,10,5)
[m,n] = size(A);
As=sort(A,2);
b=[true(m,1),diff(As,1,2)>0];
R=repmat((1:m)',1,n);
C=cumsum(b,2);
r=R(b);
c=C(b);
a=As(b);
B=accumarray([r,c],a)
2 Comments
Bruno Luong
on 8 Aug 2022
% Test example
A small modification to easier find r
A=randi(4,10,5)
[m,n] = size(A);
As=sort(A,2);
b=[true(m,1),diff(As,1,2)>0];
C=cumsum(b,2);
[r,~] = find(b); % not need R
c=C(b);
a=As(b);
B=accumarray([r,c],a)
More Answers (0)
See Also
Categories
Find more on Operating on Diagonal Matrices in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!