changeset 18204:b29beed0e98d

Use first non-singleton dimension for prctile, quantile (bug #40736). * prctile.m, quantile.m: Use first non-singleton dimension when DIM is unspecified. Change documentation to match new behavior. Add %!tests to validate change.
author Rik <rik@octave.org>
date Fri, 03 Jan 2014 11:58:21 -0800
parents adbbacce8aaf
children 8c92b5e7fa4d
files scripts/statistics/base/prctile.m scripts/statistics/base/quantile.m
diffstat 2 files changed, 56 insertions(+), 20 deletions(-) [+]
line wrap: on
line diff
--- a/scripts/statistics/base/prctile.m	Fri Jan 03 14:34:47 2014 -0500
+++ b/scripts/statistics/base/prctile.m	Fri Jan 03 11:58:21 2014 -0800
@@ -30,10 +30,8 @@
 ##
 ## If @var{p} is unspecified, return the quantiles for @code{[0 25 50 75 100]}.
 ## The optional argument @var{dim} determines the dimension along which
-## the percentiles are calculated.  If @var{dim} is omitted, and @var{x} is
-## a vector or matrix, it defaults to 1 (column-wise quantiles).  When
-## @var{x} is an N-D array, @var{dim} defaults to the first non-singleton
-## dimension.
+## the percentiles are calculated.  If @var{dim} is omitted it defaults to the
+## the first non-singleton dimension.
 ## @seealso{quantile}
 ## @end deftypefn
 
@@ -59,14 +57,10 @@
   endif
 
   nd = ndims (x);
+  sz = size (x);
   if (nargin < 3)
-    if (nd == 2)
-      ## If a matrix or vector, always use 1st dimension.
-      dim = 1;
-    else
-      ## If an N-d array, find the first non-singleton dimension.
-      (dim = find (sz > 1, 1)) || (dim = 1);
-    endif
+    ## Find the first non-singleton dimension.
+    (dim = find (sz > 1, 1)) || (dim = 1);
   else
     if (!(isscalar (dim) && dim == fix (dim))
         || !(1 <= dim && dim <= nd))
@@ -84,11 +78,26 @@
 
 %!test
 %! pct = 50;
+%! q = prctile (1:4, pct);
+%! qa = 2.5;
+%! assert (q, qa);
 %! q = prctile (1:4, pct, 1);
 %! qa = [1, 2, 3, 4];
 %! assert (q, qa);
 %! q = prctile (1:4, pct, 2);
-%! qa = 2.5000;
+%! qa = 2.5;
+%! assert (q, qa);
+
+%!test
+%! pct = [50 75];
+%! q = prctile (1:4, pct);
+%! qa = [2.5 3.5];
+%! assert (q, qa);
+%! q = prctile (1:4, pct, 1);
+%! qa = [1, 2, 3, 4; 1, 2, 3, 4];
+%! assert (q, qa);
+%! q = prctile (1:4, pct, 2);
+%! qa = [2.5 3.5];
 %! assert (q, qa);
 
 %!test
--- a/scripts/statistics/base/quantile.m	Fri Jan 03 14:34:47 2014 -0500
+++ b/scripts/statistics/base/quantile.m	Fri Jan 03 11:58:21 2014 -0800
@@ -32,10 +32,8 @@
 ## If @var{p} is unspecified, return the quantiles for
 ## @code{[0.00 0.25 0.50 0.75 1.00]}.
 ## The optional argument @var{dim} determines the dimension along which
-## the quantiles are calculated.  If @var{dim} is omitted, and @var{x} is
-## a vector or matrix, it defaults to 1 (column-wise quantiles).  If
-## @var{x} is an N-D array, @var{dim} defaults to the first non-singleton
-## dimension.
+## the quantiles are calculated.  If @var{dim} is omitted it defaults to
+## the first non-singleton dimension.
 ##
 ## The methods available to calculate sample quantiles are the nine methods
 ## used by R (@url{http://www.r-project.org/}).  The default value is
@@ -108,7 +106,7 @@
 ## Author: Ben Abbott <bpabbott@mac.com>
 ## Description: Matlab style quantile function of a discrete/continuous distribution
 
-function q = quantile (x, p = [], dim = 1, method = 5)
+function q = quantile (x, p = [], dim, method = 5)
 
   if (nargin < 1 || nargin > 4)
     print_usage ();
@@ -126,9 +124,14 @@
     error ("quantile: P must be a numeric vector");
   endif
 
-  if (!(isscalar (dim) && dim == fix (dim))
-      || !(1 <= dim && dim <= ndims (x)))
-    error ("quantile: DIM must be an integer and a valid dimension");
+  if (nargin < 3)
+    ## Find the first non-singleton dimension.
+    (dim = find (size (x) > 1, 1)) || (dim = 1);
+  else
+    if (!(isscalar (dim) && dim == fix (dim))
+        || !(1 <= dim && dim <= ndims (x)))
+      error ("quantile: DIM must be an integer and a valid dimension");
+    endif
   endif
 
   ## Set the permutation vector.
@@ -158,6 +161,30 @@
 
 
 %!test
+%! p = 0.50;
+%! q = quantile (1:4, p);
+%! qa = 2.5;
+%! assert (q, qa);
+%! q = quantile (1:4, p, 1);
+%! qa = [1, 2, 3, 4];
+%! assert (q, qa);
+%! q = quantile (1:4, p, 2);
+%! qa = 2.5;
+%! assert (q, qa);
+
+%!test
+%! p = [0.50 0.75];
+%! q = quantile (1:4, p);
+%! qa = [2.5 3.5];
+%! assert (q, qa);
+%! q = quantile (1:4, p, 1);
+%! qa = [1, 2, 3, 4; 1, 2, 3, 4];
+%! assert (q, qa);
+%! q = quantile (1:4, p, 2);
+%! qa = [2.5 3.5];
+%! assert (q, qa);
+
+%!test
 %! p = 0.5;
 %! x = sort (rand (11));
 %! q = quantile (x, p);