Mercurial > octave-dspies
comparison scripts/set/setdiff.m @ 19003:d00f6b09258f @
Overhaul functions in scripts/set directory.
* set.txi: Rewrite documentation for set functions.
* intersect.m: Rewrite docstring. Use by_rows variable for code clarity.
Return output orientation which is compatible with Matlab. Add %!tests for
output orientation and N-dimensional inputs.
* setdiff.m: Rewrite docstring. Use by_rows variable for code clarity.
Rename output i to ia to clarify it is an index into the set a.
Return output orientation which is compatible with Matlab. Add %!tests for
N-dimensional inputs.
* setxor.m: Rewrite docstring. Use by_rows variable for code clarity.
Return output orientation which is compatible with Matlab. Add %!tests for
output orientation and N-dimensional inputs.
* union.m: Rewrite docstring. Use by_rows variable for code clarity.
Return output orientation which is compatible with Matlab. Add %!tests for
output orientation and N-dimensional inputs. Add %!tests for validsetargs
which are common to all set functions.
* unique.m: Rewrite docstring. Verify that input is numeric or cell array
of strings. Avoid computing idx for optional i,j outputs unless required.
Add %!error tests for input validation.
* ismember.m: Rewrite docstring. Use input variable 'a' instead of 'A' for
conformance with rest of set functions. Rename output index variable to
s_idx for clarity that it is an index into the set s.
* powerset.m: Rewrite doctring. Add input validation on nargin. Add %!error
input validation tests.
* module.mk: Include validsetargs.m in build system.
* validsetargs.m: Function renamed from validargs which was too general.
* validargs.m: Function renamed to validsetargs.
author | Rik <rik@octave.org> |
---|---|
date | Mon, 11 Aug 2014 09:39:45 -0700 |
parents | 30d8501a857a |
children |
comparison
equal
deleted
inserted
replaced
19001:391e080ae810 | 19003:d00f6b09258f |
---|---|
16 ## You should have received a copy of the GNU General Public License | 16 ## You should have received a copy of the GNU General Public License |
17 ## along with Octave; see the file COPYING. If not, see | 17 ## along with Octave; see the file COPYING. If not, see |
18 ## <http://www.gnu.org/licenses/>. | 18 ## <http://www.gnu.org/licenses/>. |
19 | 19 |
20 ## -*- texinfo -*- | 20 ## -*- texinfo -*- |
21 ## @deftypefn {Function File} {} setdiff (@var{a}, @var{b}) | 21 ## @deftypefn {Function File} {@var{c} =} setdiff (@var{a}, @var{b}) |
22 ## @deftypefnx {Function File} {} setdiff (@var{a}, @var{b}, "rows") | 22 ## @deftypefnx {Function File} {@var{c} =} setdiff (@var{a}, @var{b}, "rows") |
23 ## @deftypefnx {Function File} {[@var{c}, @var{i}] =} setdiff (@var{a}, @var{b}) | 23 ## @deftypefnx {Function File} {[@var{c}, @var{ia}] =} setdiff (@dots{}) |
24 ## 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 |
25 ## ascending order. If @var{a} and @var{b} are both column vectors | 25 ## ascending order. |
26 ## return a column vector, otherwise return a row vector. | |
27 ## @var{a}, @var{b} may be cell arrays of string(s). | |
28 ## | 26 ## |
29 ## Given the optional third argument @qcode{"rows"}, return the rows in | 27 ## If @var{a} and @var{b} are both column vectors return a column vector; |
30 ## @var{a} that are not in @var{b}, sorted in ascending order by rows. | 28 ## Otherwise, return a row vector. The inputs may also be cell arrays of |
29 ## strings. | |
31 ## | 30 ## |
32 ## If requested, return @var{i} such that @code{c = a(i)}. | 31 ## If the optional input @qcode{"rows"} is given then return the rows in |
32 ## @var{a} that are not in @var{b}. The inputs must be 2-D matrices to use | |
33 ## this option. | |
34 ## | |
35 ## If requested, return the index vector @var{ia} such that | |
36 ## @code{@var{c} = @var{a}(@var{ia})}. | |
33 ## @seealso{unique, union, intersect, setxor, ismember} | 37 ## @seealso{unique, union, intersect, setxor, ismember} |
34 ## @end deftypefn | 38 ## @end deftypefn |
35 | 39 |
36 ## Author: Paul Kienzle | 40 ## Author: Paul Kienzle |
37 ## Adapted-by: jwe | 41 ## Adapted-by: jwe |
38 | 42 |
39 function [c, i] = setdiff (a, b, varargin) | 43 function [c, ia] = setdiff (a, b, varargin) |
40 | 44 |
41 if (nargin < 2 || nargin > 3) | 45 if (nargin < 2 || nargin > 3) |
42 print_usage (); | 46 print_usage (); |
43 endif | 47 endif |
44 | 48 |
45 [a, b] = validargs ("setdiff", a, b, varargin{:}); | 49 [a, b] = validsetargs ("setdiff", a, b, varargin{:}); |
46 | 50 |
47 if (nargin > 2) | 51 by_rows = nargin == 3; |
52 iscol = isvector (a) && isvector (b) && iscolumn (a) && iscolumn (b); | |
53 | |
54 if (by_rows) | |
48 if (nargout > 1) | 55 if (nargout > 1) |
49 [c, i] = unique (a, "rows"); | 56 [c, ia] = unique (a, "rows"); |
50 else | 57 else |
51 c = unique (a, "rows"); | 58 c = unique (a, "rows"); |
52 endif | 59 endif |
53 if (! isempty (c) && ! isempty (b)) | 60 if (! isempty (c) && ! isempty (b)) |
54 ## Form a and b into combined set. | 61 ## Form A and B into combined set. |
55 b = unique (b, "rows"); | 62 b = unique (b, "rows"); |
56 [dummy, idx] = sortrows ([c; b]); | 63 [tmp, idx] = sortrows ([c; b]); |
57 ## Eliminate those elements of a that are the same as in b. | 64 ## Eliminate those elements of A that are the same as in B. |
58 dups = find (all (dummy(1:end-1,:) == dummy(2:end,:), 2)); | 65 dups = find (all (tmp(1:end-1,:) == tmp(2:end,:), 2)); |
59 c(idx(dups),:) = []; | 66 c(idx(dups),:) = []; |
60 if (nargout > 1) | 67 if (nargout > 1) |
61 i(idx(dups),:) = []; | 68 ia(idx(dups),:) = []; |
62 endif | 69 endif |
63 endif | 70 endif |
64 else | 71 else |
65 if (nargout > 1) | 72 if (nargout > 1) |
66 [c, i] = unique (a); | 73 [c, ia] = unique (a); |
67 else | 74 else |
68 c = unique (a); | 75 c = unique (a); |
69 endif | 76 endif |
70 if (! isempty (c) && ! isempty (b)) | 77 if (! isempty (c) && ! isempty (b)) |
71 ## Form a and b into combined set. | 78 ## Form a and b into combined set. |
72 b = unique (b); | 79 b = unique (b); |
73 [dummy, idx] = sort ([c(:); b(:)]); | 80 [tmp, idx] = sort ([c(:); b(:)]); |
74 ## Eliminate those elements of a that are the same as in b. | 81 ## Eliminate those elements of a that are the same as in b. |
75 if (iscellstr (dummy)) | 82 if (iscellstr (tmp)) |
76 dups = find (strcmp (dummy(1:end-1), dummy(2:end))); | 83 dups = find (strcmp (tmp(1:end-1), tmp(2:end))); |
77 else | 84 else |
78 dups = find (dummy(1:end-1) == dummy(2:end)); | 85 dups = find (tmp(1:end-1) == tmp(2:end)); |
79 endif | 86 endif |
80 c(idx(dups)) = []; | 87 c(idx(dups)) = []; |
81 if (nargout > 1) | 88 if (nargout > 1) |
82 i(idx(dups)) = []; | 89 ia(idx(dups)) = []; |
83 endif | 90 endif |
84 ## Reshape if necessary for Matlab compatibility. | 91 ## Reshape if necessary for Matlab compatibility. |
85 if (iscolumn (c) && ! iscolumn (b)) | 92 if (iscol) |
86 c = c.'; | 93 c = c(:); |
94 else | |
95 c = c(:).'; | |
87 endif | 96 endif |
88 endif | 97 endif |
89 endif | 98 endif |
90 | 99 |
91 endfunction | 100 endfunction |
98 %!assert (setdiff ([1; 2; 3; 4], [1; 2; 4], "rows"), 3) | 107 %!assert (setdiff ([1; 2; 3; 4], [1; 2; 4], "rows"), 3) |
99 %!assert (setdiff ([1, 2; 3, 4], [1, 2; 3, 6], "rows"), [3, 4]) | 108 %!assert (setdiff ([1, 2; 3, 4], [1, 2; 3, 6], "rows"), [3, 4]) |
100 %!assert (setdiff ({"one","two";"three","four"}, {"one","two";"three","six"}), {"four"}) | 109 %!assert (setdiff ({"one","two";"three","four"}, {"one","two";"three","six"}), {"four"}) |
101 | 110 |
102 %!test | 111 %!test |
103 %! a = [3, 1, 4, 1, 5]; b = [1, 2, 3, 4]; | 112 %! a = [3, 1, 4, 1, 5]; |
104 %! [y, i] = setdiff (a, b.'); | 113 %! b = [1, 2, 3, 4]; |
105 %! assert (y, [5]); | 114 %! [c, ia] = setdiff (a, b'); |
106 %! assert (y, a(i)); | 115 %! assert (c, [5]); |
116 %! assert (c, a(ia)); | |
107 | 117 |
108 %% Test output orientation compatibility (bug #42577) | 118 %% Test output orientation compatibility (bug #42577) |
109 %!assert (setdiff ([1:5], 2), [1,3,4,5]) | 119 %!assert (setdiff ([1:5], 2), [1,3,4,5]) |
110 %!assert (setdiff ([1:5]', 2), [1;3;4;5]) | 120 %!assert (setdiff ([1:5]', 2), [1;3;4;5]) |
111 %!assert (setdiff ([1:5], [2:3]), [1,4,5]) | 121 %!assert (setdiff ([1:5], [2:3]), [1,4,5]) |
112 %!assert (setdiff ([1:5], [2:3]'), [1,4,5]) | 122 %!assert (setdiff ([1:5], [2:3]'), [1,4,5]) |
113 %!assert (setdiff ([1:5]', [2:3]), [1,4,5]) | 123 %!assert (setdiff ([1:5]', [2:3]), [1,4,5]) |
114 %!assert (setdiff ([1:5]', [2:3]'), [1;4;5]) | 124 %!assert (setdiff ([1:5]', [2:3]'), [1;4;5]) |
115 | 125 |
116 %% Test input validation | 126 %!test |
117 %!error setdiff () | 127 %! a = rand (3,3,3); |
118 %!error setdiff (1) | 128 %! b = a(1); |
119 %!error setdiff (1,2,3,4) | 129 %! assert (setdiff (a, b), sort (a(2:end))); |
120 | 130 |