comparison scripts/set/union.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 d63878346099
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} {} union (@var{a}, @var{b}) 21 ## @deftypefn {Function File} {@var{c} =} union (@var{a}, @var{b})
22 ## @deftypefnx {Function File} {} union (@var{a}, @var{b}, "rows") 22 ## @deftypefnx {Function File} {@var{c} =} union (@var{a}, @var{b}, "rows")
23 ## @deftypefnx {Function File} {[@var{c}, @var{ia}, @var{ib}] =} union (@var{a}, @var{b}) 23 ## @deftypefnx {Function File} {[@var{c}, @var{ia}, @var{ib}] =} union (@dots{})
24 ## 24 ##
25 ## Return the set of elements that are in either of the sets @var{a} and 25 ## Return the elements that are in either @var{a} or @var{b} sorted in
26 ## @var{b}. @var{a}, @var{b} may be cell arrays of strings. 26 ## ascending order with duplicates removed.
27 ## For example:
28 ## 27 ##
29 ## @example 28 ## If @var{a} and @var{b} are both column vectors return a column vector;
30 ## @group 29 ## Otherwise, return a row vector. The inputs may also be cell arrays of
31 ## union ([1, 2, 4], [2, 3, 5]) 30 ## strings.
32 ## @result{} [1, 2, 3, 4, 5]
33 ## @end group
34 ## @end example
35 ## 31 ##
36 ## If the optional third input argument is the string @qcode{"rows"} then 32 ## If the optional input @qcode{"rows"} is given then return rows that are in
37 ## each row of the matrices @var{a} and @var{b} will be considered as a 33 ## either @var{a} or @var{b}. The inputs must be 2-D matrices to use this
38 ## single set element. For example: 34 ## option.
35 ##
36 ## The optional outputs @var{ia} and @var{ib} are index vectors such that
37 ## @code{@var{a}(@var{ia})} and @code{@var{b}(@var{ib})} are disjoint sets
38 ## whose union is @var{c}.
39 ## 39 ##
40 ## @example 40 ## @seealso{unique, intersect, setdiff, setxor, ismember}
41 ## @group
42 ## union ([1, 2; 2, 3], [1, 2; 3, 4], "rows")
43 ## @result{} 1 2
44 ## 2 3
45 ## 3 4
46 ## @end group
47 ## @end example
48 ##
49 ## The optional outputs @var{ia} and @var{ib} are index vectors such that
50 ## @code{a(ia)} and @code{b(ib)} are disjoint sets whose union is @var{c}.
51 ##
52 ## @seealso{intersect, setdiff, unique}
53 ## @end deftypefn 41 ## @end deftypefn
54 42
55 ## Author: jwe 43 ## Author: jwe
56 44
57 function [y, ia, ib] = union (a, b, varargin) 45 function [y, ia, ib] = union (a, b, varargin)
58 46
59 if (nargin < 2 || nargin > 3) 47 if (nargin < 2 || nargin > 3)
60 print_usage (); 48 print_usage ();
61 endif 49 endif
62 50
63 [a, b] = validargs ("union", a, b, varargin{:}); 51 [a, b] = validsetargs ("union", a, b, varargin{:});
64 52
65 if (nargin == 2) 53 by_rows = nargin == 3;
54 iscol = isvector (a) && isvector (b) && iscolumn (a) && iscolumn (b);
55
56 if (by_rows)
57 y = [a; b];
58 else
66 y = [a(:); b(:)]; 59 y = [a(:); b(:)];
67 na = numel (a); nb = numel (b); 60 ## Adjust output orientation for Matlab compatibility
68 if (rows (a) == 1 || rows (b) == 1) 61 if (! iscol)
69 y = y.'; 62 y = y.';
70 endif 63 endif
71 else
72 y = [a; b];
73 na = rows (a); nb = rows (b);
74 endif 64 endif
75 65
76 if (nargout == 1) 66 if (nargout <= 1)
77 y = unique (y, varargin{:}); 67 y = unique (y, varargin{:});
78 else 68 else
79 [y, i] = unique (y, varargin{:}); 69 [y, idx] = unique (y, varargin{:});
80 ia = i(i <= na); 70 na = numel (a);
81 ib = i(i > na) - na; 71 ia = idx(idx <= na);
72 ib = idx(idx > na) - na;
82 endif 73 endif
83 74
84 endfunction 75 endfunction
85 76
86 77
87 %!assert (union ([1, 2, 4], [2, 3, 5]), [1, 2, 3, 4, 5]); 78 %!assert (union ([1, 2, 4], [2, 3, 5]), [1, 2, 3, 4, 5])
88 %!assert (union ([1; 2; 4], [2, 3, 5]), [1, 2, 3, 4, 5]); 79 %!assert (union ([1; 2; 4], [2, 3, 5]), [1, 2, 3, 4, 5])
89 %!assert (union ([1, 2, 3], [5; 7; 9]), [1, 2, 3, 5, 7, 9]); 80 %!assert (union ([1; 2; 4], [2; 3; 5]), [1; 2; 3; 4; 5])
81 %!assert (union ([1, 2, 3], [5; 7; 9]), [1, 2, 3, 5, 7, 9])
82
83 ## Test multi-dimensional arrays
84 %!test
85 %! a = rand (3,3,3);
86 %! b = a;
87 %! b(1,1,1) = 2;
88 %! assert (union (a, b), sort ([a(1:end), 2]));
90 89
91 %!test 90 %!test
92 %! a = [3, 1, 4, 1, 5]; b = [1, 2, 3, 4]; 91 %! a = [3, 1, 4, 1, 5];
92 %! b = [1, 2, 3, 4];
93 %! [y, ia, ib] = union (a, b.'); 93 %! [y, ia, ib] = union (a, b.');
94 %! assert (y, [1, 2, 3, 4, 5]); 94 %! assert (y, [1, 2, 3, 4, 5]);
95 %! assert (y, sort ([a(ia), b(ib)])); 95 %! assert (y, sort ([a(ia), b(ib)]));
96 96
97 %!error union (1)
98 %!error union (1, 2, 3)
99 97
98 %% Test common input validation for set routines contained in validsetargs
99 %!error <cell array of strings cannot be combined> union ({"a"}, 1)
100 %!error <A and B must be arrays or cell arrays> union (@sin, 1)
101 %!error <invalid option: columns> union (1, 2, "columns")
102 %!error <cells not supported with "rows"> union ({"a"}, {"b"}, "rows")
103 %!error <A and B must be arrays or cell arrays> union (@sin, 1, "rows")
104 %!error <A and B must be 2-dimensional matrices> union (rand(2,2,2), 1, "rows")
105 %!error <number of columns in A and B must match> union ([1 2], 1, "rows")
106