changeset 19222:c3611856cdd4

xor.m: Extend to handle more than 2 arguments as a reduction operator. * xor.m: Redo docstring. Create internal function __xor__ to perform 2 argument xor. Loop over extra arguments in varargin, calling __xor__ as necessary. Update input validation and BIST tests. * data.cc (Fand, For, Fnot): Improve docstrings of related logical operations.
author Rik <rik@octave.org>
date Tue, 30 Sep 2014 10:58:34 -0700
parents b54093acb8fe
children d70b1cec7743
files libinterp/corefcn/data.cc scripts/miscellaneous/xor.m
diffstat 2 files changed, 63 insertions(+), 30 deletions(-) [+]
line wrap: on
line diff
--- a/libinterp/corefcn/data.cc	Tue Sep 30 08:29:16 2014 -0700
+++ b/libinterp/corefcn/data.cc	Tue Sep 30 10:58:34 2014 -0700
@@ -5865,9 +5865,10 @@
 
 DEFUN (not, args, ,
        "-*- texinfo -*-\n\
-@deftypefn {Built-in Function} {} not (@var{x})\n\
-Return the logical NOT of @var{x}.  This function is equivalent to\n\
-@code{! x}.\n\
+@deftypefn {Built-in Function} {@var{z} =} not (@var{x})\n\
+Return the logical NOT of @var{x}.\n\
+\n\
+This function is equivalent to the operator syntax @w{@code{! x}}.\n\
 @seealso{and, or, xor}\n\
 @end deftypefn")
 {
@@ -6206,12 +6207,13 @@
 
 DEFUN (and, args, ,
        "-*- texinfo -*-\n\
-@deftypefn  {Built-in Function} {} and (@var{x}, @var{y})\n\
-@deftypefnx {Built-in Function} {} and (@var{x1}, @var{x2}, @dots{})\n\
+@deftypefn  {Built-in Function} {@var{z} =} and (@var{x}, @var{y})\n\
+@deftypefnx {Built-in Function} {@var{z} =} and (@var{x1}, @var{x2}, @dots{})\n\
 Return the logical AND of @var{x} and @var{y}.\n\
-This function is equivalent to @w{@code{x & y}}.\n\
-If more arguments are given, the logical and is applied\n\
-cumulatively from left to right:\n\
+\n\
+This function is equivalent to the operator syntax @w{@code{x & y}}.  If\n\
+more than two arguments are given, the logical AND is applied cumulatively\n\
+from left to right:\n\
 \n\
 @example\n\
 (@dots{}((x1 & x2) & x3) & @dots{})\n\
@@ -6227,12 +6229,13 @@
 
 DEFUN (or, args, ,
        "-*- texinfo -*-\n\
-@deftypefn  {Built-in Function} {} or (@var{x}, @var{y})\n\
-@deftypefnx {Built-in Function} {} or (@var{x1}, @var{x2}, @dots{})\n\
+@deftypefn  {Built-in Function} {@var{z} =} or (@var{x}, @var{y})\n\
+@deftypefnx {Built-in Function} {@var{z} =} or (@var{x1}, @var{x2}, @dots{})\n\
 Return the logical OR of @var{x} and @var{y}.\n\
-This function is equivalent to @w{@code{x | y}}.\n\
-If more arguments are given, the logical or is applied\n\
-cumulatively from left to right:\n\
+\n\
+This function is equivalent to the operator syntax @w{@code{x | y}}.  If\n\
+more than two arguments are given, the logical OR is applied cumulatively\n\
+from left to right:\n\
 \n\
 @example\n\
 (@dots{}((x1 | x2) | x3) | @dots{})\n\
--- a/scripts/miscellaneous/xor.m	Tue Sep 30 08:29:16 2014 -0700
+++ b/scripts/miscellaneous/xor.m	Tue Sep 30 10:58:34 2014 -0700
@@ -17,23 +17,33 @@
 ## <http://www.gnu.org/licenses/>.
 
 ## -*- texinfo -*-
-## @deftypefn {Mapping Function} {@var{z} =} xor (@var{x}, @var{y})
-## Return the @dfn{exclusive or} of the entries of @var{x} and @var{y}.
+## @deftypefn  {Function File} {@var{z} =} xor (@var{x}, @var{y})
+## @deftypefnx {Function File} {@var{z} =} xor (@var{x1}, @var{x2}, @dots{})
+## Return the @dfn{exclusive or} of @var{x} and @var{y}.
+##
 ## For boolean expressions @var{x} and @var{y},
 ## @code{xor (@var{x}, @var{y})} is true if and only if one of @var{x} or
-## @var{y} is true.  Otherwise, for @var{x} and @var{y} both true or both
+## @var{y} is true.  Otherwise, if @var{x} and @var{y} are both true or both
 ## false, @code{xor} returns false.
 ##
 ## The truth table for the xor operation is
 ##
 ## @multitable @columnfractions 0.44 .03 .05 .03 0.44
 ## @item @tab @var{x} @tab @var{y} @tab @var{z} @tab
+## @item @tab - @tab - @tab - @tab
 ## @item @tab 0 @tab 0 @tab 0 @tab
 ## @item @tab 1 @tab 0 @tab 1 @tab
 ## @item @tab 0 @tab 1 @tab 1 @tab
 ## @item @tab 1 @tab 1 @tab 0 @tab
 ## @end multitable
 ##
+## If more than two arguments are given the xor operation is applied
+## cumulatively from left to right:
+##
+## @example
+## (@dots{}((x1 XOR x2) XOR x3) XOR @dots{})
+## @end example
+##
 ## @seealso{and, or, not}
 ## @end deftypefn
 
@@ -41,21 +51,35 @@
 ## Created: 16 September 1994
 ## Adapted-By: jwe
 
-function z = xor (x, y)
+function z = xor (x, y, varargin)
+
+  if (nargin < 2)
+    print_usage ();
+  endif
+
+  z = __xor__ (x, y);
 
-  if (nargin == 2)
-    if (isscalar (x) || isscalar (y) || size_equal (x, y))
-      ## Typecast to logicals is necessary for other numeric types.
-      z = logical (x) != logical (y);
-    else
-      try
-        z = bsxfun (@xor, x, y);
-      catch
-        error ("xor: X and Y must be of compatible size or scalars");
-      end_try_catch
-    endif
+  ## Slow expansion to multiple arguments.
+  ## Probably okay number of elements ## will be small.
+  if (! isempty (varargin))
+    for i = 1:numel (varargin) 
+      z = __xor__ (z, varargin{i});
+    endfor
+  endif
+
+endfunction
+
+function z = __xor__ (x, y)
+
+  if (isscalar (x) || isscalar (y) || size_equal (x, y))
+    ## Typecast to logicals is necessary for other numeric types.
+    z = logical (x) != logical (y);
   else
-    print_usage ();
+    try
+      z = bsxfun (@xor, x, y);
+    catch
+      error ("xor: X and Y must be of compatible size or scalars");
+    end_try_catch
   endif
 
 endfunction
@@ -65,7 +89,13 @@
 %!assert (xor ([i, i, 0, 0], [1, 0, 1, 0]), logical ([0, 1, 1, 0]))
 
 %!assert (xor (eye (2), fliplr (eye (2))), logical (ones (2)))
+%!assert (xor (speye (2), fliplr (speye (2))), sparse (logical (ones (2))))
 
+## Test XOR reduction
+%!assert (xor ([1 0], [1 1], [0 0]), [0 1])
+
+%% Test input validation
 %!error xor ()
-%!error xor (1, 2, 3)
+%!error xor (1)
+%!error <X and Y must be of compatible size> xor (ones (3,2), ones (2,3))