Mercurial > octave
changeset 31379:84fa33608593
normalize.m: Use bsxfun rather than broadcasting (bug #55765)
* normalize.m: Replace broadcasting with bsxfun for in "range" option and
primary calculation. Add FIXME note that it can revert to broadcasting when
sparse and diagonal matrix types no longer produce errors. Add BISTs for
sparse and diagonal input handling and xtests for preserving sparseness.
author | Nicholas R. Jankowski <jankowski.nicholas@gmail.com> |
---|---|
date | Mon, 31 Oct 2022 16:25:46 -0400 |
parents | 8dc9508b8364 |
children | 980059c3b129 |
files | scripts/statistics/normalize.m |
diffstat | 1 files changed, 36 insertions(+), 2 deletions(-) [+] |
line wrap: on
line diff
--- a/scripts/statistics/normalize.m Mon Oct 31 19:27:17 2022 +0100 +++ b/scripts/statistics/normalize.m Mon Oct 31 16:25:46 2022 -0400 @@ -389,7 +389,10 @@ case "robust" ## center/median to zero and MAD = 1 c = median (x, dim); - s = median (abs (x - c), dim); + ## FIXME: Use bsxfun, rather than broadcasting, until broadcasting + ## supports diagonal and sparse matrices (Bugs #41441, #35787). + s = median (abs (bsxfun (@minus, x , c)), dim); + ## s = median (abs (x - c), dim); # Automatic broadcasting endswitch case "norm" @@ -444,7 +447,11 @@ endif ## Divide by scale factor. If scale = 0, divide by zero = Inf, which is OK. - z = (x - c) ./ s; + + ## FIXME: Use bsxfun, rather than broadcasting, until broadcasting + ## supports diagonal and sparse matrices (Bugs #41441, #35787). + z = bsxfun (@rdivide, bsxfun (@minus, x , c), s); + ## z = (x - c) ./ s; # Automatic broadcasting endfunction @@ -610,6 +617,33 @@ %! [z, c, s] = normalize (Inf); %! assert ({z, c, s}, {NaN, Inf, NaN}); +## Test sparse and diagonal inputs +%!test +%! [z, c, s] = normalize (eye (2)); +%! assert (z, (sqrt(2)/2)*[1, -1; -1, 1], eps); +%! assert (c, [0.5, 0.5], eps); +%! assert (s, (sqrt(2)/2)*[1, 1], eps); +%!test +%! [z, c, s] = normalize (sparse (eye (2))); +%! assert (full (z), (sqrt(2)/2)*[1, -1; -1, 1], eps); +%! assert (full (c), [0.5, 0.5], eps); +%! assert (full (s), (sqrt(2)/2)*[1, 1], eps); +%!test +%! [z, c, s] = normalize (sparse (magic (3)), "zscore", "robust"); +%! assert (full (z), [4 -1 0; -1 0 1; 0 1 -4], eps); +%! assert (full (c), [4, 5, 6], eps); +%! assert (full (s), [1, 4, 1], eps); +%!test <55765> +%! [z, c, s] = normalize (sparse (eye(2))); +%! assert (issparse (z)); +%! assert (issparse (c)); +%! assert (issparse (s)); +%!test <55765> +%! [z, c, s] = normalize (sparse (magic (3)), "zscore", "robust"); +%! assert (issparse (z)); +%! assert (issparse (c)); +%! assert (issparse (s)); + ## Matlab ignores NaNs, operating as if the vector had one less element, then ## returns the result retaining the NaN in the solution. %!assert <50571> (normalize ([1 2 NaN], 2), [-1, 1, NaN]*sqrt(2)/2)