changeset 10669:cab3b148d4e4

Improve validation of input arguments for base statistics functions.
author Rik <octave@nomad.inbox5.com>
date Thu, 27 May 2010 20:12:51 -0700
parents 72585f1ca7a2
children 654fbde5dceb
files scripts/ChangeLog scripts/statistics/base/histc.m scripts/statistics/base/iqr.m scripts/statistics/base/kurtosis.m scripts/statistics/base/mode.m scripts/statistics/base/ranks.m scripts/statistics/base/run_count.m scripts/statistics/base/skewness.m scripts/statistics/base/statistics.m scripts/statistics/base/studentize.m
diffstat 10 files changed, 117 insertions(+), 115 deletions(-) [+]
line wrap: on
line diff
--- a/scripts/ChangeLog	Thu May 27 12:13:28 2010 -0700
+++ b/scripts/ChangeLog	Thu May 27 20:12:51 2010 -0700
@@ -1,3 +1,11 @@
+2010-05-26  Rik <octave@nomad.inbox5.com>
+
+        * statistics/base/histc.m, statistics/base/iqr.m, 
+        statistics/base/kurtosis.m, statistics/base/mode.m, 
+        statistics/base/ranks.m, statistics/base/run_count.m, 
+        statistics/base/skewness.m, statistics/base/statistics.m, 
+        statistics/base/studentize.m: Improve validation of input arguments. 
+
 2010-05-26  Jaroslav Hajek  <highegg@gmail.com>
 
 	* specfun/isprime.m: Fix and further optimize.
--- a/scripts/statistics/base/histc.m	Thu May 27 12:13:28 2010 -0700
+++ b/scripts/statistics/base/histc.m	Thu May 27 20:12:51 2010 -0700
@@ -32,8 +32,8 @@
 ## that was equal to the last element of @var{edges}.
 ##
 ## When @var{y} is a @math{N}-dimensional array, the same operation as above is
-## repeated along dimension @var{dim}.  If this argument is given, the operation
-## is performed along the first non-singleton dimension.
+## repeated along dimension @var{dim}.  If not specified @var{dim} defaults
+## to the first non-singleton dimension.
 ##
 ## If a second output argument is requested an index matrix is also returned.
 ## The @var{idx} matrix has same size as @var{y}.  Each element of @var{idx}
@@ -45,36 +45,43 @@
 
 function [n, idx] = histc (data, edges, dim)
   ## Check input
-  if (nargin < 2)
+  if (nargin < 2 || nargin > 3)
     print_usage ();
   endif
 
-  sz = size (data);
-  if (nargin < 3)
-    dim = find (sz > 1, 1);
-    if (isempty (dim))
-      dim = 1;
-    endif
+  if (!isreal (data))
+    error ("histc: Y argument must be real-valued, not complex");
   endif
 
-  if (!isreal (data))
-    error ("histc: first argument must be real a vector");
-  endif
-  
-  ## Make sure 'edges' is sorted
   num_edges = numel (edges);
   if (num_edges == 0)
-    error ("histc: edges must not be empty")
+    error ("histc: EDGES must not be empty")
   endif
 
-  if (isreal (edges))
+  if (!isreal (edges))
+    error ("histc: EDGES must be real-valued, not complex");
+  else
+    ## Make sure 'edges' is sorted
     edges = edges (:);
     if (! issorted (edges) || edges(1) > edges(end))
       warning ("histc: edge values not sorted on input");
       edges = sort (edges);
     endif
+  endif
+
+  nd = ndims (data);
+  sz = size (data);
+  if (nargin < 3)
+    ## Find the first non-singleton dimension.
+    dim = find (sz > 1, 1);
+    if (isempty (dim))
+      dim = 1;
+    endif
   else
-    error ("histc: second argument must be a vector");
+    if (!(isscalar (dim) && dim == round (dim)) || 
+        !(1 <= dim && dim <= nd))
+      error ("histc: DIM must be an integer and a valid dimension");
+    endif
   endif
 
   nsz = sz;
--- a/scripts/statistics/base/iqr.m	Thu May 27 12:13:28 2010 -0700
+++ b/scripts/statistics/base/iqr.m	Thu May 27 20:12:51 2010 -0700
@@ -36,23 +36,23 @@
     print_usage ();
   endif
 
