Mercurial > octave
comparison scripts/statistics/base/median.m @ 21540:ffb4770ba079
Make median preserve discrete types (bug #47515).
* median.m: Replace mean by "native" sum (or max for logical), and
avoid assigning NaN to non-float types.
* data.cc (Fnth_element): Allow type bool, treated as an integer.
author | Lachlan Andrew <lachlanbis@gmail.com> |
---|---|
date | Thu, 24 Mar 2016 13:35:40 +1100 |
parents | a4faec57f4c8 |
children | ecce63c99c3f |
comparison
equal
deleted
inserted
replaced
21539:212bafe8413a | 21540:ffb4770ba079 |
---|---|
39 ## (x(N/2) + x((N/2)+1))/2 N even | 39 ## (x(N/2) + x((N/2)+1))/2 N even |
40 ## @end group | 40 ## @end group |
41 ## @end example | 41 ## @end example |
42 ## | 42 ## |
43 ## @end ifnottex | 43 ## @end ifnottex |
44 ## If @var{x} is of a discrete type such as integer or logical, then | |
45 ## the case of even N rounds up (or toward @qcode{true}). | |
46 ## | |
44 ## If @var{x} is a matrix, compute the median value for each column and | 47 ## If @var{x} is a matrix, compute the median value for each column and |
45 ## return them in a row vector. | 48 ## return them in a row vector. |
46 ## | 49 ## |
47 ## If the optional @var{dim} argument is given, operate along this dimension. | 50 ## If the optional @var{dim} argument is given, operate along this dimension. |
48 ## @seealso{mean, mode} | 51 ## @seealso{mean, mode} |
78 n = size (x, dim); | 81 n = size (x, dim); |
79 k = floor ((n+1) / 2); | 82 k = floor ((n+1) / 2); |
80 if (mod (n, 2) == 1) | 83 if (mod (n, 2) == 1) |
81 retval = nth_element (x, k, dim); | 84 retval = nth_element (x, k, dim); |
82 else | 85 else |
83 retval = mean (nth_element (x, k:k+1, dim), dim); | 86 retval = sum (nth_element (x, k:k+1, dim), dim, "native") / 2; |
87 if (islogical (x)) | |
88 retval = logical (retval); | |
89 endif | |
84 endif | 90 endif |
85 ## Inject NaNs where needed, to be consistent with Matlab. | 91 ## Inject NaNs where needed, to be consistent with Matlab. |
86 retval(any (isnan (x), dim)) = NaN; | 92 if (isfloat (x)) |
93 retval(any (isnan (x), dim)) = NaN; | |
94 endif | |
87 | 95 |
88 endfunction | 96 endfunction |
89 | 97 |
90 | 98 |
91 %!test | 99 %!test |
111 %! x = sort (a, 4); | 119 %! x = sort (a, 4); |
112 %! y = sort (b, 3); | 120 %! y = sort (b, 3); |
113 %!assert (median (a, 4), x(:, :, :, 3)) | 121 %!assert (median (a, 4), x(:, :, :, 3)) |
114 %!assert (median (b, 3), (y(:, :, 3, :) + y(:, :, 4, :))/2) | 122 %!assert (median (b, 3), (y(:, :, 3, :) + y(:, :, 4, :))/2) |
115 | 123 |
124 ## Test non-floating point types | |
125 %!assert (median ([true, false]), true); | |
126 %!assert (median (uint8 ([1, 3])), uint8 (2)); | |
127 %!assert (median (int8 ([1, 3, 4])), int8 (3)); | |
128 %!assert (median (single ([1, 3, 4])), single (3)); | |
129 %!assert (median (single ([1, 3, NaN])), single (NaN)); | |
130 | |
116 ## Test input validation | 131 ## Test input validation |
117 %!error median () | 132 %!error median () |
118 %!error median (1, 2, 3) | 133 %!error median (1, 2, 3) |
119 %!error <X must be a numeric> median ({1:5}) | 134 %!error <X must be a numeric> median ({1:5}) |
120 %!error <X cannot be an empty matrix> median ([]) | 135 %!error <X cannot be an empty matrix> median ([]) |