]> Creatis software - CreaPhase.git/blob - octave_packages/m/statistics/base/mode.m
update packages
[CreaPhase.git] / octave_packages / m / statistics / base / mode.m
1 ## Copyright (C) 2007-2012 David Bateman
2 ##
3 ## This file is part of Octave.
4 ##
5 ## Octave is free software; you can redistribute it and/or modify it
6 ## under the terms of the GNU General Public License as published by
7 ## the Free Software Foundation; either version 3 of the License, or (at
8 ## your option) any later version.
9 ##
10 ## Octave is distributed in the hope that it will be useful, but
11 ## WITHOUT ANY WARRANTY; without even the implied warranty of
12 ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13 ## General Public License for more details.
14 ##
15 ## You should have received a copy of the GNU General Public License
16 ## along with Octave; see the file COPYING.  If not, see
17 ## <http://www.gnu.org/licenses/>.
18
19 ## -*- texinfo -*-
20 ## @deftypefn  {Function File} {} mode (@var{x})
21 ## @deftypefnx {Function File} {} mode (@var{x}, @var{dim})
22 ## @deftypefnx {Function File} {[@var{m}, @var{f}, @var{c}] =} mode (@dots{})
23 ## Compute the most frequently occurring value in a dataset (mode).
24 ## @code{mode} determines the frequency of values along the first non-singleton
25 ## dimension and returns the value with the highest frequency.  If two, or
26 ## more, values have the same frequency @code{mode} returns the smallest.
27 ##
28 ## If the optional argument @var{dim} is given, operate along this dimension.
29 ##
30 ## The return variable @var{f} is the number of occurrences of the mode in
31 ## in the dataset.  The cell array @var{c} contains all of the elements
32 ## with the maximum frequency.
33 ## @seealso{mean, median}
34 ## @end deftypefn
35
36 function [m, f, c] = mode (x, dim)
37
38   if (nargin < 1 || nargin > 2)
39     print_usage ();
40   endif
41
42   if (! (isnumeric (x) || islogical (x)))
43     error ("mode: X must be a numeric vector or matrix");
44   endif
45
46   nd = ndims (x);
47   sz = size (x);
48   if (nargin < 2)
49     ## Find the first non-singleton dimension.
50     (dim = find (sz > 1, 1)) || (dim = 1);
51   else
52     if (!(isscalar (dim) && dim == fix (dim))
53         || !(1 <= dim && dim <= nd))
54       error ("mode: DIM must be an integer and a valid dimension");
55     endif
56   endif
57
58   sz2 = sz;
59   sz2(dim) = 1;
60   sz3 = ones (1, nd);
61   sz3(dim) = sz(dim);
62
63   if (issparse (x))
64     t2 = sparse (sz(1), sz(2));
65   else
66     t2 = zeros (sz);
67   endif
68
69   if (dim != 1)
70     perm = [dim, 1:dim-1, dim+1:nd];
71     t2 = permute (t2, perm);
72   endif
73
74   xs = sort (x, dim);
75   t = cat (dim, true (sz2), diff (xs, 1, dim) != 0);
76
77   if (dim != 1)
78     t2(permute (t != 0, perm)) = diff ([find(permute (t, perm))(:); prod(sz)+1]);
79     f = max (ipermute (t2, perm), [], dim);
80     xs = permute (xs, perm);
81   else
82     t2(t) = diff ([find(t)(:); prod(sz)+1]);
83     f = max (t2, [], dim);
84   endif
85
86   c = cell (sz2);
87   if (issparse (x))
88     m = sparse (sz2(1), sz2(2));
89   else
90     m = zeros (sz2, class (x));
91   endif
92   for i = 1 : prod (sz2)
93     c{i} = xs(t2(:, i) == f(i), i);
94     m(i) = c{i}(1);
95   endfor
96 endfunction
97
98
99 %!test
100 %! [m, f, c] = mode (toeplitz (1:5));
101 %! assert (m, [1,2,2,2,1]);
102 %! assert (f, [1,2,2,2,1]);
103 %! assert (c, {[1;2;3;4;5],[2],[2;3],[2],[1;2;3;4;5]});
104 %!test
105 %! [m, f, c] = mode (toeplitz (1:5), 2);
106 %! assert (m, [1;2;2;2;1]);
107 %! assert (f, [1;2;2;2;1]);
108 %! assert (c, {[1;2;3;4;5];[2];[2;3];[2];[1;2;3;4;5]});
109 %!test
110 %! a = sprandn (32, 32, 0.05);
111 %! [m, f, c] = mode (a);
112 %! [m2, f2, c2] = mode (full (a));
113 %! assert (m, sparse (m2));
114 %! assert (f, sparse (f2));
115 %! c_exp(1:length(a)) = { sparse (0) };
116 %! assert (c ,c_exp);
117 %! assert (c2,c_exp );
118
119 %!assert(mode ([2,3,1,2,3,4],1),[2,3,1,2,3,4]);
120 %!assert(mode ([2,3,1,2,3,4],2),2);
121 %!assert(mode ([2,3,1,2,3,4]),2);
122 %!assert(mode (single([2,3,1,2,3,4])), single(2));
123 %!assert(mode (int8([2,3,1,2,3,4])), int8(2));
124
125 %!assert(mode ([2;3;1;2;3;4],1),2);
126 %!assert(mode ([2;3;1;2;3;4],2),[2;3;1;2;3;4]);
127 %!assert(mode ([2;3;1;2;3;4]),2);
128
129 %!shared x
130 %! x(:,:,1) = toeplitz (1:3);
131 %! x(:,:,2) = circshift (toeplitz (1:3), 1);
132 %! x(:,:,3) = circshift (toeplitz (1:3), 2);
133 %!test
134 %! [m, f, c] = mode (x, 1);
135 %! assert (reshape (m, [3, 3]), [1 1 1; 2 2 2; 1 1 1]);
136 %! assert (reshape (f, [3, 3]), [1 1 1; 2 2 2; 1 1 1]);
137 %! c = reshape (c, [3, 3]);
138 %! assert (c{1}, [1; 2; 3]);
139 %! assert (c{2}, 2);
140 %! assert (c{3}, [1; 2; 3]);
141 %!test
142 %! [m, f, c] = mode (x, 2);
143 %! assert (reshape (m, [3, 3]), [1 1 2; 2 1 1; 1 2 1]);
144 %! assert (reshape (f, [3, 3]), [1 1 2; 2 1 1; 1 2 1]);
145 %! c = reshape (c, [3, 3]);
146 %! assert (c{1}, [1; 2; 3]);
147 %! assert (c{2}, 2);
148 %! assert (c{3}, [1; 2; 3]);
149 %!test
150 %! [m, f, c] = mode (x, 3);
151 %! assert (reshape (m, [3, 3]), [1 2 1; 1 2 1; 1 2 1]);
152 %! assert (reshape (f, [3, 3]), [1 2 1; 1 2 1; 1 2 1]);
153 %! c = reshape (c, [3, 3]);
154 %! assert (c{1}, [1; 2; 3]);
155 %! assert (c{2}, [1; 2; 3]);
156 %! assert (c{3}, [1; 2; 3]);
157
158 %% Test input validation
159 %!error mode ()
160 %!error mode (1, 2, 3)
161 %!error mode ({1 2 3})
162 %!error mode (['A'; 'B'])
163 %!error mode (1, ones(2,2))
164 %!error mode (1, 1.5)
165 %!error mode (1, 0)
166 %!error mode (1, 3)
167