Mercurial > hg > octave-lyh
diff scripts/set/setxor.m @ 7920:e56bb65186f6
improve set functions for Matlab compatibility
author | Jaroslav Hajek <highegg@gmail.com> |
---|---|
date | Wed, 25 Jun 2008 22:11:07 +0200 |
parents | a1dbe9d80eee |
children | cadc73247d65 |
line wrap: on
line diff
--- a/scripts/set/setxor.m +++ b/scripts/set/setxor.m @@ -1,4 +1,5 @@ ## Copyright (C) 2000, 2006, 2007 Paul Kienzle +## Copyright (C) 2008 Jaroslav Hajek ## ## This file is part of Octave. ## @@ -18,22 +19,38 @@ ## -*- texinfo -*- ## @deftypefn {Function File} {} setxor (@var{a}, @var{b}) +## @deftypefnx {Function File} {} setxor (@var{a}, @var{b}, 'rows') ## ## Return the elements exclusive to @var{a} or @var{b}, sorted in ascending ## order. If @var{a} and @var{b} are both column vectors return a column ## vector, otherwise return a row vector. ## +## @deftypefnx {Function File} {[@var{c}, @var{ia}, @var{ib}] =} setxor (@var{a}, @var{b}) +## +## Return index vectors @var{ia} and @var{ib} such that @code{a==c(ia)} and +## @code{b==c(ib)}. +## ## @seealso{unique, union, intersect, setdiff, ismember} ## @end deftypefn -function c = setxor (a, b) - if (nargin != 2) +function [c, ia, ib] = setxor (a, b, varargin) + + if (nargin < 2 || nargin > 3) print_usage (); endif + if (nargin == 3 && ! strcmpi (varargin{1}, "rows")) + error ("setxor: if a third input argument is present, it must be the string 'rows'"); + endif + ## Form A and B into sets. - a = unique (a); - b = unique (b); + if (nargout > 1) + [a, ia] = unique (a, varargin{:}); + [b, ib] = unique (b, varargin{:}); + else + a = unique (a, varargin{:}); + b = unique (b, varargin{:}); + endif if (isempty (a)) c = b; @@ -41,16 +58,39 @@ c = a; else ## Reject duplicates. - c = sort ([a(:); b(:)]); - n = length (c); - idx = find (c(1:n-1) == c(2:n)); - if (! isempty (idx)) - c([idx, idx+1]) = []; - endif - if (size (a, 1) == 1 || size (b, 1) == 1) - c = c.'; + if (nargin > 2) + na = rows (a); nb = rows (b); + [c, i] = sortrows ([a; b]); + n = rows (c); + idx = find (all (c(1:n-1) == c(2:n), 2)); + if (! isempty (idx)) + c([idx, idx+1],:) = []; + i([idx, idx+1],:) = []; + endif + else + na = numel (a); nb = numel (b); + [c, i] = sort ([a(:); b(:)]); + n = length (c); + idx = find (c(1:n-1) == c(2:n)); + if (! isempty (idx)) + c([idx, idx+1]) = []; + i([idx, idx+1]) = []; + endif + if (size (a, 1) == 1 || size (b, 1) == 1) + c = c.'; + endif endif endif + if (nargout > 1) + ia = ia(i(i <= na)); + ib = ib(i(i > na) - na); + endif + endfunction %!assert(setxor([1,2,3],[2,3,4]),[1,4]) +%!test +%! a = [3, 1, 4, 1, 5]; b = [1, 2, 3, 4]; +%! [y, ia, ib] = setxor (a, b.'); +%! assert(y, [2, 5]); +%! assert(y, sort([a(ia), b(ib)]));