changeset 13153:25effffba9b0

maint: Periodic merge of stable to default
author Jordi Gutiérrez Hermoso <jordigh@octave.org>
date Sat, 17 Sep 2011 22:07:41 -0500
parents 54f804016276 (current diff) 8d5f0b41e6b0 (diff)
children 8c7caa009a1e
files scripts/general/accumarray.m scripts/general/interp3.m scripts/general/interpn.m src/mappers.cc
diffstat 5 files changed, 134 insertions(+), 46 deletions(-) [+]
line wrap: on
line diff
--- a/scripts/general/accumarray.m	Fri Sep 16 18:14:50 2011 -0400
+++ b/scripts/general/accumarray.m	Sat Sep 17 22:07:41 2011 -0500
@@ -19,50 +19,78 @@
 
 ## -*- texinfo -*-
 ## @deftypefn  {Function File} {} accumarray (@var{subs}, @var{vals}, @var{sz}, @var{func}, @var{fillval}, @var{issparse})
-## @deftypefnx {Function File} {} accumarray (@var{csubs}, @var{vals}, @dots{})
+## @deftypefnx {Function File} {} accumarray (@var{subs}, @var{vals}, @dots{})
 ##
 ## Create an array by accumulating the elements of a vector into the
 ## positions defined by their subscripts.  The subscripts are defined by
-## the rows of the matrix @var{subs} and the values by @var{vals}.  Each row
-## of @var{subs} corresponds to one of the values in @var{vals}.
+## the rows of the matrix @var{subs} and the values by @var{vals}.  Each
+## row of @var{subs} corresponds to one of the values in @var{vals}. If
+## @var{vals} is a scalar, it will be used for each of the row of
+## @var{subs}.
 ##
-## The size of the matrix will be determined by the subscripts themselves.
-## However, if @var{sz} is defined it determines the matrix size.  The length
-## of @var{sz} must correspond to the number of columns in @var{subs}.
+## The size of the matrix will be determined by the subscripts
+## themselves. However, if @var{sz} is defined it determines the matrix
+## size. The length of @var{sz} must correspond to the number of columns
+## in @var{subs}.
 ##
-## The default action of @code{accumarray} is to sum the elements with the
-## same subscripts.  This behavior can be modified by defining the @var{func}
-## function.  This should be a function or function handle that accepts a
-## column vector and returns a scalar.  The result of the function should not
-## depend on the order of the subscripts.
+## The default action of @code{accumarray} is to sum the elements with
+## the same subscripts.  This behavior can be modified by defining the
+## @var{func} function.  This should be a function or function handle
+## that accepts a column vector and returns a scalar.  The result of the
+## function should not depend on the order of the subscripts.
+##
+## The elements of the returned array that have no subscripts associated
+## with them are set to zero.  Defining @var{fillval} to some other
+## value allows these values to be defined.
 ##
-## The elements of the returned array that have no subscripts associated with
-## them are set to zero.  Defining @var{fillval} to some other value allows
-## these values to be defined.
+## By default @code{accumarray} returns a full matrix.  If
+## @var{issparse} is logically true, then a sparse matrix is returned
+## instead.
 ##
-## By default @code{accumarray} returns a full matrix.  If @var{issparse} is
-## logically true, then a sparse matrix is returned instead.
-##
-## An example of the use of @code{accumarray} is:
+## The following @code{accumarray} example constructs a frequency table
+## that in the first column counts how many occurrences each number in
+## the second column has, taken from the vector @var{x}. Note the usage
+## of @code{unique}  for assigning to all repeated elements of @var{x}
+## the same index (@xref{doc-unique}).
 ##
 ## @example
 ## @group
