changeset 27238:177be3c01238

setxor.m: Accept a "legacy" flag for Matlab compatibility. * NEWS: Announce "legacy" flag. * setxor.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. Adjust orientation of outputs ia, ib based on optlegacy and isrowvec. Add BIST test for "legacy" input.
author Rik <rik@octave.org>
date Thu, 11 Jul 2019 19:55:53 -0700
parents 67e5e997a3bf
children bee80e27dcc5
files NEWS scripts/set/setxor.m
diffstat 2 files changed, 36 insertions(+), 8 deletions(-) [+]
line wrap: on
line diff
--- a/NEWS	Thu Jul 11 15:29:38 2019 -0700
+++ b/NEWS	Thu Jul 11 19:55:53 2019 -0700
@@ -58,9 +58,10 @@
   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 all outputs to match Matlab releases prior to R2012b.
+- The functions `intersect`, `setxor`, `union`, now accept a `"legacy"`
+  flag which changes the index values (second and third outputs) as well
+  as the 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/setxor.m	Thu Jul 11 15:29:38 2019 -0700
+++ b/scripts/set/setxor.m	Thu Jul 11 19:55:53 2019 -0700
@@ -21,6 +21,7 @@
 ## -*- texinfo -*-
 ## @deftypefn  {} {@var{c} =} setxor (@var{a}, @var{b})
 ## @deftypefnx {} {@var{c} =} setxor (@var{a}, @var{b}, "rows")
+## @deftypefnx {} {@var{c} =} setxor (@dots{}, "legacy")
 ## @deftypefnx {} {[@var{c}, @var{ia}, @var{ib}] =} setxor (@dots{})
 ##
 ## Return the unique elements exclusive to sets @var{a} or @var{b} sorted in
@@ -34,23 +35,32 @@
 ## to sets @var{a} and @var{b}.  The inputs must be 2-D matrices to use this
 ## option.
 ##
-## If requested, return index vectors @var{ia} and @var{ib} such that
-## @code{@var{a}(@var{ia})} and @code{@var{b}(@var{ib})} are disjoint sets
+## The optional outputs @var{ia} and @var{ib} are column index vectors such
+## that @code{@var{a}(@var{ia})} and @code{@var{b}(@var{ib})} are disjoint sets
 ## whose union is @var{c}.
 ##
+## Programming Note: The input flag @qcode{"legacy"} changes the algorithm
+## to be compatible with @sc{matlab} releases prior to R2012b.
+##
 ## @seealso{unique, union, intersect, setdiff, ismember}
 ## @end deftypefn
 
 function [c, ia, ib] = setxor (a, b, varargin)
 
-  if (nargin < 2 || nargin > 3)
+  if (nargin < 2 || nargin > 4)
     print_usage ();
   endif
 
   [a, b] = validsetargs ("setxor", a, b, varargin{:});
 
-  by_rows = nargin == 3;
-  isrowvec = isrow (a) && isrow (b);
+  by_rows = any (strcmp ("rows", varargin));
+  optlegacy = any (strcmp ("legacy", varargin));
+
+  if (optlegacy)
+    isrowvec = ! iscolumn (a) || ! iscolumn (b);
+  else
+    isrowvec = isrow (a) && isrow (b);
+  endif
 
   ## Form A and B into sets.
   if (nargout > 1)
@@ -99,6 +109,10 @@
     if (nargout > 1)
       ia = ia(i(i <= na));
       ib = ib(i(i > na) - na);
+      if (optlegacy && isrowvec)
+        ia = ia(:).';
+        ib = ib(:).';
+      endif
     endif
   endif
 
@@ -166,3 +180,16 @@
 %! b = a;
 %! b(1,1,1) = 2;
 %! assert (intersect (a, b), sort (a(2:end)'));
+
+## Test "legacy" input
+%!test
+%! a = [5 1 3 3 3];
+%! b = [4 1 2 2];
+%! [c,ia,ib] = setxor (a,b);
+%! assert (c, [2, 3, 4, 5]);
+%! assert (ia, [3; 1]);
+%! assert (ib, [3; 1]);
+%! [c,ia,ib] = setxor (a,b, "legacy");
+%! assert (c, [2, 3, 4, 5]);
+%! assert (ia, [5, 1]);
+%! assert (ib, [4, 1]);