Mercurial > octave
comparison scripts/statistics/normalize.m @ 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 | d727bda73574 |
children | fd29c7a50a78 |
comparison
equal
deleted
inserted
replaced
31378:8dc9508b8364 | 31379:84fa33608593 |
---|---|
387 case "std" | 387 case "std" |
388 [s, c] = std (x, [], dim); | 388 [s, c] = std (x, [], dim); |
389 case "robust" | 389 case "robust" |
390 ## center/median to zero and MAD = 1 | 390 ## center/median to zero and MAD = 1 |
391 c = median (x, dim); | 391 c = median (x, dim); |
392 s = median (abs (x - c), dim); | 392 ## FIXME: Use bsxfun, rather than broadcasting, until broadcasting |
393 ## supports diagonal and sparse matrices (Bugs #41441, #35787). | |
394 s = median (abs (bsxfun (@minus, x , c)), dim); | |
395 ## s = median (abs (x - c), dim); # Automatic broadcasting | |
393 endswitch | 396 endswitch |
394 | 397 |
395 case "norm" | 398 case "norm" |
396 switch (methodoption) | 399 switch (methodoption) |
397 case 1 | 400 case 1 |
442 endswitch | 445 endswitch |
443 | 446 |
444 endif | 447 endif |
445 | 448 |
446 ## Divide by scale factor. If scale = 0, divide by zero = Inf, which is OK. | 449 ## Divide by scale factor. If scale = 0, divide by zero = Inf, which is OK. |
447 z = (x - c) ./ s; | 450 |
451 ## FIXME: Use bsxfun, rather than broadcasting, until broadcasting | |
452 ## supports diagonal and sparse matrices (Bugs #41441, #35787). | |
453 z = bsxfun (@rdivide, bsxfun (@minus, x , c), s); | |
454 ## z = (x - c) ./ s; # Automatic broadcasting | |
448 | 455 |
449 endfunction | 456 endfunction |
450 | 457 |
451 function c = process_center_option (x, dim, center_option) | 458 function c = process_center_option (x, dim, center_option) |
452 | 459 |
608 %! [z, c, s] = normalize ([1 2 Inf], 2); | 615 %! [z, c, s] = normalize ([1 2 Inf], 2); |
609 %! assert ({z, c, s}, {[NaN, NaN, NaN], Inf, NaN}); | 616 %! assert ({z, c, s}, {[NaN, NaN, NaN], Inf, NaN}); |
610 %! [z, c, s] = normalize (Inf); | 617 %! [z, c, s] = normalize (Inf); |
611 %! assert ({z, c, s}, {NaN, Inf, NaN}); | 618 %! assert ({z, c, s}, {NaN, Inf, NaN}); |
612 | 619 |
620 ## Test sparse and diagonal inputs | |
621 %!test | |
622 %! [z, c, s] = normalize (eye (2)); | |
623 %! assert (z, (sqrt(2)/2)*[1, -1; -1, 1], eps); | |
624 %! assert (c, [0.5, 0.5], eps); | |
625 %! assert (s, (sqrt(2)/2)*[1, 1], eps); | |
626 %!test | |
627 %! [z, c, s] = normalize (sparse (eye (2))); | |
628 %! assert (full (z), (sqrt(2)/2)*[1, -1; -1, 1], eps); | |
629 %! assert (full (c), [0.5, 0.5], eps); | |
630 %! assert (full (s), (sqrt(2)/2)*[1, 1], eps); | |
631 %!test | |
632 %! [z, c, s] = normalize (sparse (magic (3)), "zscore", "robust"); | |
633 %! assert (full (z), [4 -1 0; -1 0 1; 0 1 -4], eps); | |
634 %! assert (full (c), [4, 5, 6], eps); | |
635 %! assert (full (s), [1, 4, 1], eps); | |
636 %!test <55765> | |
637 %! [z, c, s] = normalize (sparse (eye(2))); | |
638 %! assert (issparse (z)); | |
639 %! assert (issparse (c)); | |
640 %! assert (issparse (s)); | |
641 %!test <55765> | |
642 %! [z, c, s] = normalize (sparse (magic (3)), "zscore", "robust"); | |
643 %! assert (issparse (z)); | |
644 %! assert (issparse (c)); | |
645 %! assert (issparse (s)); | |
646 | |
613 ## Matlab ignores NaNs, operating as if the vector had one less element, then | 647 ## Matlab ignores NaNs, operating as if the vector had one less element, then |
614 ## returns the result retaining the NaN in the solution. | 648 ## returns the result retaining the NaN in the solution. |
615 %!assert <50571> (normalize ([1 2 NaN], 2), [-1, 1, NaN]*sqrt(2)/2) | 649 %!assert <50571> (normalize ([1 2 NaN], 2), [-1, 1, NaN]*sqrt(2)/2) |
616 %!assert <50571> (normalize ([1 2 NaN; 1 2 3], 2), [[-1 1 NaN]*sqrt(2)/2; -1 0 1], eps) | 650 %!assert <50571> (normalize ([1 2 NaN; 1 2 3], 2), [[-1 1 NaN]*sqrt(2)/2; -1 0 1], eps) |
617 | 651 |