-## accumarray ([1,1,1;2,1,2;2,3,2;2,1,2;2,3,2], 101:105)
+## x = [91, 92, 90, 92, 90, 89, 91, 89, 90, 100, 100, 100];
+## [u, ~, j] = unique (x);
+## [accumarray(j', 1), u']
+## @result{} 2    89
+##    3    90
+##    2    91
+##    2    92
+##    3   100
+## @end group
+## @end example
+##
+## Another example, where the result is a multidimensional 3D array and
+## the default value (zero) appears in the output:
+##
+## @example
+## @group
+## accumarray ([1, 1, 1;
+##              2, 1, 2;
+##              2, 3, 2;
+##              2, 1, 2;
+##              2, 3, 2], 101:105)
 ## @result{} ans(:,:,1) = [101, 0, 0; 0, 0, 0]
 ##    ans(:,:,2) = [0, 0, 0; 206, 0, 208]
 ## @end group
 ## @end example
 ##
-## The complexity in the non-sparse case is generally O(M+N), where N is the
-## number of
-## subscripts and M is the maximum subscript (linearized in multi-dimensional
-## case).
-## If @var{func} is one of @code{@@sum} (default), @code{@@max}, @code{@@min}
-## or @code{@@(x) @{x@}}, an optimized code path is used.
-## Note that for general reduction function the interpreter overhead can play a
-## major part and it may be more efficient to do multiple accumarray calls and
-## compute the results in a vectorized manner.
-## @seealso{accumdim}
+## The complexity in the non-sparse case is generally O(M+N), where N is
+## the number of subscripts and M is the maximum subscript (linearized
+## in multi-dimensional case). If @var{func} is one of @code{@@sum}
+## (default), @code{@@max}, @code{@@min} or @code{@@(x) @{x@}}, an
+## optimized code path is used. Note that for general reduction function
+## the interpreter overhead can play a major part and it may be more
+## efficient to do multiple accumarray calls and compute the results in
+## a vectorized manner.
+##
+## @seealso{accumdim, unique}
 ## @end deftypefn
 
 function A = accumarray (subs, vals, sz = [], func = [], fillval = [], issparse = [])
--- a/scripts/general/interp2.m	Fri Sep 16 18:14:50 2011 -0400
+++ b/scripts/general/interp2.m	Sat Sep 17 22:07:41 2011 -0500
@@ -101,9 +101,11 @@
   switch (nargin)
     case 1
       Z = varargin{1};
+      n = 1;
     case 2
       if (ischar (varargin{2}))
         [Z, method] = deal (varargin{:});
+        n = 1;
       else
         [Z, n] = deal (varargin{:});
       endif
@@ -159,6 +161,7 @@
     error ("interp2: X, Y must be numeric matrices");
   endif
   if (! isempty (n))
+    ## Calculate the interleaved input vectors.
     p = 2^n;
     XI = (p:p*zc)/p;
     YI = (p:p*zr)'/p;
@@ -337,17 +340,16 @@
     endif
 
     ## Check dimensions of XI and YI
-    if (isvector (XI) && isvector (YI))
+    if (isvector (XI) && isvector (YI) && ! size_equal (XI, YI))
       XI = XI(:).';
       YI = YI(:);
+      [XI, YI] = meshgrid (XI, YI);
     elseif (! size_equal (XI, YI))
       error ("interp2: XI and YI must be matrices of equal size");
     endif
 
-    ## FIXME bicubic/__splinen__ don't handle arbitrary XI, YI.
     if (strcmp (method, "cubic"))
