comparison scripts/set/setdiff.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 1bf0ce0930be
comparison
equal deleted inserted replaced
11921:166a195399f7 11922:746f13936eee
1 ## Copyright (C) 2000, 2005, 2006, 2007 Paul Kienzle 1 ## Copyright (C) 2000, 2005, 2006, 2007 Paul Kienzle
2 ## Copyright (C) 2008 Jaroslav Hajek
2 ## 3 ##
3 ## This file is part of Octave. 4 ## This file is part of Octave.
4 ## 5 ##
5 ## Octave is free software; you can redistribute it and/or modify it 6 ## Octave is free software; you can redistribute it and/or modify it
6 ## under the terms of the GNU General Public License as published by 7 ## under the terms of the GNU General Public License as published by
17 ## <http://www.gnu.org/licenses/>. 18 ## <http://www.gnu.org/licenses/>.
18 19
19 ## -*- texinfo -*- 20 ## -*- texinfo -*-
20 ## @deftypefn {Function File} {} setdiff (@var{a}, @var{b}) 21 ## @deftypefn {Function File} {} setdiff (@var{a}, @var{b})
21 ## @deftypefnx {Function File} {} setdiff (@var{a}, @var{b}, "rows") 22 ## @deftypefnx {Function File} {} setdiff (@var{a}, @var{b}, "rows")
23 ## @deftypefnx {Function File} {[@var{c}, @var{i}] = } setdiff (@var{a}, @var{b})
22 ## Return the elements in @var{a} that are not in @var{b}, sorted in 24 ## Return the elements in @var{a} that are not in @var{b}, sorted in
23 ## ascending order. If @var{a} and @var{b} are both column vectors 25 ## ascending order. If @var{a} and @var{b} are both column vectors
24 ## return a column vector, otherwise return a row vector. 26 ## return a column vector, otherwise return a row vector.
25 ## 27 ##
26 ## Given the optional third argument @samp{"rows"}, return the rows in 28 ## Given the optional third argument @samp{"rows"}, return the rows in
27 ## @var{a} that are not in @var{b}, sorted in ascending order by rows. 29 ## @var{a} that are not in @var{b}, sorted in ascending order by rows.
30 ##
31 ## If requested, return @var{i} such that @code{c = a(i)}.
28 ## @seealso{unique, union, intersect, setxor, ismember} 32 ## @seealso{unique, union, intersect, setxor, ismember}
29 ## @end deftypefn 33 ## @end deftypefn
30 34
31 ## Author: Paul Kienzle 35 ## Author: Paul Kienzle
32 ## Adapted-by: jwe 36 ## Adapted-by: jwe
33 37
34 function c = setdiff (a, b, byrows_arg) 38 function [c, i] = setdiff (a, b, byrows_arg)
35 39
36 if (nargin < 2 || nargin > 3) 40 if (nargin < 2 || nargin > 3)
37 print_usage (); 41 print_usage ();
38 endif 42 endif
39 43
48 byrows = true; 52 byrows = true;
49 endif 53 endif
50 endif 54 endif
51 55
52 if (byrows) 56 if (byrows)
53 c = unique (a, "rows"); 57 if (nargout > 1)
58 [c, i] = unique (a, "rows");
59 else
60 c = unique (a, "rows");
61 endif
54 if (! isempty (c) && ! isempty (b)) 62 if (! isempty (c) && ! isempty (b))
55 ## Form a and b into combined set. 63 ## Form a and b into combined set.
56 b = unique (b, "rows"); 64 b = unique (b, "rows");
57 [dummy, idx] = sortrows ([c; b]); 65 [dummy, idx] = sortrows ([c; b]);
58 ## Eliminate those elements of a that are the same as in b. 66 ## Eliminate those elements of a that are the same as in b.
59 dups = find (all (dummy(1:end-1,:) == dummy(2:end,:), 2)); 67 dups = find (all (dummy(1:end-1,:) == dummy(2:end,:), 2));
60 c(idx(dups),:) = []; 68 c(idx(dups),:) = [];
69 if (nargout > 1)
70 i(idx(dups),:) = [];
71 endif
61 endif 72 endif
62 else 73 else
63 c = unique (a); 74 if (nargout > 1)
75 [c, i] = unique (a);
76 else
77 c = unique (a);
78 endif
64 if (! isempty (c) && ! isempty (b)) 79 if (! isempty (c) && ! isempty (b))
65 ## Form a and b into combined set. 80 ## Form a and b into combined set.
66 b = unique (b); 81 b = unique (b);
67 [dummy, idx] = sort ([c(:); b(:)]); 82 [dummy, idx] = sort ([c(:); b(:)]);
68 ## Eliminate those elements of a that are the same as in b. 83 ## Eliminate those elements of a that are the same as in b.
70 dups = find (strcmp (dummy(1:end-1), dummy(2:end))); 85 dups = find (strcmp (dummy(1:end-1), dummy(2:end)));
71 else 86 else
72 dups = find (dummy(1:end-1) == dummy(2:end)); 87 dups = find (dummy(1:end-1) == dummy(2:end));
73 endif 88 endif
74 c(idx(dups)) = []; 89 c(idx(dups)) = [];
90 if (nargout > 1)
91 i(idx(dups)) = [];
92 endif
75 ## Reshape if necessary. 93 ## Reshape if necessary.
76 if (size (c, 1) != 1 && size (b, 1) == 1) 94 if (size (c, 1) != 1 && size (b, 1) == 1)
77 c = c.'; 95 c = c.';
78 endif 96 endif
79 endif 97 endif
86 %!assert(setdiff(["b";"z";"b";"z"],["b";"c";"b"]), "z") 104 %!assert(setdiff(["b";"z";"b";"z"],["b";"c";"b"]), "z")
87 %!assert(setdiff([1, 1; 2, 2; 3, 3; 4, 4], [1, 1; 2, 2; 4, 4], "rows"), [3 3]) 105 %!assert(setdiff([1, 1; 2, 2; 3, 3; 4, 4], [1, 1; 2, 2; 4, 4], "rows"), [3 3])
88 %!assert(setdiff([1; 2; 3; 4], [1; 2; 4], "rows"), 3) 106 %!assert(setdiff([1; 2; 3; 4], [1; 2; 4], "rows"), 3)
89 %!assert(setdiff([1, 2; 3, 4], [1, 2; 3, 6], "rows"), [3, 4]) 107 %!assert(setdiff([1, 2; 3, 4], [1, 2; 3, 6], "rows"), [3, 4])
90 %!assert(setdiff({"one","two";"three","four"},{"one","two";"three","six"}), {"four"}) 108 %!assert(setdiff({"one","two";"three","four"},{"one","two";"three","six"}), {"four"})
109
110 %!test
111 %! a = [3, 1, 4, 1, 5]; b = [1, 2, 3, 4];
112 %! [y, i] = setdiff (a, b.');
113 %! assert(y, [5]);
114 %! assert(y, a(i));