comparison scripts/set/intersect.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} {} intersect (@var{a}, @var{b}) 21 ## @deftypefn {Function File} {@var{c} =} intersect (@var{a}, @var{b})
22 ## @deftypefnx {Function File} {[@var{c}, @var{ia}, @var{ib}] =} intersect (@var{a}, @var{b}) 22 ## @deftypefnx {Function File} {@var{c} =} intersect (@var{a}, @var{b}, "rows")
23 ## @deftypefnx {Function File} {[@var{c}, @var{ia}, @var{ib}] =} intersect (@dots{})
23 ## 24 ##
24 ## Return the elements in both @var{a} and @var{b}, sorted in ascending 25 ## Return the elements common to both @var{a} and @var{b} sorted in ascending
25 ## order. If @var{a} and @var{b} are both column vectors return a column 26 ## order.
26 ## vector, otherwise return a row vector.
27 ## @var{a}, @var{b} may be cell arrays of string(s).
28 ## 27 ##
29 ## Return index vectors @var{ia} and @var{ib} such that @code{a(ia)==c} and 28 ## If @var{a} and @var{b} are both column vectors then return a column vector;
30 ## @code{b(ib)==c}. 29 ## Otherwise, return a row vector. The inputs may also be cell arrays of
30 ## strings.
31 ##
32 ## If the optional input @qcode{"rows"} is given then return the common rows of
33 ## @var{a} and @var{b}. The inputs must be 2-D matrices to use this option.
34 ##
35 ## If requested, return index vectors @var{ia} and @var{ib} such that
36 ## @code{@var{c} = @var{a}(@var{ia})} and @code{@var{c} = @var{b}(@var{ib})}.
31 ## 37 ##
32 ## @end deftypefn 38 ## @end deftypefn
33 ## @seealso{unique, union, setxor, setdiff, ismember} 39 ## @seealso{unique, union, setdiff, setxor, ismember}
34 40
35 function [c, ia, ib] = intersect (a, b, varargin) 41 function [c, ia, ib] = intersect (a, b, varargin)
36 42
37 if (nargin < 2 || nargin > 3) 43 if (nargin < 2 || nargin > 3)
38 print_usage (); 44 print_usage ();
39 endif 45 endif
40 46
41 [a, b] = validargs ("intersect", a, b, varargin{:}); 47 [a, b] = validsetargs ("intersect", a, b, varargin{:});
42 48
43 if (isempty (a) || isempty (b)) 49 if (isempty (a) || isempty (b))
44 c = ia = ib = []; 50 c = ia = ib = [];
45 else 51 else
46 ## form a and b into sets 52 by_rows = nargin == 3;
53 iscol = isvector (a) && isvector (b) && iscolumn (a) && iscolumn (b);
54
55 ## Form A and B into sets
47 if (nargout > 1) 56 if (nargout > 1)
48 [a, ja] = unique (a, varargin{:}); 57 [a, ja] = unique (a, varargin{:});
49 [b, jb] = unique (b, varargin{:}); 58 [b, jb] = unique (b, varargin{:});
50 else 59 else
51 a = unique (a, varargin{:}); 60 a = unique (a, varargin{:});
52 b = unique (b, varargin{:}); 61 b = unique (b, varargin{:});
53 endif 62 endif
54 63
55 if (nargin > 2) 64 if (by_rows)
56 c = [a; b]; 65 c = [a; b];
57 [c, ic] = sortrows (c); 66 [c, ic] = sortrows (c);
58 ii = find (all (c(1:end-1,:) == c(2:end,:), 2)); 67 ii = find (all (c(1:end-1,:) == c(2:end,:), 2));
59 c = c(ii,:); 68 c = c(ii,:);
60 len_a = rows (a); 69 len_a = rows (a);
61 else 70 else
62 c = [a(:); b(:)]; 71 c = [a(:); b(:)];
63 [c, ic] = sort (c); # [a(:);b(:)](ic) == c 72 [c, ic] = sort (c); # [a(:);b(:)](ic) == c
64 if (iscellstr (c)) 73 if (iscellstr (c))
65 ii = find (strcmp (c(1:end-1), c(2:end))); 74 ii = find (strcmp (c(1:end-1), c(2:end)));
66 else 75 else
67 ii = find (c(1:end-1) == c(2:end)); 76 ii = find (c(1:end-1) == c(2:end));
68 endif 77 endif
69 c = c(ii); 78 c = c(ii);
70 len_a = length (a); 79 len_a = length (a);
71 endif 80 endif
72 81
73 if (nargout > 1) 82 if (nargout > 1)
74 ia = ja(ic(ii)); # a(ia) == c 83 ia = ja(ic(ii)); # a(ia) == c
75 ib = jb(ic(ii+1) - len_a); # b(ib) == c 84 ib = jb(ic(ii+1) - len_a); # b(ib) == c
76 endif 85 endif
77 86
78 if (nargin == 2 && (rows (b) == 1 || rows (a) == 1)) 87 ## Adjust output orientation for Matlab compatibility
88 if (! by_rows && ! iscol)
79 c = c.'; 89 c = c.';
80 endif 90 endif
81 endif 91 endif
82 92
83 endfunction 93 endfunction
84 94
85 95
86 %!# Test the routine for index vectors ia and ib 96 ## Test orientation of output
97 %!shared a,b
98 %! a = 1:4;
99 %! b = 2:5;
100
101 %!assert (size (intersect (a, b)), [1 3])
102 %!assert (size (intersect (a', b)), [1 3])
103 %!assert (size (intersect (a, b')), [1 3])
104 %!assert (size (intersect (a', b')), [3 1])
105
106 ## Test multi-dimensional arrays
107 %!test
108 %! a = rand (3,3,3);
109 %! b = a;
110 %! b(1,1,1) = 2;
111 %! assert (intersect (a, b), sort (a(2:end)));
112
113 ## Test the routine for index vectors ia and ib
87 %!test 114 %!test
88 %! a = [3 2 4 5 7 6 5 1 0 13 13]; 115 %! a = [3 2 4 5 7 6 5 1 0 13 13];
89 %! b = [3 5 12 1 1 7]; 116 %! b = [3 5 12 1 1 7];
90 %! [c,ia,ib] = intersect (a, b); 117 %! [c,ia,ib] = intersect (a, b);
91 %! assert (c, [1 3 5 7]); 118 %! assert (c, [1 3 5 7]);