changeset 31914:034c8ab3d7d3

Backed out changeset 01ae7ebc6a13 cov.m causing BIST failures in corr.m and other calling functions. Backing out until corr updated.
author Nicholas R. Jankowski <jankowski.nicholas@gmail.com>
date Mon, 20 Mar 2023 22:54:54 -0400
parents 01ae7ebc6a13
children b35cd94027b0
files etc/NEWS.9.md scripts/statistics/cov.m
diffstat 2 files changed, 88 insertions(+), 426 deletions(-) [+]
line wrap: on
line diff
--- a/etc/NEWS.9.md	Mon Mar 20 16:04:42 2023 -0400
+++ b/etc/NEWS.9.md	Mon Mar 20 22:54:54 2023 -0400
@@ -38,12 +38,7 @@
 limits of single precision by processing as doubles (bug #63848).  `median`
 has also adopted the 'outtype' option from `mean`.
 
-- `mode` now produces Matlab compatible output for empty inputs (bug #50583).
- 
-- `cov` now processes the input form cov(x,y) with two separate data arrays
-x and y, as cov (x(:), y(:)) to maintain Matlab compatibility.  It also
-accepts a NANFLAG option to allow ignoring NaN entries in input data (bug 
-#50571) and produces Matlab compatible outputs for empty inputs (bug #50583).
+- `mode` now produces Matlab compatible outputs for empty inputs.
 
 ### Alphabetical list of new functions added in Octave 9
 
--- a/scripts/statistics/cov.m	Mon Mar 20 16:04:42 2023 -0400
+++ b/scripts/statistics/cov.m	Mon Mar 20 22:54:54 2023 -0400
@@ -25,488 +25,155 @@
 
 ## -*- texinfo -*-
 ## @deftypefn  {} {@var{c} =} cov (@var{x})
+## @deftypefnx {} {@var{c} =} cov (@var{x}, @var{opt})
 ## @deftypefnx {} {@var{c} =} cov (@var{x}, @var{y})
-## @deftypefnx {} {@var{c} =} cov (@dots{}, @var{opt})
-## @deftypefnx {} {@var{c} =} cov (@dots{}, @var{nanflag})
+## @deftypefnx {} {@var{c} =} cov (@var{x}, @var{y}, @var{opt})
 ## Compute the covariance matrix.
 ##
-## The covariance between two variable vectors @var{A} and  @var{B} is
-## calculated as:
+## If each row of @var{x} and @var{y} is an observation, and each column is
+## a variable, then the @w{(@var{i}, @var{j})-th} entry of
+## @code{cov (@var{x}, @var{y})} is the covariance between the @var{i}-th
+## variable in @var{x} and the @var{j}-th variable in @var{y}.
 ## @tex
 ## $$
-## \sigma_{ij} = {1 \over N-1} \sum_{i=1}^N (a_i - \bar{a})(b_i - \bar{b})
+## \sigma_{ij} = {1 \over N-1} \sum_{i=1}^N (x_i - \bar{x})(y_i - \bar{y})
 ## $$
-## where $\bar{a}$ and $\bar{b}$ are the mean values of $a$ and $b$ and $N$ is
-## the length of the vectors $a$ and $b$.
+## where $\bar{x}$ and $\bar{y}$ are the mean values of @var{x} and @var{y}.
 ## @end tex
 ## @ifnottex
 ##
 ## @example
-## cov (@var{a},@var{b}) = 1/(N-1) * SUM_i (@var{a}(i) - mean (@var{a})) * (@var{b}(i) - mean (@var{b}))
+## cov (@var{x}) = 1/(N-1) * SUM_i (@var{x}(i) - mean(@var{x})) * (@var{y}(i) - mean(@var{y}))
 ## @end example
 ##
 ## @noindent
-## where @math{N} is the length of the vectors @var{a} and @var{b}.
+## where @math{N} is the length of the @var{x} and @var{y} vectors.
+##
 ## @end ifnottex
 ##
-## If called with one argument, compute @code{cov (@var{x}, @var{x})}.  If
-## @var{x} is a vector, this is the scalar variance of @var{x}.  If @var{x} is
-## a matrix, each row of @var{x} is treated as an observation, and each column
-## as a variable, and the @w{(@var{i}, @var{j})-th} entry of
-## @code{cov (@var{x})} is the covariance between the @var{i}-th and
-## @var{j}-th columns in @var{x}.  If @var{x} has dimensions n x m, the output
-## @var{c} will be a m x m square covariance matrix.
+## If called with one argument, compute @code{cov (@var{x}, @var{x})}, the
+## covariance between the columns of @var{x}.
 ##
-## If called with two arguments, compute @code{cov (@var{x}, @var{y})}, the
-## covariance between two random variables @var{x} and @var{y}.  @var{x} and
-## @var{y} must have the same number of elements, and will be treated as
-## vectors with the covariance computed as
-## @code{cov (@var{x}(:), @var{y}(:))}.  The output will be a 2 x 2
-## covariance matrix.
-##
-## The optional argument @var{opt} determines the type of normalization to
-## use.  Valid values are
+## The argument @var{opt} determines the type of normalization to use.
+## Valid values are
 ##
 ## @table @asis
-## @item 0 [default]:
-##   Normalize with @math{N-1}.  This provides the best unbiased estimator of
-## thecovariance
+## @item 0:
+##   normalize with @math{N-1}, provides the best unbiased estimator of the
+## covariance [default]
 ##
 ## @item 1:
-##   Normalize with @math{N}.  This provides the second moment around the
-## mean.  @var{opt} is set to 1 for N = 1.
+##   normalize with @math{N}, this provides the second moment around the mean
 ## @end table
 ##
-## The optional argument @var{nanflag} must appear last in the argument list
-## and controls how NaN values are handled by @code{cov}.  The three valid
-## values are:
-##
-## @table @asis
-## @item includenan [default]:
-##   Leave NaN values in @var{x} and @var{y}.  Output will follow the normal
-## rules for handling NaN values in arithemtic operations.
-##
-## @item omitrows:
-##   Rows containing NaN values are trimmed from both @var{x} and @var{y}
-## prior to calculating the covariance.  (A NaN in one variable will remove
-## that row from both @var{x} and @var{y}.)
-##
-## @item partialrows:
-##   Rows containing NaN values are ignored from both @var{x} and @var{y}
-##   independently for each @var{i}-th and @var{j}-th covariance
-##   calculation.  This may result in a different number of observations,
-##   @math{N}, being used to calculated each element of the covariance matrix.
-## @end table
-##
-## Compatibility Note:  Previous versions of @code{cov} treated rows
-## @var{x} and @var{y} as multivariate random variables.  This version
-## attempts to maintain full compatibility with @sc{matlab} by treating
-## @var{x} and @var{y} as two univariate distributions regardless of shape,
-## resulting in a 2x2 output matrix.  Code relying on Octave's previous
-## definition will need to be modified when running this newer version of
-## @code{cov}.  The previous behavior can be obtained by using the
-## NaN package's @code{covm} function as @code{covm (@var{x}, @var{y}, "D")}.
+## Compatibility Note:: Octave always treats rows of @var{x} and @var{y}
+## as multivariate random variables.
+## For two inputs, however, @sc{matlab} treats @var{x} and @var{y} as two
+## univariate distributions regardless of their shapes, and will calculate
+## @code{cov ([@var{x}(:), @var{y}(:)])} whenever the number of elements in
+## @var{x} and @var{y} are equal.  This will result in a 2x2 matrix.
+## Code relying on @sc{matlab}'s definition will need to be changed when
+## running in Octave.
 ## @seealso{corr}
 ## @end deftypefn
 
-function c = cov (x, varargin)
+function c = cov (x, y = [], opt = 0)
 
-  if (nargin < 1 || nargin > 4)
+  if (nargin < 1)
     print_usage ();
   endif
 
-  opt = 0;
-  is_y = false;
-  nanflag = "includenan";
+  if (   ! (isnumeric (x) || islogical (x))
+      || ! (isnumeric (y) || islogical (y)))
+    error ("cov: X and Y must be numeric matrices or vectors");
+  endif
+
+  if (ndims (x) != 2 || ndims (y) != 2)
+    error ("cov: X and Y must be 2-D matrices or vectors");
+  endif
+
+  if (nargin == 2 && isscalar (y))
+    opt = y;
+  endif
 
-  if (! (isnumeric (x) || islogical (x)))
-      error ("cov: X must be a numeric vector or matrix");
+  if (opt != 0 && opt != 1)
+    error ("cov: normalization OPT must be 0 or 1");
+  endif
+
+  ## Special case, scalar has zero covariance
+  if (isscalar (x))
+    if (isa (x, "single"))
+      c = single (0);
+    else
+      c = 0;
+    endif
+    return;
   endif
 
   if (isrow (x))
     x = x.';
   endif
-
-  nvarg = numel (varargin);
-
-  if (nvarg > 0)
-    switch (nvarg)
-      case 3
-        ## Only char input should be nanflag, must be last.
-        if (ischar (varargin{1}) || ischar (varargin {2}))
-          if (ischar (varargin{3}))
-            error ("cov: only one NANFLAG parameter may be specified");
-          else
-            error ("cov: NANFLAG parameter must be the last input");
-          endif
-        endif
-
-        y = varargin{1};
-        opt = double (varargin{2}); # opt should not affect output class.
-        nanflag = lower (varargin {3});
-        is_y = true;
-
-      case 2
-        if (ischar (varargin{1}))
-          error ("cov: NANFLAG parameter must be the last input");
-        endif
-
-        if (ischar (varargin{end}))
-          nanflag = lower (varargin{end});
-
-          if (isscalar (varargin{1}) && ...
-            (varargin{1} == 0 || varargin{1} == 1))
-            opt = double (varargin {1});
-
-          else
-            y = varargin{1};
-            is_y = true;
-          endif
+  n = rows (x);
 
-        else
-          y = varargin{1};
-          opt = double (varargin{2});
-          is_y = true;
-        endif
-
-      case 1
-        if (ischar (varargin{end}))
-          nanflag = lower (varargin{end});
-
-        elseif (isscalar (varargin{1}) && ...
-               (varargin{1} == 0 || varargin{1} == 1))
-          opt = double (varargin {1});
-
-        else
-          y = varargin{1};
-          is_y = true;
-        endif
-    endswitch
-
-    if (is_y)
-      if (! (isnumeric (y) || islogical (y)))
-        error ("cov: Y must be a numeric vector or matrix");
-
-      elseif (numel (x) != numel (y))
-        error ("cov: X and Y must have the same number of observations");
-
-      else
-        ## Flatten to single array.  Process the same as two-column x.
-        x = [x(:), y(:)];
-      endif
+  if (nargin == 1 || isscalar (y))
+    x = center (x, 1);
+    c = x' * x / (n - 1 + opt);
+  else
+    if (isrow (y))
+      y = y.';
     endif
-
-    if (! any (strcmp (nanflag, {"includenan", "omitrows", "partialrows"})))
-        error ("cov: unknown NANFLAG parameter '%s'", nanflag);
+    if (rows (y) != n)
+      error ("cov: X and Y must have the same number of observations");
     endif
-
-    if ((opt != 0 && opt != 1) || ! isscalar (opt))
-      error ("cov: normalization paramter OPT must be 0 or 1");
-    endif
+    x = center (x, 1);
+    y = center (y, 1);
+    c = x' * y / (n - 1 + opt);
   endif
 
-  if (ndims (x) > 2)
-    ## Note: Matlab requires 2D inputs even if providing a y input results in
-    ##       reshaping for operation as cov (x(:), y(:)) (tested in 2022b).
-    ##       Octave permits arbitrarily shaped inputs for the cov(x,y) case as
-    ##       long as numel (x) == numel (y).  Only when no y is provided is X
-    ##       restricted to 2D for consistent 2D columnwise behavior of cov.
-    error ("cov: X must be a 2-D matrix or vector");
-  endif
-
-  ## Special case: empty inputs.  Output shape changes depends on number of
-  ## columns.  Inputs already verified as limited to 2D.
-  if (isempty (x))
-    sx = size (x);
-
-    if (sx == [0, 0])
-      c = NaN;
-    elseif (sx(1) > 0)
-      c = [];
-    else
-      c = NaN (sx(2));
-    endif
-
-    if (isa (x, "single"))
-      c = single (c);
-    endif
-    return;
-  endif
-
-  if (! strcmp (nanflag, "includenan") && all (nnx = ! isnan (x)))
-    ## Avoid unnecessary slower nanflag processing.
-    nanflag = "includenan";
-  endif
-
-  switch (nanflag)
-    case {"includenan", "omitrows"}
-
-      if (strcmp (nanflag, "omitrows"))
-        ## Trim any rows in x containing a NaN.
-        x = x(all (nnx, 2), :);
-      endif
-
-      n = rows (x);
+endfunction
 
-      if (n < 2)
-        ## Scalars and empties force opt = 1.
-        opt = 1;
-      endif
-
-      x -= sum (x, 1) / n;
-      c = x' * x / (n - 1 + opt);
-
-    case "partialrows"
-      ## Find all NaN locations for adjusted processing later.  NaN's will
-      ## only be trimmed for the columns containing them when calculating
-      ## covariance involving that row.  Each output element of c might have a
-      ## unique n, opt, and mean for each of the two vectors used to calculate
-      ## that element based on the paired column total number of non-NaN rows.
-      ## Separate out simple vector case.  Project into dim3 for general case.
-
-      if (iscolumn (x))
-        x = x(nnx);
-        n = numel (x);
-        if (n < 2)
-          opt = 1;
-        endif
-        x -= sum (x, 1) / n;
-
-        ## Matrix multiplication preserves output size compatibliity if x is
-        ## trimmed to empty.
-        c = (x' * x) / (n - 1 + opt);
-      else
-
-        ## Number of elements in each column pairing.
-        n = nnx' * nnx;
-
-        ## opt for each column pairing
-        opt = opt * ones (columns (x));
-        opt (n < 2) = 1;
-
-        ## Mean for each column pairing.
-        ## Rotate x vectors into dim3, project into dim1 with non-nan array
-        x = permute(x, [3, 2, 1]) .* permute (nnx, [2, 3, 1]);
-        mu = x;
-        mu (isnan (x)) = 0; # Exclude input NaNs from summation.
-        mu = sum (mu, 3) ./ n; # Vectors trimmed to n=0 may create more NaNs.
-        x -= mu; # Center x's.
-        x(isnan (x)) = 0; # Exclude input and mean NaNs from output.
-
-        ## Sum dim3 elements of x products to emulate x'*x.
-        c = sum (permute (x, [2,1,3]) .* x, 3) ./ (n - 1 + opt);
-
-      endif
-  endswitch
-endfunction
 
 %!test
 %! x = rand (10);
 %! cx1 = cov (x);
 %! cx2 = cov (x, x);
-%! assert (size (cx1) == [10, 10]);
-%! assert (size (cx2) == [2, 2]);
-
-%!test
-%! x = [1:3]';
-%! y = [3:-1:1]';
-%! assert (cov (x, x), [1 1; 1 1]);
-%! assert (cov (x, x), cov ([x, x]));
-%! assert (cov (x, y), [1 -1; -1 1]);
-%! assert (cov (x, y), cov ([x, y]));
+%! assert (size (cx1) == [10, 10] && size (cx2) == [10, 10]);
+%! assert (cx1, cx2, 1e1*eps);
 
 %!test
 %! x = [1:3]';
 %! y = [3:-1:1]';
-%! assert (cov (single (x)), single (1));
-%! assert (cov (single (x), x), single ([1 1; 1 1]));
-%! assert (cov (x, single (x)), single ([1 1; 1 1]));
-%! assert (cov (single (x), single (x)), single ([1 1; 1 1]));
-
-%!test
-%! x = [1:8];
-%! c = cov (x);
-%! assert (isscalar (c));
-%! assert (c, 6);
+%! assert (cov (x, y), -1, 5*eps);
+%! assert (cov (x, flipud (y)), 1, 5*eps);
+%! assert (cov ([x, y]), [1 -1; -1 1], 5*eps);
 
 %!test
-%! x = [1 0; 1 0];
-%! y = [1 2; 1 1];
-%! z = [1/3 -1/6; -1/6 0.25];
-%! assert (cov (x, y), z, eps);
-%! assert (cov (x, y(:)), z, eps);
-%! assert (cov (x, y(:)'), z, eps);
-%! assert (cov (x', y(:)), z .* [1, -1; -1, 1], eps);
-%! assert (cov (x(:), y), z, eps);
-%! assert (cov (x(:)', y), z, eps);
+%! x = single ([1:3]');
+%! y = single ([3:-1:1]');
+%! assert (cov (x, y), single (-1), 5*eps);
+%! assert (cov (x, flipud (y)), single (1), 5*eps);
+%! assert (cov ([x, y]), single ([1 -1; -1 1]), 5*eps);
 
-## Test scalar inputs & class preservation
+%!test
+%! x = [1:5];
+%! c = cov (x);
+%! assert (isscalar (c));
+%! assert (c, 2.5);
+
 %!assert (cov (5), 0)
-%!assert (cov (1, 0), 0)
-%!assert (cov (1, 1), 0)
-%!assert (cov (1, 0.1), [0, 0; 0, 0])
-%!assert (cov (1, 1.1), [0, 0; 0, 0])
-%!assert (cov (1, 3), [0, 0; 0, 0])
 %!assert (cov (single (5)), single (0))
-%!assert (cov (single (5), 0), single (0))
-%!assert (cov (single (5), 1), single (0))
-%!assert (cov (single (5), 1.1), single ([0, 0; 0, 0]))
-%!assert (cov (5, single (0)), double (0))
-%!assert (cov (5, single (1)), double (0))
-%!assert (cov (5, single (1.1)), single ([0, 0; 0, 0]))
-%!assert (cov (5, single (1.1), 0), single ([0, 0; 0, 0]))
-%!assert (cov (5, single (1.1), 1), single ([0, 0; 0, 0]))
-%!assert (cov (5, 1.1, single (0)), double([0, 0; 0, 0]))
 
-## Test opt
 %!test
 %! x = [1:5];
 %! c = cov (x, 0);
 %! assert (c, 2.5);
 %! c = cov (x, 1);
 %! assert (c, 2);
-%! c = cov (double (x), single (1));
-%! assert (class (c), "double");
-%!assert (cov (2, 4), zeros(2))
-%!assert (cov (2, 4, 0), zeros(2))
-%!assert (cov (2, 4, 1), zeros(2))
-%!assert (cov (NaN, 4), [NaN, NaN; NaN, 0])
-%!assert (cov (NaN, 4, 0), [NaN, NaN; NaN, 0])
-%!assert (cov (NaN, 4, 1), [NaN, NaN; NaN, 0])
-
-## Test logical inputs
-%!assert (cov (logical(0), logical(0)), double(0))
-%!assert (cov (0, logical(0)), double(0))
-%!assert (cov (logical(0), 0), double(0))
-%!assert (cov (logical([0 1; 1 0]), logical([0 1; 1 0])), double ([1 1;1 1]./3))
-
-## Test empty and NaN handling (bug #50583)
-%!assert <*50583> (cov ([]), NaN)
-%!assert <*50583> (cov (single ([])), single (NaN))
-%!assert <*50583> (cov ([], []), NaN (2, 2))
-%!assert <*50583> (cov (single ([]), single([])),  single (NaN (2, 2)))
-%!assert <*50583> (cov ([], single ([])), single (NaN (2, 2)))
-%!assert <*50583> (cov (single ([]), []), single (NaN (2, 2)))
-%!assert <*50583> (cov (ones(1, 0)), NaN)
-%!assert <*50583> (cov (ones(2, 0)), [])
-%!assert <*50583> (cov (ones(0, 1)), NaN)
-%!assert <*50583> (cov (ones(0, 2)), NaN (2, 2))
-%!assert <*50583> (cov (ones(0, 6)), NaN (6, 6))
-%!assert <*50583> (cov (ones(2, 0), []), NaN (2, 2))
-%!assert <*50583> (cov (ones(0,6), []), NaN (2, 2))
-%!assert <*50583> (cov (NaN), NaN)
-%!assert <*50583> (cov (NaN, NaN), NaN (2, 2))
-%!assert <*50583> (cov (5, NaN), [0, NaN; NaN, NaN])
-%!assert <*50583> (cov (NaN, 5), [NaN, NaN; NaN, 0])
-%!assert <*50583> (cov (single (NaN)), single (NaN))
-%!assert <*50583> (cov (NaN (2, 2)), NaN (2, 2))
-%!assert <*50583> (cov (single (NaN (2, 2))), single (NaN (2, 2)))
-%!assert <*50583> (cov (NaN(2, 9)), NaN(9, 9))
-%!assert <*50583> (cov (NaN(9, 2)), NaN(2, 2))
-%!assert <*50583> (cov ([NaN, 1, 2, NaN]), NaN)
-%!assert <*50583> (cov ([1, NaN, 2, NaN]), NaN)
-
-## Test NaN and nanflag option (bug #50571)
-%!test <*50571>
-%! x = magic(3);
-%! y = magic(3);
-%! x(3) = NaN;
-%! assert (cov (y, "omitrows"), cov(y));
-%! assert (cov (y, "partialrows"), cov(y));
-%! assert (cov (x), [NaN, NaN, NaN; NaN, 16, -8; NaN, -8, 7]);
-%! assert (cov (x, "omitrows"), ...
-%!   [12.5, -10, -2.5; -10, 8, 2; -2.5, 2, 0.5], eps);
-%! assert (cov (x, "partialrows"),
-%!   [12.5, -10, -2.5; -10, 16, -8; -2.5, -8, 7], eps);
-%! assert (cov (x, x), NaN(2,2));
-%! assert (cov (x, y), [NaN, NaN; NaN, 7.5], eps);
-%! assert (cov (y, x), [7.5, NaN; NaN, NaN], eps);
-%! assert (cov (x, x, 'omitrows'), (471/56) * ones(2), eps);
-%! assert (cov (x, x, 'partialrows'), (471/56) * ones(2), eps);
-%! assert (cov (x, y, 'omitrows'), (471/56) * ones(2), eps);
-%! assert (cov (x, y, 'partialrows'), (471/56)*[1,1;1,0] + [0,0;0,7.5], eps);
-%! assert (cov (y, x, 'omitrows'), (471/56) * ones(2), eps);
-%! assert (cov (y, x, 'partialrows'), (471/56)*[0,1;1,1] + [7.5,0;0,0], eps);
-%! assert (cov (x, y, 0, 'omitrows'), (471/56) * ones(2), eps);
-%! assert (cov (x, y, 0, 'partialrows'), (471/56)*[1,1;1,0] + [0,0;0,7.5], eps);
-%!assert (cov ([NaN NaN NaN]), NaN)
-%!assert <*50571> (cov ([NaN NaN NaN], "omitrows"), NaN)
-%!assert <*50571> (cov ([NaN NaN NaN], "partialrows"), NaN)
-%!assert (cov (NaN(3)), NaN(3))
-%!assert <*50571> (cov (NaN(3), "omitrows"), NaN(3))
-%!assert <*50571> (cov (NaN(3), "partialrows"), NaN(3))
-%!assert (cov ([NaN NaN NaN],[1 2 3]), [NaN, NaN; NaN 1])
-%!assert <*50571> (cov ([NaN NaN NaN],[1 2 3], "omitrows"), [NaN, NaN; NaN NaN])
-%!assert <*50571> (cov ([NaN NaN NaN],[1 2 3], "partialrows"), [NaN, NaN; NaN 1])
-%!test <*50571>
-%! x = magic(3);
-%! x(4:6) = NaN;
-%! assert (cov (x), [7 NaN 1; NaN NaN NaN; 1 NaN 7]);
-%! assert (cov (x, "omitrows"), NaN(3));
-%! assert (cov (x, "partialrows"), [7 NaN 1; NaN NaN NaN; 1 NaN 7]);
-%!assert <*50571> (cov (5, NaN, "omitrows"), NaN(2, 2))
-%!assert <*50571> (cov (NaN, 5, "omitrows"), NaN(2, 2))
-%!assert <*50571> (cov (5, NaN, "partialrows"), [0, NaN; NaN, NaN])
-%!assert <*50571> (cov (NaN, 5, "partialrows"), [NaN, NaN; NaN, 0])
-%!test <*50571>
-%! x = [1:10]';
-%! y = x;
-%! x(2:2:10)=NaN;
-%! y(1:2:9)=NaN;
-%! assert (cov(x,y), NaN(2));
-%! assert (cov(x,y,'omitrows'), NaN(2));
-%! assert (cov(x,y,'partialrows'), [10 NaN; NaN, 10]);
-%! x(10) = 5;
-%! assert (cov(x,y), NaN(2));
-%! assert (cov(x,y,'omitrows'), zeros(2));
-%! assert (cov(x,y,'partialrows'), [8 0; 0, 10]);
-#!assert (cov ([NaN, NaN, 3]), NaN)
-#!assert <*50571>  (cov ([NaN, NaN, 3], 'omitrows'), 0)
-#!assert <*50571> (cov ([NaN, NaN, 3], 'partialrows'), 0)
-%!assert (cov ([NaN, NaN, NaN; NaN, 2, 3; NaN, NaN, 3]), NaN(3))
-%!assert <*50571> (cov ([NaN, NaN, NaN; NaN, 2, 3; NaN, NaN, 3], 'omitrows'), NaN(3))
-%!assert <*50571> (cov ([NaN, NaN, NaN; NaN, 2, 3; NaN, NaN, 3], 'partialrows'), [NaN, NaN, NaN; NaN(2,1), zeros(2)])
-%!assert <*50571> (cov ([NaN, NaN, NaN; NaN, 2, 3; NaN, NaN, 3], 0, 'partialrows'), [NaN, NaN, NaN; NaN(2,1), zeros(2)])
-%!assert <*50571> (cov ([NaN, NaN, NaN; NaN, 2, 3; NaN, NaN, 3], 1, 'partialrows'), [NaN, NaN, NaN; NaN(2,1), zeros(2)])
-%!test <*50571>
-%! x = magic(4);
-%! x([4 5 7 10 14 16]) = NaN;
-%! x1 = x(:,2);
-%! x2 = x(:,3);
-%! assert (cov(x1,x2),nan(2));
-%! assert (cov(x1,x2,'omitrows'),zeros(2));
-%! assert (cov(x1,x2, 'partialrows'), [4.5,0;0,39],eps);
-%! assert (cov(x1,x2,0,'partialrows'), [4.5,0;0,39],eps);
-%! assert (cov(x1,x2,1,'partialrows'), [2.25,0;0,26],eps);
-%! assert (cov(x), nan(4));
-%! assert (cov(x,'omitrows'), nan(4));
-%! assert (cov(x,'partialrows'), [31 0 -10.5 3.5; 0 4.5 0 NaN; -10.5 0 39 -1.5; 3.5 NaN -1.5 0.5], eps);
-%! assert (cov(x, 0, 'partialrows'), [31 0 -10.5 3.5; 0 4.5 0 NaN; -10.5 0 39 -1.5; 3.5 NaN -1.5 0.5], eps);
-%! assert (cov(x, 1,'partialrows'), [62/3 0 -5.25 1.75; 0 2.25 0 NaN; -5.25 0 26 -0.75; 1.75 NaN -0.75 0.25], eps);
 
 ## Test input validation
 %!error <Invalid call> cov ()
-%!error <Invalid call> cov (1, 2, 3, 4, 5)
-%!error <X must be a> cov ("foo")
-%!error <X must be a> cov ({123})
-%!error <X must be a> cov (struct())
-%!error <X must be a> cov (ones (2, 2, 2))
-%!error <X must be a> cov (ones (1, 0, 2))
-%!error <only one NANFLAG> cov (1, "foo", 0, "includenan")
-%!error <only one NANFLAG> cov (1, 1, "foo", "includenan")
-%!error <normalization paramter OPT must be> cov (1, 2, [])
-%!error <normalization paramter OPT must be> cov (1, 2, 1.1)
-%!error <normalization paramter OPT must be> cov (1, 2, -1)
-%!error <normalization paramter OPT must be> cov (1, 2, [0 1])
-%!error <X and Y must have the same number> cov (5,[1 2])
-%!error <X and Y must have the same number> cov (ones (2, 2), ones (2, 2, 2))
-%!error <X and Y must have the same number> cov (ones (2, 2), ones (3, 2))
-%!error <X and Y must have the same number> cov (1, [])
-%!error <X and Y must have the same number> cov ([1, 2], ones(1, 0, 2))
-%!error <unknown NANFLAG parameter 'foo'> cov (1, "foo")
-%!error <unknown NANFLAG parameter 'foo'> cov (1, "foo")
-%!error <unknown NANFLAG parameter 'foo'> cov (1, 2, "foo")
-%!error <unknown NANFLAG parameter 'foo'> cov (1, 2, 0, "foo")
-%!error <unknown NANFLAG parameter ''> cov (1, 2, 1, [])
-%!error <NANFLAG parameter must be the last> cov (1, "includenan", 1)
-%!error <NANFLAG parameter must be the last> cov (1, 1, "includenan", 1)
+%!error cov ([1; 2], ["A", "B"])
+%!error cov (ones (2,2,2))
+%!error cov (ones (2,2), ones (2,2,2))
+%!error <normalization OPT must be 0 or 1> cov (1, 3)
+%!error cov (ones (2,2), ones (3,2))