-      ## Please remove the dummy zero when bicubic is fixed.
-      if (0 && isgriddata (XI) && isgriddata (YI'))
+      if (isgriddata (XI) && isgriddata (YI'))
         ZI = bicubic (X, Y, Z, XI (1, :), YI (:, 1), extrapval);
       elseif (isgriddata (X) && isgriddata (Y'))
         ## Allocate output
@@ -589,3 +591,20 @@
 %! X = meshgrid (1:4);
 %! assert (interp2 (X, 2.5, 2.5, 'nearest'), 3);
 
+%!shared z, zout, tol
+%!  z = [1 3 5; 3 5 7; 5 7 9];
+%!  zout = [1 2 3 4 5; 2 3 4 5 6; 3 4 5 6 7; 4 5 6 7 8; 5 6 7 8 9];
+%!  tol = 2 * eps;
+%!assert (interp2 (z), zout, tol);
+%!assert (interp2 (z, "linear"), zout, tol);
+%!assert (interp2 (z, "pchip"), zout, tol);
+%!assert (interp2 (z, "cubic"), zout, 10 * tol);
+%!assert (interp2 (z, "spline"), zout, tol);
+%!assert (interp2 (z, [2 3 1], [2 2 2]', "linear"), repmat ([5, 7, 3], [3, 1]), tol) 
+%!assert (interp2 (z, [2 3 1], [2 2 2]', "pchip"), repmat ([5, 7, 3], [3, 1]), tol) 
+%!assert (interp2 (z, [2 3 1], [2 2 2]', "cubic"), repmat ([5, 7, 3], [3, 1]), 10 * tol) 
+%!assert (interp2 (z, [2 3 1], [2 2 2]', "spline"), repmat ([5, 7, 3], [3, 1]), tol) 
+%!assert (interp2 (z, [2 3 1], [2 2 2], "linear"), [5 7 3], tol);
+%!assert (interp2 (z, [2 3 1], [2 2 2], "pchip"), [5 7 3], tol);
+%!assert (interp2 (z, [2 3 1], [2 2 2], "cubic"), [5 7 3], 10 * tol);
+%!assert (interp2 (z, [2 3 1], [2 2 2], "spline"), [5 7 3], tol);
--- a/scripts/general/interp3.m	Fri Sep 16 18:14:50 2011 -0400
+++ b/scripts/general/interp3.m	Sat Sep 17 22:07:41 2011 -0500
@@ -69,14 +69,14 @@
   extrapval = NA;
   nargs = nargin;
 
-  if (nargin < 1)
+  if (nargin < 1 || ! isnumeric (varargin{1}))
     print_usage ();
   endif
 
   if (ischar (varargin{end}))
     method = varargin{end};
     nargs = nargs - 1;
-  elseif (ischar (varargin{end-1}))
+  elseif (nargs > 1 && ischar (varargin{end - 1}))
     if (! isnumeric (varargin{end}) || ! isscalar (varargin{end}))
       error ("interp3: extrapal is expected to be a numeric scalar");
     endif
@@ -91,8 +91,8 @@
     if (ndims (v) != 3)
       error ("interp3: expect 3-dimensional array of values");
     endif
-    x = varargin (2:4);
-    if (any (! cellfun ("isvector", x)))
+    x = varargin (2:end);
+    if (any (! cellfun (@isvector, x)))
       for i = 2 : 3
         if (! size_equal (x{1}, x{i}))
           error ("interp3: dimensional mismatch");
@@ -109,7 +109,7 @@
       error ("interp3: expect 3-dimensional array of values");
     endif
     x = varargin (1:3);
-    if (any (! cellfun ("isvector", x)))
+    if (any (! cellfun (@isvector, x)))
       for i = 2 : 3
         if (! size_equal (x{1}, x{i}) || ! size_equal (x{i}, v))
           error ("interp3: dimensional mismatch");
@@ -119,7 +119,7 @@
       x{1} = permute (x{1}, [2, 1, 3]);
     endif
     y = varargin (5:7);
-    if (any (! cellfun ("isvector", y)))
+    if (any (! cellfun (@isvector, y)))
       for i = 2 : 3
         if (! size_equal (y{1}, y{i}))
           error ("interp3: dimensional mismatch");
@@ -146,3 +146,21 @@
 %! [xxi, yyi, zzi] = ndgrid (xi, yi, zi);
 %! vi2 = interpn(x, y, z, v, xxi, yyi, zzi);
 %! assert (vi, vi2);
+
+%!shared z, zout, tol
+%! z = zeros (3, 3, 3);
+%! zout = zeros (5, 5, 5);
+%! z(:,:,1) = [1 3 5; 3 5 7; 5 7 9];
+%! z(:,:,2) = z(:,:,1) + 2;
+%! z(:,:,3) = z(:,:,2) + 2;
+%! for n = 1:5
+%!   zout(:,:,n) = [1 2 3 4 5;
+%!                  2 3 4 5 6; 
+%!                  3 4 5 6 7;
+%!                  4 5 6 7 8;
+%!                  5 6 7 8 9] + (n-1);
+%! end
+%! tol = 10 * eps;
+%!assert (interp3 (z), zout, tol)
+%!assert (interp3 (z, "linear"), zout, tol)
+%!assert (interp3 (z, "spline"), zout, tol)
--- a/scripts/general/interpn.m	Fri Sep 16 18:14:50 2011 -0400
+++ b/scripts/general/interpn.m	Sat Sep 17 22:07:41 2011 -0500
@@ -70,14 +70,14 @@
   extrapval = NA;
   nargs = nargin;
 
-  if (nargin < 1)
+  if (nargin < 1 || ! isnumeric (varargin{1}))
     print_usage ();
   endif
 
   if (ischar (varargin{end}))
     method = varargin{end};
     nargs = nargs - 1;
-  elseif (ischar (varargin{end - 1}))
+  elseif (nargs > 1 && ischar (varargin{end - 1}))
     if (! isnumeric (varargin{end}) || ! isscalar (varargin{end}))
       error ("interpn: extrapal is expected to be a numeric scalar");
     endif
@@ -90,9 +90,12 @@
     v = varargin{1};
     m = 1;
     if (nargs == 2)
-      m = varargin{2};
-      if (! isnumeric (m) || ! isscalar (m) || floor (m) != m)
-        error ("interpn: M is expected to be a integer scalar");
+      if (ischar (varargin{2}))
+        method = varargin{2};
+      elseif (isnumeric (m) && isscalar (m) && round (m) == m)
+        m = varargin{2};
+      else
+        print_usage ();
       endif
     endif
     sz = size (v);
@@ -103,6 +106,8 @@
       x{i} = 1 : sz(i);
       y{i} = 1 : (1 / (2 ^ m)) : sz(i);
     endfor
+    y{1} = y{1}.';
+    [y{:}] = ndgrid (y{:});
   elseif (! isvector (varargin{1}) && nargs == (ndims (varargin{1}) + 1))
     v = varargin{1};
     sz = size (v);
@@ -290,3 +295,20 @@
 %! X = meshgrid (1:4);
 %! assert (interpn (X, 2.5, 2.5, 'nearest'), 3);
 
+%!shared z, zout, tol
+%! z = zeros (3, 3, 3);
+%! zout = zeros (5, 5, 5);
+%! z(:,:,1) = [1 3 5; 3 5 7; 5 7 9];
+%! z(:,:,2) = z(:,:,1) + 2;
+%! z(:,:,3) = z(:,:,2) + 2;
+%! for n = 1:5
+%!   zout(:,:,n) = [1 2 3 4 5;
+%!                  2 3 4 5 6; 
+%!                  3 4 5 6 7;
+%!                  4 5 6 7 8;
+%!                  5 6 7 8 9] + (n-1);
+%! end
+%! tol = 10 * eps;
+%!assert (interpn (z), zout, tol)
+%!assert (interpn (z, "linear"), zout, tol)
+%!assert (interpn (z, "spline"), zout, tol)
--- a/src/mappers.cc	Fri Sep 16 18:14:50 2011 -0400
+++ b/src/mappers.cc	Sat Sep 17 22:07:41 2011 -0500
@@ -1565,7 +1565,8 @@
     "-*- texinfo -*-\n\
 @deftypefn {Mapping Function} {} round (@var{x})\n\
 Return the integer nearest to @var{x}.  If @var{x} is complex, return\n\
-@code{round (real (@var{x})) + round (imag (@var{x})) * I}.\n\
+@code{round (real (@var{x})) + round (imag (@var{x})) * I}. If there\n\
+are two nearest integers, return the one further away from zero.\n\
 \n\
 @example\n\
 @group\n\
@@ -1573,7 +1574,7 @@
      @result{} -3   3\n\
 @end group\n\
 @end example\n\
-@seealso{ceil, floor, fix}\n\
+@seealso{ceil, floor, fix, roundb}\n\
 @end deftypefn")
 {
   octave_value retval;