Mercurial > octave
changeset 31974:d33f168bdc92
median.m: Correct omitnan internal index orientation (bug #64011)
* scripts/statistics/median.m: Force all vector count and median element
indices in the omitnan codepath to be column vectors to avoid sub2ind
orientation errors. Add omitnan BISTs including both odd and even column
counts with 2D and 3D arrays.
author | Nicholas R. Jankowski <jankowski.nicholas@gmail.com> |
---|---|
date | Thu, 06 Apr 2023 18:28:57 -0400 |
parents | bc6fe3baf635 |
children | 72d005398818 |
files | scripts/statistics/median.m |
diffstat | 1 files changed, 21 insertions(+), 5 deletions(-) [+] |
line wrap: on
line diff
--- a/scripts/statistics/median.m Thu Apr 06 12:13:55 2023 -0700 +++ b/scripts/statistics/median.m Thu Apr 06 18:28:57 2023 -0400 @@ -333,7 +333,11 @@ endif else - n = sum (! isnan (x), 1); + ## Each column may have a different n and k. Force index column vector + ## for consistent orientation for 2D and nD inputs, then use sub2ind to + ## get correct element(s) for each column. + + n = sum (! isnan (x), 1)(:); k = floor ((n + 1) / 2); m_idx_odd = mod (n, 2) & n; m_idx_even = (! m_idx_odd) & n; @@ -345,12 +349,12 @@ endif ## Grab kth value, k possibly different for each column - if (any (m_idx_odd(:))) - x_idx_odd = sub2ind (szx, k(m_idx_odd)(:), find (m_idx_odd)); + if (any (m_idx_odd)) + x_idx_odd = sub2ind (szx, k(m_idx_odd), find (m_idx_odd)); m(m_idx_odd) = x(x_idx_odd); endif - if (any (m_idx_even(:))) - k_even = k(m_idx_even)(:); + if (any (m_idx_even)) + k_even = k(m_idx_even); x_idx_even = sub2ind (szx, [k_even, k_even + 1], ... (find (m_idx_even))(:, [1, 1])); m(m_idx_even) = sum (x(x_idx_even), 2) / 2; @@ -556,6 +560,7 @@ %!assert (median ([1 2 NaN 3]), NaN) %!assert (median ([1 2 NaN 3], "omitnan"), 2) %!assert (median ([1,2,NaN;4,5,6;NaN,8,9]), [NaN, 5, NaN]) +%!assert <*64011> (median ([1,2,NaN;4,5,6;NaN,8,9], "omitnan"), [2.5, 5, 7.5], eps) %!assert (median ([1 2 ; NaN 4]), [NaN 3]) %!assert (median ([1 2 ; NaN 4], "omitnan"), [1 3]) %!assert (median ([1 2 ; NaN 4], 1, "omitnan"), [1 3]) @@ -576,6 +581,17 @@ %!assert (median (single([NaN 2 ; NaN 4]), "omitnan"), single([NaN 3])) %!assert (median (single([NaN 2 ; NaN 4]), "omitnan", "double"), double([NaN 3])) +## Test omitnan with 2D & 3D inputs to confirm correct sub2ind orientation +%!test <*64011> +%! x = [magic(3), magic(3)]; +%! x([3, 7, 11, 12, 16, 17]) = NaN; +%! ynan = [NaN, 5, NaN, NaN, 5, NaN]; +%! yomitnan = [5.5, 5, 4.5, 8, 5, 2]; +%! assert (median (x), ynan); +%! assert (median (x, "omitnan"), yomitnan, eps); +%! assert (median (cat (3, x, x)), cat (3, ynan, ynan)); +%! assert (median (cat (3, x, x), "omitnan"), cat (3, yomitnan, yomitnan), eps); + %!assert (median (Inf), Inf) %!assert (median (-Inf), -Inf) %!assert (median ([-Inf Inf]), NaN)