changeset 19446:78e424d31596

Overhaul max/min functions (fixes bug #43712). Return logical class for logical inputs. Allow max (array, scalar) calls to proceed without creating a broadcast warning. Rewrite docstring. Add many more BIST tests to get 100% line coverage. * max.cc (do_minmax_bin_op<charNDArray>): Remove code protected by if (x.is_scalar_type()) which is never triggered by input. Check for scalar using numel() == 1 and call max function with array, scalar invocation. * max.cc (do_minmax_body): At end of function, cast retval to bool_array if both inputs were of bool type (bug #43712). * max.cc (Fmin, Fmax): Rewrite docstrings. Add BIST tests.
author Rik <rik@octave.org>
date Sat, 20 Dec 2014 20:07:50 -0800
parents 95c533ed464b
children e354372e20f2
files libinterp/corefcn/max.cc
diffstat 1 files changed, 365 insertions(+), 63 deletions(-) [+]
line wrap: on
line diff
--- a/libinterp/corefcn/max.cc	Thu Dec 18 10:50:09 2014 -0500
+++ b/libinterp/corefcn/max.cc	Sat Dec 20 20:07:50 2014 -0800
@@ -155,7 +155,7 @@
 
   octave_value retval;
 
-  if (argx.is_scalar_type () == 1)
+  if (argx.is_scalar_type ())
     {
       ScalarType x = octave_value_extract<ScalarType> (argx);
       ArrayType y = octave_value_extract<ArrayType> (argy);
@@ -167,7 +167,7 @@
       else
         retval = max (x, y);
     }
-  else if (argy.is_scalar_type () == 1)
+  else if (argy.is_scalar_type ())
     {
       ArrayType x = octave_value_extract<ArrayType> (argx);
       ScalarType y = octave_value_extract<ScalarType> (argy);
@@ -210,39 +210,26 @@
 {
   octave_value retval;
 
-  if (argx.is_scalar_type () == 1)
-    {
-      char x = octave_value_extract<char> (argx);
-      charNDArray y = octave_value_extract<charNDArray> (argy);
+  charNDArray x = octave_value_extract<charNDArray> (argx);
+  charNDArray y = octave_value_extract<charNDArray> (argy);
 
-      if (error_state)
-        ;
-      else if (ismin)
-        retval = NDArray (min (x, y));
+  if (error_state)
+    ;
+  else if (ismin)
+    {
+      if (x.numel () == 1)
+        retval = NDArray (min (x(0), y));
+      else if (y.numel () == 1)
+        retval = NDArray (min (x, y(0)));
       else
-        retval = NDArray (max (x, y));
-    }
-  else if (argy.is_scalar_type () == 1)
-    {
-      charNDArray x = octave_value_extract<charNDArray> (argx);
-      char y = octave_value_extract<char> (argy);
-
-      if (error_state)
-        ;
-      else if (ismin)
         retval = NDArray (min (x, y));
-      else
-        retval = NDArray (max (x, y));
     }
   else
     {
-      charNDArray x = octave_value_extract<charNDArray> (argx);
-      charNDArray y = octave_value_extract<charNDArray> (argy);
-
-      if (error_state)
-        ;
-      else if (ismin)
-        retval = NDArray (min (x, y));
+      if (x.numel () == 1)
+        retval = NDArray (max (x(0), y));
+      else if (y.numel () == 1)
+        retval = NDArray (max (x, y(0)));
       else
         retval = NDArray (max (x, y));
     }
@@ -284,7 +271,7 @@
             if (arg.is_range () && (dim == -1 || dim == 1))
               {
                 Range range = arg.range_value ();
-                if (range.nelem () == 0)
+                if (range.nelem () < 1)
                   {
                     retval(0) = arg;
                     if (nargout > 1)
@@ -361,6 +348,11 @@
       builtin_type_t rtyp;
       if (xtyp == btyp_char && ytyp == btyp_char)
         rtyp = btyp_char;
+      /*
+      FIXME: This is what should happen when boolNDArray has max()
+      else if (xtyp == btyp_bool && ytyp == btyp_bool)
+        rtyp = btyp_bool;
+      */
       else
         rtyp = btyp_mixed_numeric (xtyp, ytyp);
 
@@ -409,10 +401,21 @@
         MAKE_INT_BRANCH (uint32);
         MAKE_INT_BRANCH (uint64);
 #undef MAKE_INT_BRANCH
+        /*
+        FIXME: This is what should happen when boolNDArray has max()
+        case btyp_bool:
+          retval = do_minmax_bin_op<boolNDArray> (argx, argy, ismin);
+          break;
+        */
         default:
           error ("%s: cannot compute %s (%s, %s)", func, func,
                  argx.type_name ().c_str (), argy.type_name ().c_str ());
         }
+
+      // FIXME: Delete when boolNDArray has max()
+      if (xtyp == btyp_bool && ytyp == btyp_bool)
+        retval(0) = retval(0).bool_array_value ();
+
     }
   else
     print_usage ();
@@ -423,15 +426,23 @@
 DEFUN (min, args, nargout,
        "-*- texinfo -*-\n\
 @deftypefn  {Built-in Function} {} min (@var{x})\n\
-@deftypefnx {Built-in Function} {} min (@var{x}, @var{y})\n\
 @deftypefnx {Built-in Function} {} min (@var{x}, [], @var{dim})\n\
-@deftypefnx {Built-in Function} {} min (@var{x}, @var{y}, @var{dim})\n\
 @deftypefnx {Built-in Function} {[@var{w}, @var{iw}] =} min (@var{x})\n\
-For a vector argument, return the minimum value.  For a matrix\n\
-argument, return the minimum value from each column, as a row\n\
-vector, or over the dimension @var{dim} if defined, in which case @var{y} \n\
-should be set to the empty matrix (it's ignored otherwise).  For two matrices\n\
-(or a matrix and scalar), return the pair-wise minimum.\n\
+@deftypefnx {Built-in Function} {} min (@var{x}, @var{y})\n\
+Find minimum values in the array @var{x}.\n\
+\n\
+For a vector argument, return the minimum value.\n\
+For a matrix argument, return a row vector with the minimum value of each\n\
+column.\n\
+For a multi-dimensional array, @code{min} operates along the first\n\
+non-singleton dimension.\n\
+\n\
+If the optional third argument @var{dim} is present then operate along\n\
+this dimension.  In this case the second argument is ignored and should be\n\
+set to the empty matrix.\n\
+\n\
+For two matrices (or a matrix and a scalar), return the pairwise minimum.\n\
+\n\
 Thus,\n\
 \n\
 @example\n\
@@ -439,7 +450,7 @@
 @end example\n\
 \n\
 @noindent\n\
-returns the smallest element of @var{x}, and\n\
+returns the smallest element of the 2-D matrix @var{x}, and\n\
 \n\
 @example\n\
 @group\n\
@@ -453,7 +464,19 @@
 returns a row vector of the minimum values.\n\
 \n\
 For complex arguments, the magnitude of the elements are used for\n\
-comparison.\n\
+comparison.  If the magnitudes are identical, then the results are ordered\n\
+by phase angle in the range (-pi, pi].  Hence,\n\
+\n\
+@example\n\
+@group\n\
+min ([-1 i 1 -i])\n\
+    @result{} -i\n\
+@end group\n\
+@end example\n\
+\n\
+@noindent\n\
+because all entries have magnitude 1, but -i has the smallest phase angle\n\
+with value -pi/2.\n\
 \n\
 If called with one input and two output arguments,\n\
 @code{min} also returns the first index of the\n\
@@ -473,40 +496,176 @@
 }
 
 /*
+## Test generic double class
 %!assert (min ([1, 4, 2, 3]), 1)
 %!assert (min ([1; -10; 5; -2]), -10)
-%!assert (min ([4, i; -2, 2]), [-2, i])
-%!assert (min (char(42)), 42)
-%!assert (min (char(21), char(3)), 3)
-%!assert (min([char(21), char(3)]), 3)
-%!assert (min([char(100) char(3)], [char(42) char(42)]), [42 3])
+%!assert (min ([4, 2i 4.999; -2, 2, 3+4i]), [-2, 2, 4.999])
+## Special routines for char arrays
+%!assert (min (["abc", "ABC"]), 65)
+%!assert (min (["abc"; "CBA"]), [67 66 65])
+## Special routines for logical arrays
+%!assert (min (logical ([])), logical ([]))
+%!assert (min (logical ([0 0 1 0])), false)
+%!assert (min (logical ([0 0 1 0; 0 1 1 0])), logical ([0 0 1 0]))
+## Single values
+%!assert (min (single ([1, 4, 2, 3])), single (1))
+%!assert (min (single ([1; -10; 5; -2])), single (-10))
+%!assert (min (single ([4, 2i 4.999; -2, 2, 3+4i])), single ([-2, 2, 4.999]))
+## Integer values
+%!assert (min (uint8 ([1, 4, 2, 3])), uint8 (1))
+%!assert (min (uint8 ([1; -10; 5; -2])), uint8 (-10))
+%!assert (min (int8 ([1, 4, 2, 3])), int8 (1))
+%!assert (min (int8 ([1; -10; 5; -2])), int8 (-10))
+%!assert (min (uint16 ([1, 4, 2, 3])), uint16 (1))
+%!assert (min (uint16 ([1; -10; 5; -2])), uint16 (-10))
+%!assert (min (int16 ([1, 4, 2, 3])), int16 (1))
+%!assert (min (int16 ([1; -10; 5; -2])), int16 (-10))
+%!assert (min (uint32 ([1, 4, 2, 3])), uint32 (1))
+%!assert (min (uint32 ([1; -10; 5; -2])), uint32 (-10))
+%!assert (min (int32 ([1, 4, 2, 3])), int32 (1))
+%!assert (min (int32 ([1; -10; 5; -2])), int32 (-10))
+%!assert (min (uint64 ([1, 4, 2, 3])), uint64 (1))
+%!assert (min (uint64 ([1; -10; 5; -2])), uint64 (-10))
+%!assert (min (int64 ([1, 4, 2, 3])), int64 (1))
+%!assert (min (int64 ([1; -10; 5; -2])), int64 (-10))
+## Sparse double values
+%!assert (min (sparse ([1, 4, 2, 3])), sparse (1))
+%!assert (min (sparse ([1; -10; 5; -2])), sparse(-10))
+## FIXME: sparse doesn't order complex values by phase angle
+%!xtest
+%! assert (min (sparse ([4, 2i 4.999; -2, 2, 3+4i])), sparse ([-2, 2, 4.999]));
 
+## Test dimension argument
 %!test
 %! x = reshape (1:8, [2,2,2]);
-%! assert (max (x, [], 1), reshape ([2, 4, 6, 8], [1,2,2]));
-%! assert (max (x, [], 2), reshape ([3, 4, 7, 8], [2,1,2]));
-%! [y, i] = max (x, [], 3);
+%! assert (min (x, [], 1), reshape ([1, 3, 5, 7], [1,2,2]));
+%! assert (min (x, [], 2), reshape ([1, 2, 5, 6], [2,1,2]));
+%! [y, i] = min (x, [], 3);
 %! assert (ndims (y), 2);
-%! assert (y, [5, 7; 6, 8]);
+%! assert (y, [1, 3; 2, 4]);
 %! assert (ndims (i), 2);
-%! assert (i, [2, 2; 2, 2]);
+%! assert (i, [1, 1; 1, 1]);
+
+## Test 2-output forms for various arg types
+## Special routines for char arrays
+%!test
+%! [y, i] = min (["abc", "ABC"]);
+%! assert (y, 65);
+%! assert (i, 4);
+## Special routines for logical arrays
+%!test
+%! x = logical ([0 0 1 0]);
+%! [y, i] = min (x);
+%! assert (y, false);
+%! assert (i, 1);
+## Special handling of ranges
+%!test
+%! rng = 1:2:10;
+%! [y, i] = min (rng);
+%! assert (y, 1);
+%! assert (i, 1);
+%! rng = 10:-2:1;
+%! [y, i] = min (rng);
+%! assert (y, 2);
+%! assert (i, 5);
+
+## Test 2-input calling form for various arg types
+## Test generic double class
+%!test
+%! x = [1, 2, 3, 4];  y = fliplr (x);
+%! assert (min (x, y), [1 2 2 1]);
+%! assert (min (x, 3), [1 2 3 3]);
+%! assert (min (2, x), [1 2 2 2]);
+%! assert (min (x, 2.1i), [1 2 2.1i 2.1i]);
+## FIXME: Ordering of complex results with equal magnitude is not by phase
+##        angle in the 2-input form.  Instead, it is in the order in which it
+##        appears in the argument list.
+%!xtest
+%! x = [1, 2, 3, 4];  y = fliplr (x);
+%! assert (min (x, 2i), [2i 2i 3 4]);
+## Special routines for char arrays
+%!assert (min ("abc", "b"), [97 98 98])
+%!assert (min ("b", "cba"), [98 98 97])
+## Special handling for logical arrays
+%!assert (min ([true false], false), [false false])
+%!assert (min (true, [true false]), [true false])
+## Single values
+%!test
+%! x = single ([1, 2, 3, 4]);  y = fliplr (x);
+%! assert (min (x, y), single ([1 2 2 1]));
+%! assert (min (x, 3), single ([1 2 3 3]));
+%! assert (min (2, x), single ([1 2 2 2]));
+%! assert (min (x, 2.1i), single ([1 2 2.1i 2.1i]));
+## Integer values
+%!test
+%! x = uint8 ([1, 2, 3, 4]);  y = fliplr (x);
+%! assert (min (x, y), uint8 ([1 2 2 1]));
+%! assert (min (x, 3), uint8 ([1 2 3 3]));
+%! assert (min (2, x), uint8 ([1 2 2 2]));
+%! x = int8 ([1, 2, 3, 4]);  y = fliplr (x);
+%! assert (min (x, y), int8 ([1 2 2 1]));
+%! assert (min (x, 3), int8 ([1 2 3 3]));
+%! assert (min (2, x), int8 ([1 2 2 2]));
+%! x = uint16 ([1, 2, 3, 4]);  y = fliplr (x);
+%! assert (min (x, y), uint16 ([1 2 2 1]));
+%! assert (min (x, 3), uint16 ([1 2 3 3]));
+%! assert (min (2, x), uint16 ([1 2 2 2]));
+%! x = int16 ([1, 2, 3, 4]);  y = fliplr (x);
+%! assert (min (x, y), int16 ([1 2 2 1]));
+%! assert (min (x, 3), int16 ([1 2 3 3]));
+%! assert (min (2, x), int16 ([1 2 2 2]));
+%! x = uint32 ([1, 2, 3, 4]);  y = fliplr (x);
+%! assert (min (x, y), uint32 ([1 2 2 1]));
+%! assert (min (x, 3), uint32 ([1 2 3 3]));
+%! assert (min (2, x), uint32 ([1 2 2 2]));
+%! x = int32 ([1, 2, 3, 4]);  y = fliplr (x);
+%! assert (min (x, y), int32 ([1 2 2 1]));
+%! assert (min (x, 3), int32 ([1 2 3 3]));
+%! assert (min (2, x), int32 ([1 2 2 2]));
+%! x = uint64 ([1, 2, 3, 4]);  y = fliplr (x);
+%! assert (min (x, y), uint64 ([1 2 2 1]));
+%! assert (min (x, 3), uint64 ([1 2 3 3]));
+%! assert (min (2, x), uint64 ([1 2 2 2]));
+%! x = int64 ([1, 2, 3, 4]);  y = fliplr (x);
+%! assert (min (x, y), int64 ([1 2 2 1]));
+%! assert (min (x, 3), int64 ([1 2 3 3]));
+%! assert (min (2, x), int64 ([1 2 2 2]));
+## Sparse double values
+%!test
+%! x = sparse ([1, 2, 3, 4]);  y = fliplr (x);
+%! assert (min (x, y), sparse ([1 2 2 1]));
+%! assert (min (x, 3), sparse ([1 2 3 3]));
+%! assert (min (2, x), sparse ([1 2 2 2]));
+%! assert (min (x, 2.1i), sparse ([1 2 2.1i 2.1i]));
 
 %!error min ()
 %!error min (1, 2, 3, 4)
+%!error <DIM must be a valid dimension> min ([1 2; 3 4], [], -3)
+%!warning <second argument is ignored> min ([1 2 3 4], 2, 2);
+%!error <wrong type argument 'cell'> min ({1 2 3 4})
+%!error <cannot compute min \(cell, scalar\)> min ({1, 2, 3}, 2)
 */
 
 DEFUN (max, args, nargout,
        "-*- texinfo -*-\n\
 @deftypefn  {Built-in Function} {} max (@var{x})\n\
-@deftypefnx {Built-in Function} {} max (@var{x}, @var{y})\n\
 @deftypefnx {Built-in Function} {} max (@var{x}, [], @var{dim})\n\
-@deftypefnx {Built-in Function} {} max (@var{x}, @var{y}, @var{dim})\n\
 @deftypefnx {Built-in Function} {[@var{w}, @var{iw}] =} max (@var{x})\n\
-For a vector argument, return the maximum value.  For a matrix\n\
-argument, return the maximum value from each column, as a row\n\
-vector, or over the dimension @var{dim} if defined, in which case @var{y} \n\
-should be set to the empty matrix (it's ignored otherwise).  For two matrices\n\
-(or a matrix and scalar), return the pair-wise maximum.\n\
+@deftypefnx {Built-in Function} {} max (@var{x}, @var{y})\n\
+Find maximum values in the array @var{x}.\n\
+\n\
+For a vector argument, return the maximum value.\n\
+For a matrix argument, return a row vector with the maximum value of each\n\
+column.\n\
+For a multi-dimensional array, @code{max} operates along the first\n\
+non-singleton dimension.\n\
+\n\
+If the optional third argument @var{dim} is present then operate along\n\
+this dimension.  In this case the second argument is ignored and should be\n\
+set to the empty matrix.\n\
+\n\
+For two matrices (or a matrix and a scalar), return the pairwise maximum.\n\
+\n\
 Thus,\n\
 \n\
 @example\n\
@@ -514,7 +673,7 @@
 @end example\n\
 \n\
 @noindent\n\
-returns the largest element of the matrix @var{x}, and\n\
+returns the largest element of the 2-D matrix @var{x}, and\n\
 \n\
 @example\n\
 @group\n\
@@ -524,11 +683,23 @@
 @end example\n\
 \n\
 @noindent\n\
-compares each element of the range @code{2:5} with @code{pi}, and\n\
-returns a row vector of the maximum values.\n\
+compares each element of the range @code{2:5} with @code{pi}, and returns a\n\
+row vector of the maximum values.\n\
 \n\
 For complex arguments, the magnitude of the elements are used for\n\
-comparison.\n\
+comparison.  If the magnitudes are identical, then the results are ordered\n\
+by phase angle in the range (-pi, pi].  Hence,\n\
+\n\
+@example\n\
+@group\n\
+max ([-1 i 1 -i])\n\
+    @result{} -1\n\
+@end group\n\
+@end example\n\
+\n\
+@noindent\n\
+because all entries have magnitude 1, but -1 has the largest phase angle\n\
+with value pi.\n\
 \n\
 If called with one input and two output arguments,\n\
 @code{max} also returns the first index of the\n\
@@ -548,26 +719,157 @@
 }
 
 /*
+## Test generic double class
 %!assert (max ([1, 4, 2, 3]), 4)
 %!assert (max ([1; -10; 5; -2]), 5)
-%!assert (max ([4, i 4.999; -2, 2, 3+4i]), [4, 2, 3+4i])
+%!assert (max ([4, 2i 4.999; -2, 2, 3+4i]), [4, 2i, 3+4i])
+## Special routines for char arrays
+%!assert (max (["abc", "ABC"]), 99)
+%!assert (max (["abc"; "CBA"]), [97 98 99])
+## Special routines for logical arrays
+%!assert (max (logical ([])), logical ([]))
+%!assert (max (logical ([0 0 1 0])), true)
+%!assert (max (logical ([0 0 1 0; 0 1 0 0])), logical ([0 1 1 0]))
+## Single values
+%!assert (max (single ([1, 4, 2, 3])), single (4))
+%!assert (max (single ([1; -10; 5; -2])), single (5))
+%!assert (max (single ([4, 2i 4.999; -2, 2, 3+4i])), single ([4, 2i, 3+4i]))
+## Integer values
+%!assert (max (uint8 ([1, 4, 2, 3])), uint8 (4))
+%!assert (max (uint8 ([1; -10; 5; -2])), uint8 (5))
+%!assert (max (int8 ([1, 4, 2, 3])), int8 (4))
+%!assert (max (int8 ([1; -10; 5; -2])), int8 (5))
+%!assert (max (uint16 ([1, 4, 2, 3])), uint16 (4))
+%!assert (max (uint16 ([1; -10; 5; -2])), uint16 (5))
+%!assert (max (int16 ([1, 4, 2, 3])), int16 (4))
+%!assert (max (int16 ([1; -10; 5; -2])), int16 (5))
+%!assert (max (uint32 ([1, 4, 2, 3])), uint32 (4))
+%!assert (max (uint32 ([1; -10; 5; -2])), uint32 (5))
+%!assert (max (int32 ([1, 4, 2, 3])), int32 (4))
+%!assert (max (int32 ([1; -10; 5; -2])), int32 (5))
+%!assert (max (uint64 ([1, 4, 2, 3])), uint64 (4))
+%!assert (max (uint64 ([1; -10; 5; -2])), uint64 (5))
+%!assert (max (int64 ([1, 4, 2, 3])), int64 (4))
+%!assert (max (int64 ([1; -10; 5; -2])), int64 (5))
+## Sparse double values
+%!assert (max (sparse ([1, 4, 2, 3])), sparse (4))
+%!assert (max (sparse ([1; -10; 5; -2])), sparse(5))
+%!assert (max (sparse ([4, 2i 4.999; -2, 2, 3+4i])), sparse ([4, 2i, 3+4i]))
 
+## Test dimension argument
 %!test
 %! x = reshape (1:8, [2,2,2]);
 %! assert (min (x, [], 1), reshape ([1, 3, 5, 7], [1,2,2]));
 %! assert (min (x, [], 2), reshape ([1, 2, 5, 6], [2,1,2]));
 %! [y, i] = min (x, [], 3);
-%! assert (ndims(y), 2);
+%! assert (ndims (y), 2);
 %! assert (y, [1, 3; 2, 4]);
-%! assert (ndims(i), 2);
+%! assert (ndims (i), 2);
 %! assert (i, [1, 1; 1, 1]);
 
+## Test 2-output forms for various arg types
+## Special routines for char arrays
+%!test
+%! [y, i] = max (["abc", "ABC"]);
+%! assert (y, 99);
+%! assert (i, 3);
+## Special routines for logical arrays
+%!test
+%! x = logical ([0 0 1 0]);
+%! [y, i] = max (x);
+%! assert (y, true);
+%! assert (i, 3);
+## Special handling of ranges
+%!test
+%! rng = 1:2:10;
+%! [y, i] = max (rng);
+%! assert (y, 9);
+%! assert (i, 5);
+%! rng = 10:-2:1;
+%! [y, i] = max (rng);
+%! assert (y, 10);
+%! assert (i, 1);
+
+## Test 2-input calling form for various arg types
+## Test generic double class
+%!test
+%! x = [1, 2, 3, 4];  y = fliplr (x);
+%! assert (max (x, y), [4 3 3 4]);
+%! assert (max (x, 3), [3 3 3 4]);
+%! assert (max (2, x), [2 2 3 4]);
+%! assert (max (x, 2.1i), [2.1i 2.1i 3 4]);
+## FIXME: Ordering of complex results with equal magnitude is not by phase
+##        angle in the 2-input form.  Instead, it is in the order in which it
+##        appears in the argument list.
+%!xtest
+%! x = [1, 2, 3, 4];  y = fliplr (x);
+%! assert (max (x, 2i), [2i 2i 3 4]);
+## Special routines for char arrays
+%!assert (max ("abc", "b"), [98 98 99])
+%!assert (max ("b", "cba"), [99 98 98])
+## Special handling for logical arrays
+%!assert (max ([true false], false), [true false])
+%!assert (max (true, [false false]), [true true])
+## Single values
+%!test
+%! x = single ([1, 2, 3, 4]);  y = fliplr (x);
+%! assert (max (x, y), single ([4 3 3 4]));
+%! assert (max (x, 3), single ([3 3 3 4]));
+%! assert (max (2, x), single ([2 2 3 4]));
+%! assert (max (x, 2.1i), single ([2.1i 2.1i 3 4]));
+## Integer values
+%!test
+%! x = uint8 ([1, 2, 3, 4]);  y = fliplr (x);
+%! assert (max (x, y), uint8 ([4 3 3 4]));
+%! assert (max (x, 3), uint8 ([3 3 3 4]));
+%! assert (max (2, x), uint8 ([2 2 3 4]));
+%! x = int8 ([1, 2, 3, 4]);  y = fliplr (x);
+%! assert (max (x, y), int8 ([4 3 3 4]));
+%! assert (max (x, 3), int8 ([3 3 3 4]));
+%! assert (max (2, x), int8 ([2 2 3 4]));
+%! x = uint16 ([1, 2, 3, 4]);  y = fliplr (x);
+%! assert (max (x, y), uint16 ([4 3 3 4]));
+%! assert (max (x, 3), uint16 ([3 3 3 4]));
+%! assert (max (2, x), uint16 ([2 2 3 4]));
+%! x = int16 ([1, 2, 3, 4]);  y = fliplr (x);
+%! assert (max (x, y), int16 ([4 3 3 4]));
+%! assert (max (x, 3), int16 ([3 3 3 4]));
+%! assert (max (2, x), int16 ([2 2 3 4]));
+%! x = uint32 ([1, 2, 3, 4]);  y = fliplr (x);
+%! assert (max (x, y), uint32 ([4 3 3 4]));
+%! assert (max (x, 3), uint32 ([3 3 3 4]));
+%! assert (max (2, x), uint32 ([2 2 3 4]));
+%! x = int32 ([1, 2, 3, 4]);  y = fliplr (x);
+%! assert (max (x, y), int32 ([4 3 3 4]));
+%! assert (max (x, 3), int32 ([3 3 3 4]));
+%! assert (max (2, x), int32 ([2 2 3 4]));
+%! x = uint64 ([1, 2, 3, 4]);  y = fliplr (x);
+%! assert (max (x, y), uint64 ([4 3 3 4]));
+%! assert (max (x, 3), uint64 ([3 3 3 4]));
+%! assert (max (2, x), uint64 ([2 2 3 4]));
+%! x = int64 ([1, 2, 3, 4]);  y = fliplr (x);
+%! assert (max (x, y), int64 ([4 3 3 4]));
+%! assert (max (x, 3), int64 ([3 3 3 4]));
+%! assert (max (2, x), int64 ([2 2 3 4]));
+## Sparse double values
+%!test
+%! x = sparse ([1, 2, 3, 4]);  y = fliplr (x);
+%! assert (max (x, y), sparse ([4 3 3 4]));
+%! assert (max (x, 3), sparse ([3 3 3 4]));
+%! assert (max (2, x), sparse ([2 2 3 4]));
+%! assert (max (x, 2.1i), sparse ([2.1i 2.1i 3 4]));
+
 ## Test for bug #40743
 %!assert (max (zeros (1,0), ones (1,1)), zeros (1,0))
 %!assert (max (sparse (zeros (1,0)), sparse (ones (1,1))), sparse (zeros (1,0)))
 
 %!error max ()
 %!error max (1, 2, 3, 4)
+%!error <DIM must be a valid dimension> max ([1 2; 3 4], [], -3)
+%!warning <second argument is ignored> max ([1 2 3 4], 2, 2);
+%!error <wrong type argument 'cell'> max ({1 2 3 4})
+%!error <cannot compute max \(cell, scalar\)> max ({1, 2, 3}, 2)
+
 */
 
 template <class ArrayType>