Mercurial > octave-nkf
annotate scripts/set/unique.m @ 11922:746f13936eee release-3-0-x
improve set functions for Matlab compatibility
author | Jaroslav Hajek <highegg@gmail.com> |
---|---|
date | Fri, 16 Jan 2009 08:10:28 +0100 |
parents | a1dbe9d80eee |
children | 304855b33b67 |
rev | line source |
---|---|
7017 | 1 ## Copyright (C) 2000, 2001, 2005, 2006, 2007 Paul Kienzle |
11922
746f13936eee
improve set functions for Matlab compatibility
Jaroslav Hajek <highegg@gmail.com>
parents:
7017
diff
changeset
|
2 ## Copyright (C) 2008 Jaroslav Hajek |
7016 | 3 ## |
4 ## This file is part of Octave. | |
5165 | 5 ## |
7016 | 6 ## Octave is free software; you can redistribute it and/or modify it |
7 ## under the terms of the GNU General Public License as published by | |
8 ## the Free Software Foundation; either version 3 of the License, or (at | |
9 ## your option) any later version. | |
5165 | 10 ## |
7016 | 11 ## Octave is distributed in the hope that it will be useful, but |
12 ## WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
14 ## General Public License for more details. | |
5165 | 15 ## |
16 ## You should have received a copy of the GNU General Public License | |
7016 | 17 ## along with Octave; see the file COPYING. If not, see |
18 ## <http://www.gnu.org/licenses/>. | |
5165 | 19 |
20 ## -*- texinfo -*- | |
21 ## @deftypefn {Function File} {} unique (@var{x}) | |
22 ## | |
23 ## Return the unique elements of @var{x}, sorted in ascending order. | |
24 ## If @var{x} is a row vector, return a row vector, but if @var{x} | |
25 ## is a column vector or a matrix return a column vector. | |
26 ## | |
27 ## @deftypefnx {Function File} {} unique (@var{A}, 'rows') | |
28 ## | |
29 ## Return the unique rows of @var{A}, sorted in ascending order. | |
30 ## | |
31 ## @deftypefnx {Function File} {[@var{y}, @var{i}, @var{j}] = } unique (@var{x}) | |
32 ## | |
33 ## Return index vectors @var{i} and @var{j} such that @code{x(i)==y} and | |
5532 | 34 ## @code{y(j)==x}. |
11922
746f13936eee
improve set functions for Matlab compatibility
Jaroslav Hajek <highegg@gmail.com>
parents:
7017
diff
changeset
|
35 ## |
746f13936eee
improve set functions for Matlab compatibility
Jaroslav Hajek <highegg@gmail.com>
parents:
7017
diff
changeset
|
36 ## Additionally, one of 'first' or 'last' can be given as an argument. |
746f13936eee
improve set functions for Matlab compatibility
Jaroslav Hajek <highegg@gmail.com>
parents:
7017
diff
changeset
|
37 ## 'last' (default) specifies that the highest possible indices are returned |
746f13936eee
improve set functions for Matlab compatibility
Jaroslav Hajek <highegg@gmail.com>
parents:
7017
diff
changeset
|
38 ## in @var{i}, while 'first' means the lowest. |
5642 | 39 ## @seealso{union, intersect, setdiff, setxor, ismember} |
5165 | 40 ## @end deftypefn |
41 | |
11922
746f13936eee
improve set functions for Matlab compatibility
Jaroslav Hajek <highegg@gmail.com>
parents:
7017
diff
changeset
|
42 function [y, i, j] = unique (x, varargin) |
5165 | 43 |
11922
746f13936eee
improve set functions for Matlab compatibility
Jaroslav Hajek <highegg@gmail.com>
parents:
7017
diff
changeset
|
44 if (nargin < 1) |
6046 | 45 print_usage (); |
5165 | 46 endif |
47 | |
11922
746f13936eee
improve set functions for Matlab compatibility
Jaroslav Hajek <highegg@gmail.com>
parents:
7017
diff
changeset
|
48 ## parse options |
746f13936eee
improve set functions for Matlab compatibility
Jaroslav Hajek <highegg@gmail.com>
parents:
7017
diff
changeset
|
49 if (iscellstr (varargin)) |
746f13936eee
improve set functions for Matlab compatibility
Jaroslav Hajek <highegg@gmail.com>
parents:
7017
diff
changeset
|
50 optfirst = strmatch ('first', varargin) > 0; |
746f13936eee
improve set functions for Matlab compatibility
Jaroslav Hajek <highegg@gmail.com>
parents:
7017
diff
changeset
|
51 optlast = strmatch ('last', varargin) > 0; |
746f13936eee
improve set functions for Matlab compatibility
Jaroslav Hajek <highegg@gmail.com>
parents:
7017
diff
changeset
|
52 optrows = strmatch ('rows', varargin) > 0 && size (x, 2) > 1; |
746f13936eee
improve set functions for Matlab compatibility
Jaroslav Hajek <highegg@gmail.com>
parents:
7017
diff
changeset
|
53 if (optfirst && optlast) |
746f13936eee
improve set functions for Matlab compatibility
Jaroslav Hajek <highegg@gmail.com>
parents:
7017
diff
changeset
|
54 error ("unique: cannot specify both 'last' and 'first'."); |
746f13936eee
improve set functions for Matlab compatibility
Jaroslav Hajek <highegg@gmail.com>
parents:
7017
diff
changeset
|
55 elseif (optfirst + optlast + optrows != nargin-1) |
746f13936eee
improve set functions for Matlab compatibility
Jaroslav Hajek <highegg@gmail.com>
parents:
7017
diff
changeset
|
56 error ("unique: invalid option."); |
746f13936eee
improve set functions for Matlab compatibility
Jaroslav Hajek <highegg@gmail.com>
parents:
7017
diff
changeset
|
57 endif |
746f13936eee
improve set functions for Matlab compatibility
Jaroslav Hajek <highegg@gmail.com>
parents:
7017
diff
changeset
|
58 optlast = ! optfirst; |
746f13936eee
improve set functions for Matlab compatibility
Jaroslav Hajek <highegg@gmail.com>
parents:
7017
diff
changeset
|
59 else |
746f13936eee
improve set functions for Matlab compatibility
Jaroslav Hajek <highegg@gmail.com>
parents:
7017
diff
changeset
|
60 error ("unique: options must be strings"); |
746f13936eee
improve set functions for Matlab compatibility
Jaroslav Hajek <highegg@gmail.com>
parents:
7017
diff
changeset
|
61 endif |
746f13936eee
improve set functions for Matlab compatibility
Jaroslav Hajek <highegg@gmail.com>
parents:
7017
diff
changeset
|
62 |
746f13936eee
improve set functions for Matlab compatibility
Jaroslav Hajek <highegg@gmail.com>
parents:
7017
diff
changeset
|
63 if (iscell (x)) |
746f13936eee
improve set functions for Matlab compatibility
Jaroslav Hajek <highegg@gmail.com>
parents:
7017
diff
changeset
|
64 if (optrows) |
746f13936eee
improve set functions for Matlab compatibility
Jaroslav Hajek <highegg@gmail.com>
parents:
7017
diff
changeset
|
65 warning ("unique: 'rows' is ignored for cell arrays"); |
746f13936eee
improve set functions for Matlab compatibility
Jaroslav Hajek <highegg@gmail.com>
parents:
7017
diff
changeset
|
66 optrows = false; |
746f13936eee
improve set functions for Matlab compatibility
Jaroslav Hajek <highegg@gmail.com>
parents:
7017
diff
changeset
|
67 endif |
746f13936eee
improve set functions for Matlab compatibility
Jaroslav Hajek <highegg@gmail.com>
parents:
7017
diff
changeset
|
68 endif |
746f13936eee
improve set functions for Matlab compatibility
Jaroslav Hajek <highegg@gmail.com>
parents:
7017
diff
changeset
|
69 |
746f13936eee
improve set functions for Matlab compatibility
Jaroslav Hajek <highegg@gmail.com>
parents:
7017
diff
changeset
|
70 if (optrows) |
746f13936eee
improve set functions for Matlab compatibility
Jaroslav Hajek <highegg@gmail.com>
parents:
7017
diff
changeset
|
71 n = size (x, 1); |
746f13936eee
improve set functions for Matlab compatibility
Jaroslav Hajek <highegg@gmail.com>
parents:
7017
diff
changeset
|
72 else |
6609 | 73 n = numel (x); |
5165 | 74 endif |
75 | |
5168 | 76 y = x; |
5165 | 77 if (n < 1) |
78 i = j = []; | |
5168 | 79 return; |
5165 | 80 elseif (n < 2) |
81 i = j = 1; | |
5168 | 82 return; |
5165 | 83 endif |
84 | |
11922
746f13936eee
improve set functions for Matlab compatibility
Jaroslav Hajek <highegg@gmail.com>
parents:
7017
diff
changeset
|
85 if (optrows) |
5168 | 86 [y, i] = sortrows (y); |
11922
746f13936eee
improve set functions for Matlab compatibility
Jaroslav Hajek <highegg@gmail.com>
parents:
7017
diff
changeset
|
87 match = all (y(1:n-1,:) == y(2:n,:), 2); |
5165 | 88 idx = find (match); |
5168 | 89 y(idx,:) = []; |
5165 | 90 else |
5168 | 91 if (size (y, 1) != 1) |
92 y = y(:); | |
93 endif | |
94 [y, i] = sort (y); | |
5205 | 95 if (iscell (y)) |
11922
746f13936eee
improve set functions for Matlab compatibility
Jaroslav Hajek <highegg@gmail.com>
parents:
7017
diff
changeset
|
96 match = strcmp (y(1:n-1), y(2:n)); |
5205 | 97 else |
11922
746f13936eee
improve set functions for Matlab compatibility
Jaroslav Hajek <highegg@gmail.com>
parents:
7017
diff
changeset
|
98 match = (y(1:n-1) == y(2:n)); |
5205 | 99 endif |
5165 | 100 idx = find (match); |
5168 | 101 y(idx) = []; |
5165 | 102 endif |
103 | |
104 ## I don't know why anyone would need reverse indices, but it | |
105 ## was an interesting challenge. I welcome cleaner solutions. | |
106 if (nargout >= 3) | |
107 j = i; | |
5168 | 108 j(i) = cumsum (prepad (! match, n, 1)); |
5165 | 109 endif |
11922
746f13936eee
improve set functions for Matlab compatibility
Jaroslav Hajek <highegg@gmail.com>
parents:
7017
diff
changeset
|
110 if (optfirst) |
746f13936eee
improve set functions for Matlab compatibility
Jaroslav Hajek <highegg@gmail.com>
parents:
7017
diff
changeset
|
111 i(idx+1) = []; |
746f13936eee
improve set functions for Matlab compatibility
Jaroslav Hajek <highegg@gmail.com>
parents:
7017
diff
changeset
|
112 else |
746f13936eee
improve set functions for Matlab compatibility
Jaroslav Hajek <highegg@gmail.com>
parents:
7017
diff
changeset
|
113 i(idx) = []; |
746f13936eee
improve set functions for Matlab compatibility
Jaroslav Hajek <highegg@gmail.com>
parents:
7017
diff
changeset
|
114 endif |
5165 | 115 |
116 | |
117 endfunction | |
118 | |
119 %!assert(unique([1 1 2; 1 2 1; 1 1 2]),[1;2]) | |
120 %!assert(unique([1 1 2; 1 0 1; 1 1 2],'rows'),[1 0 1; 1 1 2]) | |
121 %!assert(unique([]),[]) | |
122 %!assert(unique([1]),[1]) | |
123 %!assert(unique([1 2]),[1 2]) | |
124 %!assert(unique([1;2]),[1;2]) | |
125 %!assert(unique([1,NaN,Inf,NaN,Inf]),[1,Inf,NaN,NaN]) | |
5205 | 126 %!assert(unique({'Foo','Bar','Foo'}),{'Bar','Foo'}) |
127 %!assert(unique({'Foo','Bar','FooBar'}),{'Bar','Foo','FooBar'}) | |
11922
746f13936eee
improve set functions for Matlab compatibility
Jaroslav Hajek <highegg@gmail.com>
parents:
7017
diff
changeset
|
128 |
746f13936eee
improve set functions for Matlab compatibility
Jaroslav Hajek <highegg@gmail.com>
parents:
7017
diff
changeset
|
129 %!test |
746f13936eee
improve set functions for Matlab compatibility
Jaroslav Hajek <highegg@gmail.com>
parents:
7017
diff
changeset
|
130 %! [a,i,j] = unique([1,1,2,3,3,3,4]); |
746f13936eee
improve set functions for Matlab compatibility
Jaroslav Hajek <highegg@gmail.com>
parents:
7017
diff
changeset
|
131 %! assert(a,[1,2,3,4]) |
746f13936eee
improve set functions for Matlab compatibility
Jaroslav Hajek <highegg@gmail.com>
parents:
7017
diff
changeset
|
132 %! assert(i,[2,3,6,7]) |
746f13936eee
improve set functions for Matlab compatibility
Jaroslav Hajek <highegg@gmail.com>
parents:
7017
diff
changeset
|
133 %! assert(j,[1,1,2,3,3,3,4]) |
746f13936eee
improve set functions for Matlab compatibility
Jaroslav Hajek <highegg@gmail.com>
parents:
7017
diff
changeset
|
134 %! |
746f13936eee
improve set functions for Matlab compatibility
Jaroslav Hajek <highegg@gmail.com>
parents:
7017
diff
changeset
|
135 %!test |
746f13936eee
improve set functions for Matlab compatibility
Jaroslav Hajek <highegg@gmail.com>
parents:
7017
diff
changeset
|
136 %! [a,i,j] = unique([1,1,2,3,3,3,4],'first'); |
746f13936eee
improve set functions for Matlab compatibility
Jaroslav Hajek <highegg@gmail.com>
parents:
7017
diff
changeset
|
137 %! assert(a,[1,2,3,4]) |
746f13936eee
improve set functions for Matlab compatibility
Jaroslav Hajek <highegg@gmail.com>
parents:
7017
diff
changeset
|
138 %! assert(i,[1,3,4,7]) |
746f13936eee
improve set functions for Matlab compatibility
Jaroslav Hajek <highegg@gmail.com>
parents:
7017
diff
changeset
|
139 %! assert(j,[1,1,2,3,3,3,4]) |