Mercurial > octave
changeset 21309:7fbecef105ca
Allow statistics functions to work over non-existent dimension (bug #33523).
* var.m, center.m, kurtosis.m, mean.m, meansq.m, median.m, moment.m,
skewness.m, std.m: Remove check for input dimension being within the range
of ndims (x). Add BIST tests for new behavior and update input validation
tests.
author | Rik <rik@octave.org> |
---|---|
date | Fri, 19 Feb 2016 21:27:03 -0800 |
parents | c53bfd6d8e08 |
children | fc6a9bd59094 |
files | scripts/statistics/base/center.m scripts/statistics/base/kurtosis.m scripts/statistics/base/mean.m scripts/statistics/base/meansq.m scripts/statistics/base/median.m scripts/statistics/base/moment.m scripts/statistics/base/skewness.m scripts/statistics/base/std.m scripts/statistics/base/var.m |
diffstat | 9 files changed, 71 insertions(+), 68 deletions(-) [+] |
line wrap: on
line diff
--- a/scripts/statistics/base/center.m Fri Feb 19 09:40:59 2016 -0800 +++ b/scripts/statistics/base/center.m Fri Feb 19 21:27:03 2016 -0800 @@ -59,13 +59,12 @@ ## Find the first non-singleton dimension. (dim = find (sz > 1, 1)) || (dim = 1); else - if (!(isscalar (dim) && dim == fix (dim)) - || !(1 <= dim && dim <= nd)) + if (! (isscalar (dim) && dim == fix (dim) && dim > 0)) error ("center: DIM must be an integer and a valid dimension"); endif endif - n = sz(dim); + n = size (x, dim); if (n == 0) retval = x; @@ -84,12 +83,12 @@ %!assert (center (ones (3,2,0,2, "single")), zeros (3,2,0,2, "single")) %!assert (center (magic (3)), [3,-4,1;-2,0,2;-1,4,-3]) %!assert (center ([1 2 3; 6 5 4], 2), [-1 0 1; 1 0 -1]) +%!assert (center (1, 3), 0) ## Test input validation %!error center () %!error center (1, 2, 3) -%!error center (1, ones (2,2)) -%!error center (1, 1.5) -%!error center (1, 0) -%!error center (1, 3) +%!error <DIM must be an integer> center (1, ones (2,2)) +%!error <DIM must be an integer> center (1, 1.5) +%!error <DIM must be .* a valid dimension> center (1, 0)
--- a/scripts/statistics/base/kurtosis.m Fri Feb 19 09:40:59 2016 -0800 +++ b/scripts/statistics/base/kurtosis.m Fri Feb 19 21:27:03 2016 -0800 @@ -105,12 +105,12 @@ ## Find the first non-singleton dimension. (dim = find (sz > 1, 1)) || (dim = 1); else - if (! (isscalar (dim) && dim == fix (dim)) || ! (1 <= dim && dim <= nd)) + if (! (isscalar (dim) && dim == fix (dim) && dim > 0)) error ("kurtosis: DIM must be an integer and a valid dimension"); endif endif - n = sz(dim); + n = size (x, dim); sz(dim) = 1; x = center (x, dim); # center also promotes integer, logical to double @@ -140,6 +140,7 @@ %!assert (kurtosis ([-3, 0, 1]) == kurtosis ([-1, 0, 3])) %!assert (kurtosis (ones (3, 5)), NaN (1, 5)) +%!assert (kurtosis (1, [], 3), NaN) %!assert (kurtosis ([1:5 10; 1:5 10], 0, 2), 5.4377317925288901 * [1; 1], 8 * eps) %!assert (kurtosis ([1:5 10; 1:5 10], 1, 2), 2.9786509002956195 * [1; 1], 8 * eps) @@ -165,5 +166,4 @@ %!error <DIM must be an integer> kurtosis (1, [], ones (2,2)) %!error <DIM must be an integer> kurtosis (1, [], 1.5) %!error <DIM must be .* a valid dimension> kurtosis (1, [], 0) -%!error <DIM must be .* a valid dimension> kurtosis (1, [], 3)
--- a/scripts/statistics/base/mean.m Fri Feb 19 09:40:59 2016 -0800 +++ b/scripts/statistics/base/mean.m Fri Feb 19 21:27:03 2016 -0800 @@ -105,13 +105,12 @@ ## Find the first non-singleton dimension. (dim = find (sz > 1, 1)) || (dim = 1); else - if (!(isscalar (dim) && dim == fix (dim)) - || !(1 <= dim && dim <= nd)) + if (! (isscalar (dim) && dim == fix (dim) && dim > 0)) error ("mean: DIM must be an integer and a valid dimension"); endif endif - n = sz(dim); + n = size (x, dim); if (strcmp (opt, "a")) y = sum (x, dim) / n; @@ -147,15 +146,16 @@ %!assert (mean ([4 4 2], "h"), 3) %!assert (mean (logical ([1 0 1 1])), 0.75) %!assert (mean (single ([1 0 1 1])), single (0.75)) +%!assert (mean ([1 2], 3), [1 2]) ## Test input validation %!error mean () %!error mean (1, 2, 3, 4) -%!error mean ({1:5}) -%!error mean (1, 2, 3) -%!error mean (1, ones (2,2)) -%!error mean (1, 1.5) -%!error mean (1, 0) -%!error mean (1, 3) -%!error mean (1, "b") +%!error <X must be a numeric> mean ({1:5}) +%!error <OPT must be a string> mean (1, 2, 3) +%!error <DIM must be an integer> mean (1, ones (2,2)) +%!error <DIM must be an integer> mean (1, 1.5) +%!error <DIM must be .* a valid dimension> mean (1, 0) +%!error <X must not contain any negative values> mean ([1 -1], "g") +%!error <option 'b' not recognized> mean (1, "b")
--- a/scripts/statistics/base/meansq.m Fri Feb 19 09:40:59 2016 -0800 +++ b/scripts/statistics/base/meansq.m Fri Feb 19 21:27:03 2016 -0800 @@ -64,13 +64,12 @@ ## Find the first non-singleton dimension. (dim = find (sz > 1, 1)) || (dim = 1); else - if (!(isscalar (dim) && dim == fix (dim)) - || !(1 <= dim && dim <= nd)) + if (! (isscalar (dim) && dim == fix (dim) && dim > 0)) error ("mean: DIM must be an integer and a valid dimension"); endif endif - y = sumsq (x, dim) / sz(dim); + y = sumsq (x, dim) / size (x, dim); endfunction @@ -79,13 +78,13 @@ %!assert (meansq (single (1:5)), single (11)) %!assert (meansq (magic (4)), [94.5, 92.5, 92.5, 94.5]) %!assert (meansq (magic (4), 2), [109.5; 77.5; 77.5; 109.5]) +%!assert (meansq ([1 2], 3), [1 4]) ## Test input validation %!error meansq () %!error meansq (1, 2, 3) -%!error meansq (['A'; 'B']) -%!error meansq (1, ones (2,2)) -%!error meansq (1, 1.5) -%!error meansq (1, 0) -%!error meansq (1, 3) +%!error <X must be a numeric> meansq (['A'; 'B']) +%!error <DIM must be an integer> meansq (1, ones (2,2)) +%!error <DIM must be an integer> meansq (1, 1.5) +%!error <DIM must be .* a valid dimension> meansq (1, 0)
--- a/scripts/statistics/base/median.m Fri Feb 19 09:40:59 2016 -0800 +++ b/scripts/statistics/base/median.m Fri Feb 19 21:27:03 2016 -0800 @@ -70,13 +70,12 @@ ## Find the first non-singleton dimension. (dim = find (sz > 1, 1)) || (dim = 1); else - if (!(isscalar (dim) && dim == fix (dim)) - || !(1 <= dim && dim <= nd)) + if (! (isscalar (dim) && dim == fix (dim) && dim > 0)) error ("median: DIM must be an integer and a valid dimension"); endif endif - n = sz(dim); + n = size (x, dim); k = floor ((n+1) / 2); if (mod (n, 2) == 1) retval = nth_element (x, k, dim); @@ -102,6 +101,7 @@ %!assert (median (single ([1,2,3])), single (2)) %!assert (median ([1,2,NaN;4,5,6;NaN,8,9]), [NaN, 5, NaN]) +%!assert (median ([1,2], 3), [1,2]) ## Test multidimensional arrays (bug #35679) %!shared a, b, x, y @@ -116,9 +116,9 @@ ## Test input validation %!error median () %!error median (1, 2, 3) -%!error median ({1:5}) -%!error median (['A'; 'B']) -%!error median (1, ones (2,2)) -%!error median (1, 1.5) -%!error median (1, 0) +%!error <X must be a numeric> median ({1:5}) +%!error <X cannot be an empty matrix> median ([]) +%!error <DIM must be an integer> median (1, ones (2,2)) +%!error <DIM must be an integer> median (1, 1.5) +%!error <DIM must be .* a valid dimension> median (1, 0)
--- a/scripts/statistics/base/moment.m Fri Feb 19 09:40:59 2016 -0800 +++ b/scripts/statistics/base/moment.m Fri Feb 19 21:27:03 2016 -0800 @@ -161,12 +161,12 @@ ## Find the first non-singleton dimension. (dim = find (sz > 1, 1)) || (dim = 1); else - if (! (isscalar (dim) && dim == fix (dim)) || ! (1 <= dim && dim <= nd)) + if (! (isscalar (dim) && dim == fix (dim) && dim > 0)) error ("moment: DIM must be an integer and a valid dimension"); endif endif - n = sz(dim); + n = size (x, dim); if (! any (type == "r")) x = center (x, dim); @@ -191,6 +191,8 @@ %!assert (moment (single ([1 2 3]), 1, "r"), single (2)) +%!assert (moment (1, 2, 4), 0) + ## Test input validation %!error moment () %!error moment (1) @@ -202,5 +204,4 @@ %!error <TYPE must be a string> moment (1, 2, 3, 4) %!error <DIM must be an integer and a valid dimension> moment (1, 2, ones (2,2)) %!error <DIM must be an integer and a valid dimension> moment (1, 2, 1.5) -%!error <DIM must be an integer and a valid dimension> moment (1, 2, 4)
--- a/scripts/statistics/base/skewness.m Fri Feb 19 09:40:59 2016 -0800 +++ b/scripts/statistics/base/skewness.m Fri Feb 19 21:27:03 2016 -0800 @@ -92,10 +92,8 @@ if (nargin < 2 || isempty (flag)) flag = 1; # default: do not use the "bias corrected" version - else - if (! isscalar (flag) || (flag != 0 && flag != 1)) - error ("skewness: FLAG must be 0 or 1"); - endif + elseif (! isscalar (flag) || (flag != 0 && flag != 1)) + error ("skewness: FLAG must be 0 or 1"); endif nd = ndims (x); @@ -104,12 +102,12 @@ ## Find the first non-singleton dimension. (dim = find (sz > 1, 1)) || (dim = 1); else - if (!(isscalar (dim) && dim == fix (dim)) || !(1 <= dim && dim <= nd)) + if (! (isscalar (dim) && dim == fix (dim) && dim > 0)) error ("skewness: DIM must be an integer and a valid dimension"); endif endif - n = sz(dim); + n = size (x, dim); sz(dim) = 1; x = center (x, dim); # center also promotes integer, logical to double @@ -136,6 +134,7 @@ %!assert (skewness ([-1, 0, 2]) > 0) %!assert (skewness ([-3, 0, 1]) == -1 * skewness ([-1, 0, 3])) %!assert (skewness (ones (3, 5)), NaN (1, 5)) +%!assert (skewness (1, [], 3), NaN) %!test %! x = [0; 0; 0; 1]; @@ -166,5 +165,4 @@ %!error <DIM must be an integer> skewness (1, [], ones (2,2)) %!error <DIM must be an integer> skewness (1, [], 1.5) %!error <DIM must be .* a valid dimension> skewness (1, [], 0) -%!error <DIM must be .* a valid dimension> skewness (1, [], 3)
--- a/scripts/statistics/base/std.m Fri Feb 19 09:40:59 2016 -0800 +++ b/scripts/statistics/base/std.m Fri Feb 19 21:27:03 2016 -0800 @@ -75,8 +75,7 @@ if (isempty (opt)) opt = 0; - endif - if (opt != 0 && opt != 1) + elseif (! isscalar (opt) || (opt != 0 && opt != 1)) error ("std: normalization OPT must be 0 or 1"); endif @@ -86,13 +85,12 @@ ## Find the first non-singleton dimension. (dim = find (sz > 1, 1)) || (dim = 1); else - if (!(isscalar (dim) && dim == fix (dim)) - || !(1 <= dim && dim <= nd)) + if (! (isscalar (dim) && dim == fix (dim) && dim > 0)) error ("std: DIM must be an integer and a valid dimension"); endif endif - n = sz(dim); + n = size (x, dim); if (n == 1 || isempty (x)) if (isa (x, "single")) retval = zeros (sz, "single"); @@ -113,17 +111,21 @@ %! assert (std (y), sqrt (2), sqrt (eps)); %! assert (std (x, 0, 2), zeros (10, 1)); -%!assert (std (ones (3, 1, 2), 0, 2), zeros (3, 1, 2)); -%!assert (std ([1 2], 0), sqrt (2)/2, 5*eps); -%!assert (std ([1 2], 1), 0.5, 5*eps); -%!assert (std (1), 0); -%!assert (std (single (1)), single (0)); -%!assert (std ([]), []); -%!assert (std (ones (1,3,0,2)), ones (1,3,0,2)); +%!assert (std (ones (3, 1, 2), 0, 2), zeros (3, 1, 2)) +%!assert (std ([1 2], 0), sqrt (2)/2, 5*eps) +%!assert (std ([1 2], 1), 0.5, 5*eps) +%!assert (std (1), 0) +%!assert (std (single (1)), single (0)) +%!assert (std ([]), []) +%!assert (std (ones (1,3,0,2)), ones (1,3,0,2)) +%!assert (std ([1 2 3], [], 3), [0 0 0]) ## Test input validation %!error std () %!error std (1, 2, 3, 4) -%!error std (['A'; 'B']) -%!error std (1, -1) +%!error <X must be a numeric> std (['A'; 'B']) +%!error <OPT must be 0 or 1> std (1, 2) +%!error <DIM must be an integer> std (1, [], ones (2,2)) +%!error <DIM must be an integer> std (1, [], 1.5) +%!error <DIM must be .* a valid dimension> std (1, [], 0)
--- a/scripts/statistics/base/var.m Fri Feb 19 09:40:59 2016 -0800 +++ b/scripts/statistics/base/var.m Fri Feb 19 21:27:03 2016 -0800 @@ -75,8 +75,7 @@ if (isempty (opt)) opt = 0; - endif - if (opt != 0 && opt != 1) + elseif (opt != 0 && opt != 1) error ("var: normalization OPT must be 0 or 1"); endif @@ -86,13 +85,12 @@ ## Find the first non-singleton dimension. (dim = find (sz > 1, 1)) || (dim = 1); else - if (!(isscalar (dim) && dim == fix (dim)) - || !(1 <= dim && dim <= nd)) + if (! (isscalar (dim) && dim == fix (dim) && dim > 0)) error ("var: DIM must be an integer and a valid dimension"); endif endif - n = sz(dim); + n = size (x, dim); if (n == 1) if (isa (x, "single")) retval = zeros (sz, "single"); @@ -113,11 +111,17 @@ %!assert (var ([1,2,3]), 1) %!assert (var ([1,2,3], 1), 2/3, eps) %!assert (var ([1,2,3], [], 1), [0,0,0]) +%!assert (var ([1,2,3], [], 3), [0,0,0]) ## Test input validation %!error var () %!error var (1,2,3,4) -%!error var (['A'; 'B']) -%!error var (1, -1) -%!error var ([], 1) +%!error <X must be a numeric> var (['A'; 'B']) +%!error <OPT must be 0 or 1> var (1, -1) +%!error <FLAG must be 0 or 1> skewness (1, 2) +%!error <FLAG must be 0 or 1> skewness (1, [1 0]) +%!error <DIM must be an integer> var (1, [], ones (2,2)) +%!error <DIM must be an integer> var (1, [], 1.5) +%!error <DIM must be .* a valid dimension> var (1, [], 0) +%!error <X must not be empty> var ([], 1)