Mercurial > octave-nkf
diff scripts/statistics/base/mode.m @ 6863:3c64128e621c
[project @ 2007-09-05 07:52:48 by dbateman]
author | dbateman |
---|---|
date | Wed, 05 Sep 2007 07:53:45 +0000 |
parents | |
children | 6304d9ea0a30 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/scripts/statistics/base/mode.m Wed Sep 05 07:53:45 2007 +0000 @@ -0,0 +1,111 @@ +## Copyright (C) 2007 David Bateman +## +## This file is part of Octave. +## +## Octave is free software; you can redistribute it and/or modify it +## under the terms of the GNU General Public License as published by +## the Free Software Foundation; either version 2, or (at your option) +## any later version. +## +## Octave is distributed in the hope that it will be useful, but +## WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +## General Public License for more details. +## +## You should have received a copy of the GNU General Public License +## along with Octave; see the file COPYING. If not, write to the Free +## Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +## 02110-1301, USA. + +## -*- texinfo -*- +## @deftypefn {Function File} {[@var{m}, @var{f}, @var{c}] =} mode (@var{x}, @var{dim}) +## Count the most frequently appearing value. @code{mode} counts the +## frequency along the first non-singleton dimension and if two or more +## values have te same frequency returns the smallest of the two in +## @var{m}. The dimension along which to count can be specified by the +## @var{dim} parameter. +## +## The variable @var{f} counts the frequency of each of the most frequently +## occuring ellements. The cell array @var{c} contains all of the elements +## with the maximum frequency . +## @end deftypefn + +function [m, f, c] = mode (x, dim) + + if (nargin < 1 || nargin > 2) + print_usage (); + endif + + nd = ndims (x); + sz = size (x); + + if (nargin != 2) + ## Find the first non-singleton dimension. + dim = 1; + while (dim < nd + 1 && sz(dim) == 1) + dim = dim + 1; + endwhile + if (dim > nd) + dim = 1; + endif + else + if (! (isscalar (dim) && dim == round (dim)) + && dim > 0 + && dim < (nd + 1)) + error ("mode: dim must be an integer and valid dimension"); + endif + endif + + sz2 = sz; + sz2 (dim) = 1; + sz3 = ones (1, nd); + sz3 (dim) = sz (dim); + + if (dim != 1) + perm = [1 : nd]; + perm(1) = dim; + perm(dim) = 1; + endif + + xs = sort (x, dim); + t = cat (dim, true (sz2), diff (xs, 1, dim) != 0); + if (issparse (x)) + t2 = sparse (sz(1), sz(2)); + else + t2 = zeros (size (t)); + endif + + if (dim != 1) + t2 (permute (t != 0, perm)) = diff ([find(permute (t, perm)); prod(sz)+1]); + f = max (ipermute (t2, perm), [], dim); + xs = permute (xs, perm); + else + t2 (t) = diff ([find(t); prod(sz)+1]); + f = max (t2, [], dim); + endif + + c = cell (sz2); + m = zeros (sz2); + for i = 1 : prod (sz2) + c {i} = xs (t2 (:, i) == f(i), i); + m (i) = c{i}(1); + endfor +endfunction + +%!test +%! [m, f, c] = mode (toeplitz (1:5)); +%! assert (m, [1,2,2,2,1]); +%! assert (f, [1,2,2,2,1]); +%! assert (c, {[1;2;3;4;5],[2],[2;3],[2],[1;2;3;4;5]}); +%!test +%! [m, f, c] = mode (toeplitz (1:5), 2); +%! assert (m, [1;2;2;2;1]); +%! assert (f, [1;2;2;2;1]); +%! assert (c, {[1;2;3;4;5];[2];[2;3];[2];[1;2;3;4;5]}); +%!test +%! a = sprandn (32, 32, 0.05); +%! [m, f, c] = mode (a); +%! [m2, f2, c2] = mode (full (a)); +%! assert (m, m2); +%! assert (f, f2); +%! assert (c, c2);