time | Calls | line |
---|
| | 1 | function y = median(x,dim,flag)
|
| | 2 | %MEDIAN Median value.
|
| | 3 | % For vectors, MEDIAN(x) is the median value of the elements in x.
|
| | 4 | % For matrices, MEDIAN(X) is a row vector containing the median value
|
| | 5 | % of each column. For N-D arrays, MEDIAN(X) is the median value of the
|
| | 6 | % elements along the first non-singleton dimension of X.
|
| | 7 | %
|
| | 8 | % MEDIAN(X,'all') is the median of all elements of X.
|
| | 9 | %
|
| | 10 | % MEDIAN(X,DIM) takes the median along the dimension DIM of X.
|
| | 11 | %
|
| | 12 | % MEDIAN(X,VECDIM) operates on the dimensions specified in the vector
|
| | 13 | % VECDIM. For example, MEDIAN(X,[1 2]) operates on the elements contained
|
| | 14 | % in the first and second dimensions of X.
|
| | 15 | %
|
| | 16 | % MEDIAN(...,NANFLAG) specifies how NaN (Not-A-Number) values
|
| | 17 | % are treated. The default is 'includenan':
|
| | 18 | %
|
| | 19 | % 'includenan' - the median of a vector containing NaN values is also NaN.
|
| | 20 | % 'omitnan' - the median of a vector containing NaN values is the
|
| | 21 | % median of all its non-NaN elements. If all elements
|
| | 22 | % are NaN, the result is NaN.
|
| | 23 | %
|
| | 24 | % Example:
|
| | 25 | % X = [1 2 4 4; 3 4 6 6; 5 6 8 8; 5 6 8 8]
|
| | 26 | % median(X,1)
|
| | 27 | % median(X,2)
|
| | 28 | %
|
| | 29 | % Class support for input X:
|
| | 30 | % float: double, single
|
| | 31 | % integer: uint8, int8, uint16, int16, uint32, int32, uint64, int64
|
| | 32 | %
|
| | 33 | % See also MEAN, STD, MIN, MAX, VAR, COV, MODE.
|
| | 34 |
|
| | 35 | % Copyright 1984-2018 The MathWorks, Inc.
|
| | 36 |
|
< 0.001 | 2 | 37 | if isstring(x)
|
| | 38 | error(message('MATLAB:median:wrongInput'));
|
< 0.001 | 2 | 39 | end
|
| | 40 |
|
< 0.001 | 2 | 41 | if isempty(x) % Not checking nanflag in this case
|
| | 42 | if nargin == 1 || (nargin >= 2 && (ischar(dim) || isstring(dim)))
|
| | 43 |
|
| | 44 | % The output size for [] is a special case when DIM is not given.
|
| | 45 | if isequal(x,[])
|
| | 46 | if isinteger(x) || islogical(x)
|
| | 47 | y = zeros('like',x);
|
| | 48 | else
|
| | 49 | y = nan('like',x);
|
| | 50 | end
|
| | 51 | return;
|
| | 52 | end
|
| | 53 |
|
| | 54 | if nargin == 2 && isAllFlag(dim)
|
| | 55 | dim = 1:ndims(x);
|
| | 56 | else
|
| | 57 | % Determine first nonsingleton dimension
|
| | 58 | dim = find(size(x)~=1,1);
|
| | 59 | end
|
| | 60 |
|
| | 61 | end
|
| | 62 |
|
| | 63 | s = size(x);
|
| | 64 | if max(dim)>length(s)
|
| | 65 | s(end+1:max(dim)) = 1;
|
| | 66 | end
|
| | 67 | s(dim) = 1; % Set size to 1 along dimensions
|
| | 68 | if isinteger(x) || islogical(x)
|
| | 69 | y = zeros(s,'like',x);
|
| | 70 | else
|
| | 71 | y = nan(s,'like',x);
|
| | 72 | end
|
| | 73 |
|
| | 74 | return;
|
< 0.001 | 2 | 75 | end
|
| | 76 |
|
< 0.001 | 2 | 77 | omitnan = false;
|
< 0.001 | 2 | 78 | dimSet = true;
|
< 0.001 | 2 | 79 | if nargin == 1
|
< 0.001 | 2 | 80 | dimSet = false;
|
| | 81 | elseif nargin == 2
|
| | 82 | dimSet = (~ischar(dim) && ~(isstring(dim) && isscalar(dim))) || isAllFlag(dim);
|
| | 83 | if ~dimSet
|
| | 84 | flag = dim;
|
| | 85 | end
|
< 0.001 | 2 | 86 | end
|
| | 87 |
|
< 0.001 | 2 | 88 | sz = size(x);
|
< 0.001 | 2 | 89 | if dimSet
|
| | 90 | if isnumeric(dim) || islogical(dim)
|
| | 91 | if isempty(dim) || ~isvector(dim)
|
| | 92 | error(message('MATLAB:getdimarg:invalidDim'));
|
| | 93 | else
|
| | 94 | if ~isreal(dim) || any(floor(dim) ~= ceil(dim)) || any(dim < 1) || any(~isfinite(dim))
|
| | 95 | error(message('MATLAB:getdimarg:invalidDim'));
|
| | 96 | end
|
| | 97 | if ~isscalar(dim) && ~all(diff(sort(dim)))
|
| | 98 | error(message('MATLAB:getdimarg:vecDimsMustBeUniquePositiveIntegers'));
|
| | 99 | end
|
| | 100 | end
|
| | 101 | dim = reshape(dim, 1, []);
|
| | 102 | elseif isAllFlag(dim)
|
| | 103 | x = x(:);
|
| | 104 | dim = 1;
|
| | 105 | sz = size(x);
|
| | 106 | else
|
| | 107 | error(message('MATLAB:getdimarg:invalidDim'));
|
| | 108 | end
|
| | 109 |
|
| | 110 | if all(dim > numel(sz))
|
| | 111 | y = x;
|
| | 112 | return;
|
| | 113 | end
|
< 0.001 | 2 | 114 | end
|
| | 115 |
|
< 0.001 | 2 | 116 | if nargin == 2 && dimSet == false || nargin == 3
|
| | 117 | if isstring(flag)
|
| | 118 | flag = char(flag);
|
| | 119 | end
|
| | 120 | len = max(length(flag), 1);
|
| | 121 |
|
| | 122 | if ~isrow(flag)
|
| | 123 | if nargin == 2
|
| | 124 | error(message('MATLAB:median:unknownOption'));
|
| | 125 | else
|
| | 126 | error(message('MATLAB:median:unknownFlag'));
|
| | 127 | end
|
| | 128 | end
|
| | 129 |
|
| | 130 | s = strncmpi(flag, {'omitnan', 'includenan'}, len);
|
| | 131 |
|
| | 132 | if ~any(s)
|
| | 133 | if nargin == 2
|
| | 134 | error(message('MATLAB:median:unknownOption'));
|
| | 135 | else
|
| | 136 | error(message('MATLAB:median:unknownFlag'));
|
| | 137 | end
|
| | 138 | end
|
| | 139 |
|
| | 140 | omitnan = s(1);
|
< 0.001 | 2 | 141 | end
|
| | 142 |
|
< 0.001 | 2 | 143 | if isvector(x) && (~dimSet || (isscalar(dim) && sz(dim) > 1))
|
| | 144 | % If input is a vector, calculate single value of output.
|
< 0.001 | 2 | 145 | if isreal(x) && ~issparse(x) && isnumeric(x) && ~isobject(x) % Utilize internal fast median
|
< 0.001 | 2 | 146 | if isrow(x)
|
| | 147 | x = x.';
|
| 2 | 148 | end
|
< 0.001 | 2 | 149 | y = matlab.internal.math.columnmedian(x,omitnan);
|
| | 150 | else
|
| | 151 | x = sort(x);
|
| | 152 | nCompare = length(x);
|
| | 153 | if isnan(x(nCompare)) % Check last index for NaN
|
| | 154 | if omitnan
|
| | 155 | nCompare = find(~isnan(x), 1, 'last');
|
| | 156 | if isempty(nCompare)
|
| | 157 | y = nan('like',x([])); % using x([]) so that y is always real
|
| | 158 | return;
|
| | 159 | end
|
| | 160 | else
|
| | 161 | y = nan('like',x([])); % using x([]) so that y is always real
|
| | 162 | return;
|
| | 163 | end
|
| | 164 | end
|
| | 165 | half = floor(nCompare/2);
|
| | 166 | y = x(half+1);
|
| | 167 | if 2*half == nCompare % Average if even number of elements
|
| | 168 | y = meanof(x(half),y);
|
| | 169 | end
|
< 0.001 | 2 | 170 | end
|
| | 171 | else
|
| | 172 | if ~dimSet % Determine first nonsingleton dimension
|
| | 173 | dim = find(sz ~= 1,1);
|
| | 174 | else
|
| | 175 | dim = min(dim, ndims(x)+1);
|
| | 176 | sz(end+1:max(dim)) = 1;
|
| | 177 | end
|
| | 178 |
|
| | 179 | sizey = sz;
|
| | 180 | sizey(dim) = 1;
|
| | 181 |
|
| | 182 | % Reshape and permute x into a matrix of size prod(sz(dim)) x (numel(x) / prod(sz(dim)))
|
| | 183 | tf = false(size(sizey));
|
| | 184 | tf(dim) = true;
|
| | 185 | perm = [find(tf), find(~tf)];
|
| | 186 | x = permute(x, perm);
|
| | 187 | x = reshape(x, [prod(sz(dim)), prod(sizey)]);
|
| | 188 |
|
| | 189 | if isreal(x) && ~issparse(x) && isnumeric(x) && ~isobject(x) % Utilize internal fast median
|
| | 190 | y = matlab.internal.math.columnmedian(x,omitnan);
|
| | 191 | else
|
| | 192 | % Sort along columns
|
| | 193 | x = sort(x, 1);
|
| | 194 | if ~omitnan || all(~isnan(x(end, :)))
|
| | 195 | % Use vectorized method with column indexing. Reshape at end to
|
| | 196 | % appropriate dimension.
|
| | 197 | nCompare = size(x,1); % Number of elements used to generate a median
|
| | 198 | half = floor(nCompare/2); % Midway point, used for median calculation
|
| | 199 |
|
| | 200 | y = x(half+1,:);
|
| | 201 | if 2*half == nCompare
|
| | 202 | y = meanof(x(half,:),y);
|
| | 203 | end
|
| | 204 |
|
| | 205 | if isfloat(x)
|
| | 206 | y(isnan(x(nCompare,:))) = NaN; % Check last index for NaN
|
| | 207 | end
|
| | 208 | else
|
| | 209 | % Get median of the non-NaN values in each column.
|
| | 210 | y = nan(1, size(x, 2), 'like', x([])); % using x([]) so that y is always real
|
| | 211 |
|
| | 212 | % Number of non-NaN values in each column
|
| | 213 | n = sum(~isnan(x), 1);
|
| | 214 |
|
| | 215 | % Deal with all columns that have an odd number of valid values
|
| | 216 | oddCols = find((n>0) & rem(n,2)==1);
|
| | 217 | oddIdxs = sub2ind(size(x), (n(oddCols)+1)/2, oddCols);
|
| | 218 | y(oddCols) = x(oddIdxs);
|
| | 219 |
|
| | 220 | % Deal with all columns that have an even number of valid values
|
| | 221 | evenCols = find((n>0) & rem(n,2)==0);
|
| | 222 | evenIdxs = sub2ind(size(x), n(evenCols)/2, evenCols);
|
| | 223 | y(evenCols) = meanof( x(evenIdxs), x(evenIdxs+1) );
|
| | 224 | end
|
| | 225 | end
|
| | 226 | % Reshape and permute back
|
| | 227 | y = reshape(y, sizey);
|
< 0.001 | 2 | 228 | end
|
Other subfunctions in this file are not included in this listing.