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);