# HG changeset patch
# User Nicholas R. Jankowski <jankowski.nicholas@gmail.com>
# Date 1639778141 18000
#      Fri Dec 17 16:55:41 2021 -0500
# Node ID 30ba00c94c5bb9b706e802a3b7078b62140f3486
# Parent  c95d345becf9d53c98df587ccc51fce6ad1302cb
'missing' functions - update ismissing & rmmissing, add standardizeMissing (patch #10102)

* \install-conditionally\base\ismissing.m: corrects array input processing by
changing length to numel in loop counters. Uses cellfun with isempty for
faster handling of cellstrings. Modifies input and data type checking for
handling of nD arrays and compatiblility. Updates docstring and adds BISTs
checked for compatibility for above items.
* \install-conditionally\base\rmmissing.m: corrects cellstring array input
processing by handling them as per matrix inputs. Streamlines some indexing
operations.  Modifies input and data type checking for compatablility. 
Updates docstring and adds BISTs checked for compatibility for above items.
* \install-conditionally\base\standardizeMissing.m: Adds new function.


diff -r c95d345becf9 -r 30ba00c94c5b install-conditionally/base/ismissing.m
--- a/install-conditionally/base/ismissing.m	Wed Dec 08 13:05:24 2021 -0500
+++ b/install-conditionally/base/ismissing.m	Fri Dec 17 16:55:41 2021 -0500
@@ -27,16 +27,16 @@
 ## @deftypefn {} {@var{TF} =} ismissing (@var{A})
 ## @deftypefnx {} {@var{TF} =} ismissing (@var{A}, @var{indicator})
 ##
-## Find missing data in a matrix or a string array.
+## Find missing data in a numeric or string array.
 ##
-## Given an input vector, matrix or array of cell strings @var{A},
-## @code{ismissing} returns a logical vector or matrix @var{TF} with the same
-## dimensions as @var{A}, where @code{true} values match missing values in the
-## input data.
+## Given an input numeric data array, char array, or array of cell strings
+## @var{A}, @code{ismissing} returns a logical array @var{TF} with
+## the same dimensions as @var{A}, where @code{true} values match missing
+## values in the input data.
 ##
-## The optional input @var{indicator} is an array of values, which represent
-## missing values in the input data.  The values which represent missing data by
-## default depend on the data type of @var{A}:
+## The optional input @var{indicator} is an array of values that represent
+## missing values in the input data.  The values which represent missing data
+## by default depend on the data type of @var{A}:
 ##
 ## @itemize
 ## @item
@@ -49,88 +49,129 @@
 ## @code{@{''@}}: string cells.
 ## @end itemize
 ##
+## Compatability Note: logical and numeric data types may be used
+## in any combination for @var{A} and @var{indicator}, and indicator values
+## will be automatically type-converted as necessary.  Note that logical and
+## other numeric data types have no default 'missing' value. As such, unless
+## @var{indicator} is specified such inputs will always result in a TF output
+## of @code{false(size(@var{A}))}.
+##
 ## @end deftypefn
 ##
 ## @seealso{all, any, isempty, isnan, rmmissing}
 
 function TF = ismissing (A, indicator)
 
+  if (nargin < 1) || (nargin > 2)
+    print_usage ();
+  endif
+
   ## check "indicator"
   if (nargin != 2)
      indicator = [];
-  else
-    if (! isvector (indicator))
-      error ("ismissing: invalid format for 'indicator'");
-    endif
+  endif
 
-    if ((isnumeric (A) && ! isnumeric (indicator)) ||
-        (ischar (A) && ! ischar (indicator)) ||
-        (iscellstr (A) && ! (iscellstr (indicator) || ischar (indicator))))
-      error ("ismissing: 'indicator' and 'A' must have the same data type");
-    endif
+  ## if A is an array of cell strings and indicator just a string,
+  ## convert indicator to a cell string with one element
+  if (iscellstr (A) && ischar (indicator) && ! iscellstr (indicator))
+    indicator = {indicator};
+  endif
 
-    ## if A is an array of cell strings and indicator just a string,
-    ## convert indicator to a cell string with one element
-    if (iscellstr (A) && ischar (indicator) && ! iscellstr (indicator))
-      tmpstr = indicator;
-      indicator = {};
-
-      indicator = {tmpstr};
-    endif
+  if ((! isempty (indicator)) &&
+      ((isnumeric (A) && ! (isnumeric (indicator) || islogical (indicator))) ||
+       (ischar (A) && ! ischar (indicator)) ||
+       (iscellstr (A) && ! (iscellstr (indicator)))))
+    error ("ismissing: 'indicator' and 'A' must have the same data type");
   endif
 
   ## main logic
-  if (iscellstr (A) && isempty (indicator))
-    TF = false (1, length (A));
-    ## remove all empty strings
-    for iter = 1 : length (A)
-      if (isempty (A{iter}))
-        TF(iter) = true;
-      endif
-    endfor
-  elseif (ismatrix (A) && isempty (indicator))
-    if (isnumeric (A))
-      ## numeric matrix: just remove the NaNs
+  if (isempty (indicator))
+    if (iscellstr (A))
+      ## cell strings - find empty cells
+      TF = cellfun ('isempty', A);
+
+    elseif (isnumeric (A))
+      ## numeric matrix: just find the NaNs
       TF = isnan (A);
+
     elseif (ischar (A))
-      ## char matrix: remove the white spaces
+      ## char matrix: find the white spaces
       TF = isspace (A);
+
+    elseif (islogical (A))
+      ##do nothing
+      TF = false (size (A));
+
     else
       error ("ismissing: unsupported data type");
     endif
 
-    TF = logical (TF);
-  elseif (! isempty (indicator))
-    ## special cases with custom values for missing data
-    [r, c] = size (A);
-    TF = false (r, c);
-
+  else
+    ## indicator specified for missing data
+    TF = false (size (A));
     if (iscellstr (A))
-      for iter = 1 : length (indicator)
+      for iter = 1 : numel (indicator)
         TF(find (strcmp (A, indicator(iter)))) = true;
       endfor
-    elseif (ismatrix (A))
-      for iter = 1 : length (indicator)
+    elseif (isnumeric(A) || ischar (A) || islogical (A))
+      for iter = 1 : numel (indicator)
         TF(find (A == indicator(iter))) = true;
       endfor
     else
       error ("ismissing: unsupported data format");
     endif
-  else
-    error ("ismissing: unsupported data format");
   endif
 endfunction
 
-
 %!assert (ismissing ([1,NaN,3]), [false,true,false])
 %!assert (ismissing ('abcd f'), [false,false,false,false,true,false])
 %!assert (ismissing ({'xxx','','xyz'}), [false,true,false])
+%!assert (ismissing ({'x','','y'}), [false,true,false])
+%!assert (ismissing ({'x','','y';'z','a',''}), logical([0,1,0;0,0,1]))
 %!assert (ismissing ([1,2;NaN,2]), [false,false;true,false])
 
+## test nD array data
+%!assert (ismissing (cat(3,magic(2),magic(2))), logical (zeros (2,2,2)))
+%!assert (ismissing (cat(3,magic(2),[1 2;3 NaN])), logical (cat(3,[0,0;0,0],[0,0;0,1])))
+%!assert (ismissing ([1 2; 3 4], [5 1; 2 0]), logical([1 1; 0 0]))
+%!assert (ismissing (cat(3,'f oo','ba r')), logical(cat(3,[0 1 0 0],[0 0 1 0])))
+%!assert (ismissing (cat(3,{'foo'},{''},{'bar'})), logical(cat(3,0,1,0)))
+
+## test data type handling
+%!assert (ismissing (double (NaN)), true)
+%!assert (ismissing (single (NaN)), true)
+%!assert (ismissing (' '), true)
+%!assert (ismissing ({''}), true)
+%!assert (ismissing ({' '}), false)
+%!assert (ismissing (logical ([1 0 1])), [false false false])
+%!assert (ismissing (int32 ([1 2 3])), [false false false])
+%!assert (ismissing (uint32 ([1 2 3])), [false false false])
+%!assert (ismissing (double (eye(3)), single (1)), logical(eye(3)))
+%!assert (ismissing (double (eye(3)), true), logical(eye(3)))
+%!assert (ismissing (double (eye(3)), int32 (1)), logical(eye(3)))
+%!assert (ismissing (single (eye(3)), true), logical(eye(3)))
+%!assert (ismissing (single (eye(3)), double (1)), logical(eye(3)))
+%!assert (ismissing (single(eye(3)), int32 (1)), logical(eye(3)))
+%!assert (ismissing (logical (eye(3)), true), logical(eye(3)))
+%!assert (ismissing (logical (eye(3)), double (1)), logical(eye(3)))
+%!assert (ismissing (logical (eye(3)), single (1)), logical(eye(3)))
+%!assert (ismissing (logical (eye(3)), int32 (1)), logical(eye(3)))
+%!assert (ismissing (int32 (eye(3)), int32 (1)), logical(eye(3)))
+%!assert (ismissing (int32 (eye(3)), true), logical(eye(3)))
+%!assert (ismissing (int32 (eye(3)), double (1)), logical(eye(3)))
+%!assert (ismissing (int32 (eye(3)), single (1)), logical(eye(3)))
+
+## test empty input handling
+%!assert (ismissing ([]), logical([]))
+%!assert (ismissing (''), logical([]))
+%!assert (ismissing (ones (0,1)), logical(ones(0,1)))
+%!assert (ismissing (ones (1,0)), logical(ones(1,0)))
+%!assert (ismissing (ones (1,2,0)), logical(ones(1,2,0)))
+
 ## Test input validation
-%!error ismissing ();
-%!error ismissing ({1, 2, 3});
-%!error ismissing ([1 2; 3 4], [5 1; 2 0]);
-%!error ismissing ([1 2; 3 4], "abc");
-%!error ismissing ({"", "", ""}, 1);
-%!error ismissing ({1, 2, 3});
+%!error ismissing ()
+%!error ismissing ({1, 2, 3})
+%!error ismissing ([1 2; 3 4], "abc")
+%!error ismissing ({"", "", ""}, 1)
+%!error ismissing ({'123', 123})
+
diff -r c95d345becf9 -r 30ba00c94c5b install-conditionally/base/rmmissing.m
--- a/install-conditionally/base/rmmissing.m	Wed Dec 08 13:05:24 2021 -0500
+++ b/install-conditionally/base/rmmissing.m	Fri Dec 17 16:55:41 2021 -0500
@@ -29,12 +29,12 @@
 ## @deftypefnx {} {@var{R} =} rmmissing (@dots{}, @var{Name}, @var{Value})
 ## @deftypefnx {} {[@var{R} @var{TF}] =} rmmissing (@dots{})
 ##
-## Remove missing or incomplete data from an array or a matrix.
+## Remove missing or incomplete data from an array.
 ##
-## Given an input array or matrix @var{A}, remove rows or columns with
-## missing data from a matrix, or remove missing data from an array.  @var{A}
-## can be a numeric or char matrix, a vector or an array of cell strings.
-## @var{R} is the return matrix or array, after the removal of missing data.
+## Given an input vector or matrix (2-D array) @var{A}, remove missing data
+## from a vector or missing rows or columns from a matrix.  @var{A}
+## can be a numeric array, char array, or an array of cell strings.
+## @var{R} returns the array after removal of missing data.
 ##
 ## The values which represent missing data depend on the data type of @var{A}:
 ##
@@ -60,6 +60,10 @@
 ## @code{2}: columns.
 ## @end itemize
 ##
+## Compatibility Note: logical and other numeric data types have no default
+## 'missing' value. As such, such inputs will always result in R == A and
+## a TF output of @code{false(size(@var{A}))}.
+##
 ## Additional optional parameters are set by @var{Name}-@var{Value} pairs.
 ## These are:
 ##
@@ -80,10 +84,14 @@
 
 function [R, TF] = rmmissing (A, varargin)
 
-  if (nargin < 1)
+  if ((nargin < 1) || (nargin > 4))
      print_usage ();
   endif
 
+  if ndims(A) > 2
+    error ("rmmissing: input dimension cannot exceed 2");
+  endif
+
   optDimensionI = 2; # default dimension: rows
   optMinNumMissingI = 1;
 
@@ -137,18 +145,16 @@
   endif
 
   ## main logic
-  if (iscellstr (A) || isvector (A))
-    TF = ismissing (A);
+  TF = ismissing (A);
+  if (isvector (A))
+    R = A(TF == 0);
 
-    R = A(find (TF == 0));
-  elseif (ismatrix (A))
-    ## matrix: ismissing returns a matrix, so it must be converted to a row or
+  elseif (iscellstr(A) || ismatrix (A))
+    ## matrix: ismissing returns a array, so it must be converted to a row or
     ## column vector according to the "dim" of choice
-    TF = ismissing (A);
-
     if (optMinNumMissingI > 1)
       TF = sum (TF, optDimensionI);
-      TF(find (TF < optMinNumMissingI)) = 0;
+      TF(TF < optMinNumMissingI) = 0;
       TF = logical (TF);
     else
       TF = any (TF, optDimensionI);
@@ -156,30 +162,70 @@
 
     if (optDimensionI == 2)
       ## remove the rows
-      R = A(find (TF == 0), :);
+      R = A((TF == 0), :);
     else
-      ## remove the columns 
-      R = A(:, find (TF == 0));
+      ## remove the columns
+      R = A(:, (TF == 0));
     endif
   else
     error ("rmmissing: unsupported data");
   endif
 endfunction
 
-
 %!assert (rmmissing ([1,NaN,3]), [1,3])
 %!assert (rmmissing ('abcd f'), 'abcdf')
 %!assert (rmmissing ({'xxx','','xyz'}), {'xxx','xyz'})
+%!assert (rmmissing ({'xxx','';'xyz','yyy'}), {'xyz','yyy'})
+%!assert (rmmissing ({'xxx','';'xyz','yyy'}, 2), {'xxx';'xyz'})
 %!assert (rmmissing ([1,2;NaN,2]), [1,2])
 %!assert (rmmissing ([1,2;NaN,2], 2), [2,2]')
 %!assert (rmmissing ([1,2;NaN,4;NaN,NaN],"MinNumMissing", 2), [1,2;NaN,4])
 
+## Test second output
+%!test
+%! x = [1:6];
+%! x([2,4]) = NaN;
+%! [~, idx] = rmmissing (x);
+%! assert (idx, logical ([0, 1, 0, 1, 0, 0]));
+%! assert (class(idx), 'logical');
+%! x = reshape (x, [2, 3]);
+%! [~, idx] = rmmissing (x);
+%! assert (idx, logical ([0; 1]));
+%! assert (class(idx), 'logical');
+%! [~, idx] = rmmissing (x, 2);
+%! assert (idx, logical ([1, 1, 0]));
+%! assert (class(idx), 'logical');
+%! [~, idx] = rmmissing (x, 1, "MinNumMissing", 2);
+%! assert (idx, logical ([0; 1]));
+%! assert (class(idx), 'logical');
+%! [~, idx] = rmmissing (x, 2, "MinNumMissing", 2);
+%! assert (idx, logical ([0, 0, 0]));
+%! assert (class(idx), 'logical');
+
+## Test data type handling
+%!assert (rmmissing (single ([1 2 NaN; 3 4 5])), single ([3 4 5]))
+%!assert (rmmissing (logical (ones (3))), logical (ones (3)))
+%!assert (rmmissing (int32 (ones (3))), int32 (ones (3)))
+%!assert (rmmissing (uint32 (ones (3))), uint32 (ones (3)))
+
+## Test empty input handling
+%!assert (rmmissing ([]), [])
+%!assert (rmmissing (ones (1,0)), ones (1,0))
+%!assert (rmmissing (ones (1,0), 1), ones (1,0))
+%!assert (rmmissing (ones (1,0), 2), ones (1,0))
+%!assert (rmmissing (ones (0,1)), ones (0,1))
+%!assert (rmmissing (ones (0,1), 1), ones (0,1))
+%!assert (rmmissing (ones (0,1), 2), ones (0,1))
+%!error <input dimension> rmmissing (ones (0,1,2))
+
 ## Test input validation
-%!error rmmissing ();
-%!error rmmissing ({1, 2, 3});
-%!error <must be either 1 or 2> rmmissing ([1 2; 3 4], 5);
-%!error <unknown parameter name> rmmissing ([1 2; 3 4], "XXX", 1);
-%!error <'MinNumMissing'> rmmissing ([1 2; 3 4], 2, "MinNumMissing", -2);
-%!error <'MinNumMissing'> rmmissing ([1 2; 3 4], "MinNumMissing", 3.8);
-%!error <'MinNumMissing'> rmmissing ([1 2; 3 4], "MinNumMissing", [1 2 3]);
-%!error <'MinNumMissing'> rmmissing ([1 2; 3 4], "MinNumMissing", 'xxx');
+%!error rmmissing ()
+%!error rmmissing ({1, 2, 3})
+%!error <input dimension> rmmissing (ones(2,2,2))
+%!error <must be either 1 or 2> rmmissing ([1 2; 3 4], 5)
+%!error <unknown parameter name> rmmissing ([1 2; 3 4], "XXX", 1)
+%!error <'MinNumMissing'> rmmissing ([1 2; 3 4], 2, "MinNumMissing", -2)
+%!error <'MinNumMissing'> rmmissing ([1 2; 3 4], "MinNumMissing", 3.8)
+%!error <'MinNumMissing'> rmmissing ([1 2; 3 4], "MinNumMissing", [1 2 3])
+%!error <'MinNumMissing'> rmmissing ([1 2; 3 4], "MinNumMissing", 'xxx')
+
diff -r c95d345becf9 -r 30ba00c94c5b install-conditionally/base/standardizeMissing.m
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/install-conditionally/base/standardizeMissing.m	Fri Dec 17 16:55:41 2021 -0500
@@ -0,0 +1,199 @@
+########################################################################
+##
+## Copyright (C) 1995-2021 The Octave Project Developers
+##
+## See the file COPYRIGHT.md in the top-level directory of this
+## distribution or <https://octave.org/copyright/>.
+##
+## This file is part of Octave.
+##
+## Octave is free software: you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation, either version 3 of the License, or
+## (at your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+## GNU General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <https://www.gnu.org/licenses/>.
+##
+########################################################################
+
+## -*- texinfo -*-
+## @deftypefn {} {@var{B} =} standardizeMissing (@var{A}, @var{indicator})
+##
+## Replace data values specified by @var{indicator} in @var{A} by the
+## standard 'missing' data value for that data type.
+##
+## @var{A} can be a numeric scalar or array, a character vector or array, or
+## a cell array of character vectors (a.k.a. string cells).
+##
+## @var{indicator} can be a scalar or an array containing values to be
+## replaced by the 'missing' value for the class of @var{A}, and should have
+## a data type matching @var{A}.
+##
+## 'missing' values are defined as :
+##
+## @itemize
+## @item
+## @code{NaN}: @code{single}, @code{double}
+##
+## @item
+## @code{' '} (white space): @code{char}
+##
+## @item
+## @code{@{''@}} (empty string in cell): string cells.
+## @end itemize
+##
+## Compatibility Notes:
+## @itemize
+## @item
+## Octave's implementation of @code{standardizeMissing}
+## does not restrict @var{indicator} of type 'char' to row vectors.
+##
+## @item
+## All numerical and logical inputs for @var{A} and @var{indicator} may
+## be specified in any combination. The output will be the same class as
+## @var{A}, with the @var{indicator} converted to that data type for
+## comparison.  Only @code{single} and @code{double} have defined 'missing'
+## values, so @var{A} of other data types will always output
+## @var{B} = @var{A}.
+## @end itemize
+##
+## @end deftypefn
+##
+## @seealso{ismissing, rmmissing}
+
+function A = standardizeMissing (A, indicator)
+
+  if (nargin != 2)
+     print_usage ();
+  endif
+
+  input_class = class(A);
+  do_nothing_flag = false;
+
+  ## Set missing_val.
+  ## Compatibility requirements:
+  ## Numeric/logical: Only double and single have 'missing' values defined,
+  ## so other numeric and logical pass through unchanged.
+  ## Other: only char & cellstr have 'missing' values defined, others produce
+  ## error.
+  ##
+  ## TODO: as implemented in Octave, add table, string, timetable,
+  ## categorical, datetime, and duration to class checks and BISTs
+  ##
+  ## TODO: when 'missing' class is implemented, these switch blocks can all
+  ## be removed and the final assignment updated to call missing instead of
+  ## missing_val
+
+  if (isnumeric(A) || islogical(A))
+    switch (input_class)
+      case 'double'
+        missing_val = NaN ("double");
+      case 'single'
+        missing_val = NaN ("single");
+      otherwise
+        do_nothing_flag = true;
+    endswitch
+  else
+    switch (input_class)
+      case 'char'
+        missing_val = ' ';
+      case 'cell'
+        if iscellstr(A)
+          missing_val = {''};
+        else
+          error("stardardizeMissing: only cells of strings are supported")
+        endif
+    otherwise
+      error ("standardizeMissing: unsupported data type %s", input_class);
+    endswitch
+  endif
+
+  if (! do_nothing_flag)
+
+    ## if A is an array of cell strings and indicator just a string,
+    ## convert indicator to a cell string with one element
+    if (iscellstr (A) && ischar (indicator) && ! iscellstr (indicator))
+      indicator = {indicator};
+    endif
+
+    if ((isnumeric (A) && ! (isnumeric (indicator)|| islogical (indicator))) ||
+        (ischar (A) && ! ischar (indicator)) ||
+        (iscellstr (A) && ! (iscellstr (indicator))))
+      error ("standardizeMissing: 'indicator' and 'A' must have the same data type");
+    endif
+
+    A(ismember (A, indicator)) = missing_val;
+
+  endif
+endfunction
+
+## numeric tests
+%!assert (standardizeMissing (1, 1), NaN)
+%!assert (standardizeMissing (1, 0), 1)
+%!assert (standardizeMissing (eye(2), 1), [NaN 0;0 NaN])
+%!assert (standardizeMissing ([1:3;4:6], [2 3; 4 5]), [1, NaN, NaN; NaN, NaN, 6])
+%!assert (standardizeMissing (cat (3,1,2,3,4), 3), cat (3,1,2,NaN,4))
+
+## char and cellstr tests
+%!assert (standardizeMissing ('foo', 'a'), 'foo')
+%!assert (standardizeMissing ('foo', 'f'), ' oo')
+%!assert (standardizeMissing ('foo', 'o'), 'f  ')
+%!assert (standardizeMissing ('foo', 'oo'), 'f  ')
+
+%!assert (standardizeMissing ({'foo'}, 'f'), {'foo'})
+%!assert (standardizeMissing ({'foo'}, {'f'}), {'foo'})
+%!assert (standardizeMissing ({'foo'}, 'test'), {'foo'})
+%!assert (standardizeMissing ({'foo'}, {'test'}), {'foo'})
+%!assert (standardizeMissing ({'foo'}, 'foo'), {''})
+%!assert (standardizeMissing ({'foo'}, {'foo'}), {''})
+
+## char and cellstr array tests
+%!assert (standardizeMissing (['foo';'bar'], 'oar'), ['f  ';'b  '])
+%!assert (standardizeMissing (['foo';'bar'], ['o';'a';'r']), ['f  ';'b  '])
+%!assert (standardizeMissing (['foo';'bar'], ['o ';'ar']), ['f  ';'b  '])
+
+%!assert (standardizeMissing ({'foo','bar'}, 'foo'), {'','bar'})
+%!assert (standardizeMissing ({'foo','bar'}, 'f'), {'foo','bar'})
+%!assert (standardizeMissing ({'foo','bar'}, {'foo', 'a'}), {'','bar'})
+%!assert (standardizeMissing ({'foo'}, {'f', 'oo'}), {'foo'})
+%!assert (standardizeMissing ({'foo','bar'}, {'foo'}), {'','bar'})
+%!assert (standardizeMissing ({'foo','bar'}, {'foo', 'a'}), {'','bar'})
+
+## numeric type preservation tests
+%!assert (standardizeMissing (double (1), single (1)), double (NaN))
+%!assert (standardizeMissing (single (1), single (1)), single (NaN))
+%!assert (standardizeMissing (single (1), double (1)), single (NaN))
+%!assert (standardizeMissing (single (1), true), single (NaN))
+%!assert (standardizeMissing (double (1), int32(1)), double (NaN))
+
+## Passttrough tests
+%!assert (standardizeMissing (true, true), true)
+%!assert (standardizeMissing (true, 1), true)
+%!assert (standardizeMissing (int32 (1), int32 (1)), int32 (1))
+%!assert (standardizeMissing (int32 (1), 1), int32 (1))
+%!assert (standardizeMissing (uint32 (1), uint32 (1)), uint32 (1))
+%!assert (standardizeMissing (uint32 (1), 1), uint32 (1))
+
+## Test input validation
+%!error standardizeMissing ();
+%!error standardizeMissing (1);
+%!error standardizeMissing (1,2,3);
+%!error <only cells of strings> standardizeMissing ({'abc', 1}, 1);
+%!error <unsupported data type> standardizeMissing (struct ('a','b'), 1);
+%!error <'indicator' and 'A' must have > standardizeMissing ([1 2 3], {1});
+%!error <'indicator' and 'A' must have > standardizeMissing ([1 2 3], 'a');
+%!error <'indicator' and 'A' must have > standardizeMissing ([1 2 3], struct ('a', 1));
+%!error <'indicator' and 'A' must have > standardizeMissing ('foo', 1);
+%!error <'indicator' and 'A' must have > standardizeMissing ('foo', {1});
+%!error <'indicator' and 'A' must have > standardizeMissing ('foo', {'f'});
+%!error <'indicator' and 'A' must have > standardizeMissing ('foo', struct ('a', 1));
+%!error <'indicator' and 'A' must have > standardizeMissing ({'foo'}, 1);
+%!error <'indicator' and 'A' must have > standardizeMissing ({'foo'}, 1);
+