+  if (!ismatrix(x) || ischar(x))
+    error ("iqr: X must be a numeric matrix or vector");
+  endif
+
   nd = ndims (x);
   sz = size (x);
   nel = numel (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 = find (sz > 1, 1);
+    if (isempty (dim))
       dim = 1;
     endif
   else
-    if (! (isscalar (dim) && dim == round (dim))
-        && dim > 0
-        && dim < (nd + 1))
-      error ("iqr: dim must be an integer and valid dimension");
+    if (!(isscalar (dim) && dim == round (dim)) || 
+        !(1 <= dim && dim <= nd))
+      error ("iqr: DIM must be an integer and a valid dimension");
     endif
   endif
 
--- a/scripts/statistics/base/kurtosis.m	Thu May 27 12:13:28 2010 -0700
+++ b/scripts/statistics/base/kurtosis.m	Thu May 27 20:12:51 2010 -0700
@@ -50,29 +50,25 @@
     print_usage ();
   endif
 
+  if (!ismatrix(x) || ischar(x))
+    error ("kurtosis: X must be a numeric matrix or vector");
+  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 = find (sz > 1, 1);
+    if (isempty (dim))
       dim = 1;
     endif
   else
-    if (! (isscalar (dim) && dim == round (dim))
-        && dim > 0
-        && dim < (nd + 1))
-      error ("kurtosis: dim must be an integer and valid dimension");
+    if (!(isscalar (dim) && dim == round (dim)) || 
+        !(1 <= dim && dim <= nd))
+      error ("kurtosis: DIM must be an integer and a valid dimension");
     endif
   endif
   
-  if (! ismatrix (x))
-    error ("kurtosis: x has to be a matrix or a vector");
-  endif
-
   c = sz(dim);
   sz(dim) = 1;
   idx = ones (1, nd);
--- a/scripts/statistics/base/mode.m	Thu May 27 12:13:28 2010 -0700
+++ b/scripts/statistics/base/mode.m	Thu May 27 20:12:51 2010 -0700
@@ -35,23 +35,22 @@
     print_usage ();
   endif
 
+  if (!ismatrix(x) || ischar(x))
+    error ("mode: X must be a numeric matrix or vector");
+  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 = find (sz > 1, 1);
+    if (isempty (dim))
       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");
+    if (!(isscalar (dim) && dim == round (dim)) || 
+        !(1 <= dim && dim <= nd))
+      error ("mode: DIM must be an integer and a valid dimension");
     endif
   endif
 
--- a/scripts/statistics/base/ranks.m	Thu May 27 12:13:28 2010 -0700
+++ b/scripts/statistics/base/ranks.m	Thu May 27 20:12:51 2010 -0700
@@ -37,22 +37,22 @@
     print_usage ();
   endif
 
+  if (!ismatrix(x) || ischar(x))
+    error ("ranks: X must be a numeric matrix or vector");
+  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 = find (sz > 1, 1);
+    if (isempty (dim))
       dim = 1;
     endif
   else
-    if (! (isscalar (dim) && dim == round (dim))
-        && dim > 0
-        && dim < (nd + 1))
-      error ("ranks: dim must be an integer and valid dimension");
+    if (!(isscalar (dim) && dim == round (dim)) || 
+        !(1 <= dim && dim <= nd))
+      error ("ranks: DIM must be an integer and a valid dimension");
     endif
   endif
 
--- a/scripts/statistics/base/run_count.m	Thu May 27 12:13:28 2010 -0700
+++ b/scripts/statistics/base/run_count.m	Thu May 27 20:12:51 2010 -0700
@@ -21,8 +21,8 @@
 ## @deftypefn {Function File} {} run_count (@var{x}, @var{n})
 ## Count the upward runs along the first non-singleton dimension of
 ## @var{x} of length 1, 2, @dots{}, @var{n}-1 and greater than or equal 
-## to @var{n}.  If the optional argument @var{dim} is given operate
-## along this dimension
+## to @var{n}.  If the optional argument @var{dim} is given then operate
+## along this dimension.
 ## @end deftypefn
 
 ## Author: FL <Friedrich.Leisch@ci.tuwien.ac.at>
@@ -34,30 +34,29 @@
     print_usage ();
   endif
 
+  if (!ismatrix(x) || ischar(x))
+    error ("run_count: X must be a numeric matrix or vector");
+  endif
+
+  if (!(isscalar (n) && n == round (n)) || n < 1)
+    error ("run_count: N must be a positive integer");
+  endif
+  
   nd = ndims (x);
   sz = size (x);
   if (nargin != 3)
     ## Find the first non-singleton dimension.
-    dim  = 1;
-    while (dim < nd + 1 && sz(dim) == 1)
-      dim = dim + 1;
-    endwhile
-    if (dim > nd)
+    dim = find (sz > 1, 1);
+    if (isempty (dim))
       dim = 1;
     endif
   else
-    if (! (isscalar (dim) && dim == round (dim))
-        && dim > 0
-        && dim < (nd + 1))
-      error ("run_count: dim must be an integer and valid dimension");
+    if (!(isscalar (dim) && dim == round (dim)) || 
+        !(1 <= dim && dim <= nd))
+      error ("run_count: DIM must be an integer and a valid dimension");
     endif
   endif
 
-  if (! (isscalar (n) && n == round (n)) && n > 0)
-    error ("run_count: n must be a positive integer");
-  endif
-  
-  nd = ndims (x);
   if (dim != 1)
     perm = [1 : nd];
     perm(1) = dim;
--- a/scripts/statistics/base/skewness.m	Thu May 27 12:13:28 2010 -0700
+++ b/scripts/statistics/base/skewness.m	Thu May 27 20:12:51 2010 -0700
@@ -49,29 +49,25 @@
     print_usage ();
   endif
 
+  if (!ismatrix(x) || ischar(x))
+    error ("skewness: X must be a numeric matrix or vector");
+  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 = find (sz > 1, 1);
+    if (isempty (dim))
       dim = 1;
     endif
   else
-    if (! (isscalar (dim) && dim == round (dim))
-        && dim > 0
-        && dim < (nd + 1))
-      error ("skewness: dim must be an integer and valid dimension");
+    if (!(isscalar (dim) && dim == round (dim)) || 
+        !(1 <= dim && dim <= nd))
+      error ("skewness: DIM must be an integer and a valid dimension");
     endif
   endif
 
-  if (! ismatrix (x))
-    error ("skewness: x has to be a matrix or a vector");
-  endif
-
   c = sz(dim);
   idx = ones (1, nd);
   idx (dim) = c;
--- a/scripts/statistics/base/statistics.m	Thu May 27 12:13:28 2010 -0700
+++ b/scripts/statistics/base/statistics.m	Thu May 27 20:12:51 2010 -0700
@@ -18,13 +18,15 @@
 ## <http://www.gnu.org/licenses/>.
 
 ## -*- texinfo -*-
-## @deftypefn {Function File} {} statistics (@var{x})
+## @deftypefn  {Function File} {} statistics (@var{x})
+## @deftypefnx {Function File} {} statistics (@var{x}, @var{dim})
 ## If @var{x} is a matrix, return a matrix with the minimum, first
 ## quartile, median, third quartile, maximum, mean, standard deviation,
-## skewness and kurtosis of the columns of @var{x} as its columns.
+## skewness, and kurtosis of the columns of @var{x} as its columns.
 ##
-## If @var{x} is a vector, calculate the statistics along the 
+## If @var{x} is a vector, calculate the statistics along the first 
 ## non-singleton dimension.
+##
 ## @end deftypefn
 
 ## Author: KH <Kurt.Hornik@wu-wien.ac.at>
@@ -36,28 +38,27 @@
     print_usage ();
   endif
 
+  if (!ismatrix(X) || ischar(X))
+    error ("statistics: X must be a numeric matrix or vector");
+  endif
+
   nd = ndims (X);
   sz = size (X);
-  nel = numel (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 = find (sz > 1, 1);
+    if (isempty (dim))
       dim = 1;
     endif
   else
-    if (! (isscalar (dim) && dim == round (dim))
-        && dim > 0
-        && dim < (nd + 1))
-      error ("statistics: dim must be an integer and valid dimension");
+    if (!(isscalar (dim) && dim == round (dim)) || 
+        !(1 <= dim && dim <= nd))
+      error ("statistics: DIM must be an integer and a valid dimension");
     endif
   endif
   
-  if (! ismatrix (X) || sz(dim) < 2)
-    error ("statistics: invalid argument");
+  if (sz(dim) < 2)
+    error ("statistics: dimension of X is too small (<2)");
   endif    
 
   emp_inv = quantile (X, [0.25; 0.5; 0.75], dim, 7);
--- a/scripts/statistics/base/studentize.m	Thu May 27 12:13:28 2010 -0700
+++ b/scripts/statistics/base/studentize.m	Thu May 27 20:12:51 2010 -0700
@@ -36,29 +36,25 @@
     print_usage ();
   endif
 
+  if (!ismatrix(x) || ischar(x))
+    error ("studentize: X must be a numeric matrix or vector");
+  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 = find (sz > 1, 1);
+    if (isempty (dim))
       dim = 1;
     endif
   else
-    if (! (isscalar (dim) && dim == round (dim))
-        && dim > 0
-        && dim < (nd + 1))
-      error ("studentize: dim must be an integer and valid dimension");
+    if (!(isscalar (dim) && dim == round (dim)) || 
+        !(1 <= dim && dim <= nd))
+      error ("studentize: DIM must be an integer and a valid dimension");
     endif
   endif
 
-  if (! ismatrix (x))
-    error ("studentize: x must be a vector or a matrix");
-  endif
-
   c = sz(dim);
   idx = ones (1, nd);
   idx(dim) = c;