0
votes

In Matlab I have a big matrix containing the coordinates (x,y,z) of many points (over 200000). There is an extra column used as identification. I have written this code in order to sort all coordinate points. My final goal is to find duplicated points (rows with same x,y,z). After sorting the coordinate points I use the diff function, two consecutive rows of the matrix with the same coordinates will take value [0 0 0], and then with ismember I can find which rows of that matrix resulting from applying "diff" have the [0 0 0] row. With the indices returned from ismember I can find which points are repeated.

Back to my question...This is the code I wrote to sort properly my coordintes+id matrix. I guess It could be done better. Any suggestion?

 %coordinates are always positive
 a=[ 1 2 8 4; %sample matrix
     1 0 5 6;
     2 4 7 1;
     3 2 1 0;
     2 3 5 0;
     3 1 2 8;
     1 2 4 8];
b=a; %for checking purposes

%sorting first column
a=sortrows(a,1);

%sorting second column
for i=0:max(a(:,1));

    k=find(a(:,1)==i);
    if not(isempty(k))
        a(k,:)=sortrows(a(k,:),2);
    end
end

%Sorting third column
for i=0:max(a(:,2));  
    k=find(a(:,2)==i);
    if not(isempty(k))
    %identifying rows with same value on first column
        for j=1:length(k)
            [rows,~] = ismember(a(:,1:2), [ a(k(j),1),i],'rows');
            a(rows,3:end)=sortrows(a(rows,3:end),1); 
        end
    end
end 

%Checking that rows remain the same
m=ismember(b,a,'rows');

if length(m)~=sum(m)
    disp('Error while sorting!');
end
2
Could you share the final outcome that you intend to get? Aren't the first 3 columns x-y-z? Are we supposed to sort and then identify the row indices with repeated x-y-z, or identify and then sort?Divakar

2 Answers

1
votes

Why don't you just use unique?

[uniqueRows, ii, jj] = unique(a(:,1:3),'rows');

Example

a = [1     2     3     5
     3     2     3     6
     1     2     3     9
     2     2     2     8];

gives

uniqueRows =

     1     2     3
     2     2     2
     3     2     3

and

jj =

     1
     3
     1
     2

meaning third row equals first row.

If you need the full unique rows, including the fourth column: use ii to index a:

fullUniqueRows = a(ii,:);

which gives

fullUniqueRows =

     1     2     3     9
     2     2     2     8
     3     2     3     6
0
votes

Trying to sort a based on the fourth column? Do this -

a=[ 1 2 8 4; %sample matrix
    1 0 5 6;
    2 4 7 1;
    3 2 1 0;
    2 3 5 0;
    3 2 1 8;
    1 2 4 8];

[x,y] = sort(a(:,4))
sorted_a=a(y,:)

Trying to get the row indices having repeated x-y-z coordinates being represented by the first three columns? Do this -

out = sum(squeeze(all(bsxfun(@eq,a(:,1:3),permute(a(:,1:3),[3 2 1])),2)),2)>1

and use it similarly for sorted_a.