0

I use unique function to find a full rank matrix (unique rows of matrix), now I need to unique

function that returns unique rows with a tolerance. Is there anyone who know how can I do this?

I am gratefule to you for your help.

Rosa
  • 253
  • 1
  • 14

2 Answers2

2

I think you can do it with sortrows (which is what unique uses internally):

A = [1 2 3; 1 2.1 3; 1.001 2.001, 3.001; -4 5 6] % example data
tol = 0.01; % tolerance
[~, ii] = sortrows(A);
ii_unique = ii(logical([1; any(diff(A(ii,:))>tol,2)]));
A_unique_tol = A(sort(ii_unique),:) % result

The result in this example is:

A =

    1.0000    2.0000    3.0000
    1.0000    2.1000    3.0000
    1.0010    2.0010    3.0010
   -4.0000    5.0000    6.0000

A_unique_tol =

    1.0000    2.0000    3.0000
    1.0000    2.1000    3.0000
   -4.0000    5.0000    6.0000

As usual, for old Matlab versions that don't support ~ as an output argument, change [~, ii] = sortrows(A); by [vv, ii] = sortrows(A);

Luis Mendo
  • 110,752
  • 13
  • 76
  • 147
  • Sorry, but when I run this code, it has error on line 3,(unbalenced )or ]) ,could you please help me? – Rosa Nov 11 '13 at 07:02
  • @Rosa Maybe you have an old Matlab version which does not support `~` output. Change `[~, ii] = sortrows(A);` by `[vv, ii] = sortrows(A);` – Luis Mendo Nov 11 '13 at 10:11
1

This is hard to define well, assume you have a tolerance of 1. Then what would be the outcome of [1; 2; 3; 4]?

When you have multiple columns a definition could become even more challenging.

However, if you are mostly worried about rounding issues, you can solve most of it by one of these two approaches:

  1. Round all numbers (considering your tolerance), and then use unique
  2. Start with the top row as your unique set, use ismemberf to determine whether each new row is unique and if so, add it to your unique set.

The first approach has the weakness that 0.499999999 and 0.500000000 may not be seen as duplicates. Whilst the second approach has the weakness that the order of your input matters.

Dennis Jaheruddin
  • 21,208
  • 8
  • 66
  • 122