File Exchange

image thumbnail


version (4.42 KB) by Zhigang Xu
Returns unique elements in an array and all the indices for the repetitious values.

1 Download

Updated 05 Sep 2009

View License

[B P]=numunique(A) for the array A returns the same values as in A but
with no repetitions. B will also be sorted. A can only be numerical,
as the name of the function suggests.

The second output, P, is a row of cells, containing the indices of A,
such that, A(p{n})=B(n) is true. P has the same number of cells as the
number of elements in B.

Note that each cell of P lists all the indices of A, not only the first
or last occurrence, which have the repetitious values. This is different to the Mathwork's
function UNIQUE. Sometimes we need to know all the indices of which A have the same values.

Cite As

Zhigang Xu (2020). NUMUNIQUE (, MATLAB Central File Exchange. Retrieved .

Comments and Ratings (10)

Zhigang Xu

Ah, the explanation to the above puzzle (i.e., NaN vs Double) lies in that whenever NaN is concatenated with other classes, it will be converted to zero first. Thus,


ans =



ans =


[nan uint16([1 2])]

ans =

0 1 2

[nan double([1 2])]

ans =

NaN 1 2

A lesson to remember is that NaN is only a not-a-number within double class. It will become zero when it is converted to other classes.

Zhigang Xu

This is a very thoughtful suggestion. Thanks! I did a quick experiment as follows, showing that NaN can only work with a double class to get right logical indices. I will implement your suggestion for next updating. Thanks again!

>> diff([nan [0 1]])~=0

ans =

1 1

>> diff([nan uint8([0 1])])~=0

ans =

0 1

Bruno Luong

To make the function work for other integer class, I would suggest to modify the two lines:

d=diff([NaN; x]);
d=[true; d~=0];


d=[true; d~=0];

Otherwise unexpected result is obtained with
[u p]=numunique(uint8([0 1]))

Zhigang Xu


Thanks for your comments and rating. Your suggestion can evidently make the codes more concise. However, using logical indexing is usually faster than FIND, as the Matlab Editor would advise. For this reason, I am hesitating to implement it for now. I tested your suggestion with a large input array (x=randi(999, 7e6,1)), and did not find any significant improvement in speed, although it did not go slower either. I am wondering if you can supply me your test script to show the significant difference in speed. I will be very happy to implement your suggestion after I understand why it can do so. Thanks!


Matt Fig

Well done. About the only thing I would change would be to replace these lines:

n = 1:N;
d = diff([nan; x]);
d = d~=0;
n = n(d);


n = find(diff([nan; x]));

On my machines this can make a significant difference in speed. Other than that, great code!

Bruno Luong

Good coding

Zhigang Xu

The updated version has been just up now (as 04-Sep-2009 11:09:21). So please feel free to download the new version. Thanks! --- Zhigang

Zhigang Xu

In my yesterday's submission, NUMUNIQE, I found a bug in it. Now I have fixed it and submitted an updated version already. The new version should show up in this center in a day or so. For those of you who have downloaded my yesterday's submission (there are only 5 downloads by now as 03-Sep-2009 18:52:49), you may simply cut and paste the following function body as the replacement. Or simply re-download the new version when it comes up. Sorry for any inconvenience. Zhigang

[x s]=sort(x);

d=diff([nan; x]);

if K==1
for k=1:K-1

if isrowvec, x=x.'; end

Zhigang Xu


You may want to avoid using FIND unnecessarily, since it is slow when the input is a very large array.


Jos (10584)

Nice implementation with good help (although missing a see also to UNIQUE). Here is another approach you might consider:

B = unique(A) ;
P = cell(1,numel(B)) ;
for k = 1:numel(B)
P{k} = find(A==B(k)) ;

and in more recent ML versions:
P = arrayfun(@(x) find(x==A),B,'un',false)


Suggestions from Matt Fig and Bruno Luong, and the case of unique values only are implemented. A third optional output is implemented in case one also needs the representative indices, which are chosen as those for the first occurrences.

Suggestions from Matt Fig and Bruno Luong are implemented. A third optional output is implemented in case one also needs the representative indices, which are chosen as those for the first occurrences.

Correction also for the same typos but appeared in the General Information about the file.

Correction for the two minor typos in the help text.

There was a bug and now it has been fixed.

MATLAB Release Compatibility
Created with R2008b
Compatible with any release
Platform Compatibility
Windows macOS Linux