Mercurial > octave
changeset 27237:67e5e997a3bf
setdiff.m: Accept a "legacy" flag for Matlab compatibility.
* NEWS: Announce change to setdiff return values when given "rows" argument.
Announce "legacy" flag.
* setdiff.m Add new calling form and explanation of "legacy" option to
docstring. Allow up to 4 inputs in input validation. Check for "legacy"
in input options and set variable optlegacy. Set variable isrowvec based
on optlegacy and orientation of inputs. Add BIST tests for "rows" and "legacy"
inputs.
author | Rik <rik@octave.org> |
---|---|
date | Thu, 11 Jul 2019 15:29:38 -0700 |
parents | d29a12e8b6d9 |
children | 177be3c01238 |
files | NEWS scripts/set/setdiff.m |
diffstat | 2 files changed, 64 insertions(+), 12 deletions(-) [+] |
line wrap: on
line diff
--- a/NEWS Thu Jul 11 15:05:30 2019 -0700 +++ b/NEWS Thu Jul 11 15:29:38 2019 -0700 @@ -53,9 +53,14 @@ behavior, or Matlab behavior from releases prior to R2012b, can be obtained by using the `"legacy"` flag. +- The function `setdiff` with the `"rows"` argument now returns Matlab + compatible results. The previous Octave behavior, or Matlab behavior + from releases prior to R2012b, can be obtained by using the `"legacy"` + flag. + - The functions `intersect`, `union` now accept a `"legacy"` flag which changes the index values (second and third outputs) as well as the - orientation of the outputs to match Matlab releases prior to R2012b. + orientation of all outputs to match Matlab releases prior to R2012b. - Complex RESTful web services can now be accessed by the `webread` and `webwrite` functions alongside with the `weboptions` structure. One
--- a/scripts/set/setdiff.m Thu Jul 11 15:05:30 2019 -0700 +++ b/scripts/set/setdiff.m Thu Jul 11 15:29:38 2019 -0700 @@ -20,6 +20,7 @@ ## -*- texinfo -*- ## @deftypefn {} {@var{c} =} setdiff (@var{a}, @var{b}) ## @deftypefnx {} {@var{c} =} setdiff (@var{a}, @var{b}, "rows") +## @deftypefnx {} {@var{c} =} setdiff (@dots{}, "legacy") ## @deftypefnx {} {[@var{c}, @var{ia}] =} setdiff (@dots{}) ## Return the unique elements in @var{a} that are not in @var{b} sorted in ## ascending order. @@ -33,6 +34,10 @@ ## ## If requested, return the index vector @var{ia} such that ## @code{@var{c} = @var{a}(@var{ia})}. +## +## Programming Note: The input flag @qcode{"legacy"} changes the algorithm +## to be compatible with @sc{matlab} releases prior to R2012b. +## ## @seealso{unique, union, intersect, setxor, ismember} ## @end deftypefn @@ -41,24 +46,30 @@ function [c, ia] = setdiff (a, b, varargin) - if (nargin < 2 || nargin > 3) + if (nargin < 2 || nargin > 4) print_usage (); endif [a, b] = validsetargs ("setdiff", a, b, varargin{:}); - by_rows = nargin == 3; - isrowvec = isrow (a); + by_rows = any (strcmp ("rows", varargin)); + optlegacy = any (strcmp ("legacy", varargin)); + + if (optlegacy) + isrowvec = ! iscolumn (a) || ! iscolumn (b); + else + isrowvec = isrow (a); + endif if (by_rows) if (nargout > 1) - [c, ia] = unique (a, "rows"); + [c, ia] = unique (a, varargin{:}); else - c = unique (a, "rows"); + c = unique (a, varargin{:}); endif if (! isempty (c) && ! isempty (b)) ## Form A and B into combined set. - b = unique (b, "rows"); + b = unique (b, varargin{:}); [tmp, idx] = sortrows ([c; b]); ## Eliminate those elements of A that are the same as in B. dups = find (all (tmp(1:end-1,:) == tmp(2:end,:), 2)); @@ -69,9 +80,9 @@ endif else if (nargout > 1) - [c, ia] = unique (a); + [c, ia] = unique (a, varargin{:}); else - c = unique (a); + c = unique (a, varargin{:}); endif if (! isempty (c) && ! isempty (b)) ## Form a and b into combined set. @@ -84,15 +95,18 @@ dups = find (tmp(1:end-1) == tmp(2:end)); endif c(idx(dups)) = []; - if (nargout > 1) - ia(idx(dups)) = []; - endif ## Reshape if necessary for Matlab compatibility. if (isrowvec) c = c(:).'; else c = c(:); endif + if (nargout > 1) + ia(idx(dups)) = []; + if (optlegacy && isrowvec) + ia = ia(:).'; + endif + endif endif endif @@ -126,3 +140,36 @@ %! a = rand (3,3,3); %! b = a(1); %! assert (setdiff (a, b), sort (a(2:end)')); + +## Test "rows" compatibility +%!test +%! a = [7 9 7; 0 0 0; 7 9 7; 5 5 5; 1 4 5]; +%! b = [0 0 0; 5 5 5]; +%! [c, ia] = setdiff (a, b, "rows"); +%! assert (c, [1, 4 ,5; 7, 9 7]); +%! assert (ia, [5; 1]); + +## Test "legacy" option +%!test +%! a = [3, 6, 2, 1, 5, 1, 1]; +%! b = [2, 4, 6]; +%! [c, ia] = setdiff (a, b); +%! assert (c, [1, 3, 5]); +%! assert (ia, [4; 1; 5]); +%! [c, ia] = setdiff (a, b, "legacy"); +%! assert (c, [1, 3, 5]); +%! assert (ia, [7, 1, 5]); + +## "legacy" + "rows" compatibility +%!test +%! a = [7 9 7; 0 0 0; 7 9 7; 5 5 5; 1 4 5]; +%! b = [0 0 0; 5 5 5]; +%! [c, ia] = setdiff (a, b, "rows", "legacy"); +%! assert (c, [1, 4 ,5; 7, 9 7]); +%! assert (ia, [5; 3]); + +## Output orientation with "legacy" option +%!assert (size (setdiff ([1:5], [2:3], "legacy")), [1, 3]) +%!assert (size (setdiff ([1:5]', [2:3], "legacy")), [1, 3]) +%!assert (size (setdiff ([1:5], [2:3]', "legacy")), [1, 3]) +%!assert (size (setdiff ([1:5]', [2:3]', "legacy")), [3, 1])