changeset 10882:055b95863699

unique.m: Improve performance by only calculating necessary outputs.
author Rik <octave@nomad.inbox5.com>
date Wed, 11 Aug 2010 00:14:05 -0700
parents 22cd681a4e28
children aef238768f25
files scripts/ChangeLog scripts/set/unique.m
diffstat 2 files changed, 42 insertions(+), 28 deletions(-) [+]
line wrap: on
line diff
--- a/scripts/ChangeLog	Tue Aug 10 14:09:31 2010 -0700
+++ b/scripts/ChangeLog	Wed Aug 11 00:14:05 2010 -0700
@@ -1,3 +1,7 @@
+2010-08-10  Rik <octave@nomad.inbox5.com>
+
+	* set/unique.m: Check whether outputs are used before calculating.
+
 2010-08-10  Rik <octave@nomad.inbox5.com>
 
 	* statistics/base/module.mk, deprecated/module.mk,
--- a/scripts/set/unique.m	Tue Aug 10 14:09:31 2010 -0700
+++ b/scripts/set/unique.m	Wed Aug 11 00:14:05 2010 -0700
@@ -24,9 +24,10 @@
 ## @deftypefnx {Function File} {} unique (@dots{}, "last")
 ## @deftypefnx {Function File} {[@var{y}, @var{i}, @var{j}] =} unique (@dots{})
 ## Return the unique elements of @var{x}, sorted in ascending order.
-## If @var{x} is a row vector, return a row vector, but if @var{x}
-## is a column vector or a matrix return a column vector.
-## @var{x} can be a cell array of strings.
+## If the input @var{x} is a vector then the output is a also a vector with the
+## same orientation (row or column) as the input.  For a matrix input the 
+## output is always a column vector.  @var{x} may also be a cell array of
+## strings.
 ##
 ## If the optional argument @code{"rows"} is supplied, return the unique
 ## rows of @var{x}, sorted in ascending order.
@@ -34,10 +35,10 @@
 ## If requested, return index vectors @var{i} and @var{j} such that
 ## @code{x(i)==y} and @code{y(j)==x}.
 ##
-## Additionally, one of @code{"first"} or @code{"last"} may be given as
-## an argument.  If @code{"last"} is specified, return the highest
-## possible indices in @var{i}, otherwise, if @code{"first"} is
-## specified, return the lowest.  The default is @code{"last"}.
+## Additionally, if @var{i} is a requested output then one of @code{"first"} or
+## @code{"last"} may be given as an input.  If @code{"last"} is specified, 
+## return the highest possible indices in @var{i}, otherwise, if @code{"first"}
+## is specified, return the lowest.  The default is @code{"last"}.
 ## @seealso{union, intersect, setdiff, setxor, ismember}
 ## @end deftypefn
 
@@ -48,15 +49,14 @@
   endif
 
   if (nargin > 1)
-
     ## parse options
     if (iscellstr (varargin))
       varargin = unique (varargin);
-      optfirst = strmatch ("first", varargin) > 0;
-      optlast = strmatch ("last", varargin) > 0;
-      optrows = strmatch ("rows", varargin) > 0;
+      optfirst = strmatch ("first", varargin, "exact") > 0;
+      optlast = strmatch ("last", varargin, "exact") > 0;
+      optrows = strmatch ("rows", varargin, "exact") > 0;
       if (optfirst && optlast)
-        error ("unique: cannot specify both \"last\" and \"first\"");
+        error ('unique: cannot specify both "last" and "first"');
       elseif (optfirst + optlast + optrows != nargin-1)
         error ("unique: invalid option");
       endif
@@ -65,13 +65,12 @@
     endif
 
     if (optrows && iscell (x))
-      warning ("unique: 'rows' is ignored for cell arrays");
+      warning ('unique: "rows" is ignored for cell arrays');
       optrows = false;
     endif
-
   else
-    optfirst = 0;
-    optrows = 0;
+    optfirst = false;
+    optrows = false;
   endif
 
   ## FIXME -- the operations
@@ -95,15 +94,16 @@
   endif
 
   if (optrows)
-    n = size (x, 1);
+    n = rows (x);
     dim = 1;
   else
     n = numel (x);
-    dim = (size (x, 1) == 1) + 1;
+    dim = (rows (x) == 1) + 1;
   endif
 
   y = x;
-  if (n < 1)
+  ## Special cases 0 and 1
+  if (n == 0)
     if (! optrows && isempty (x) && any (size (x)))
       if (iscell (y))
         y = cell (0, 1);
@@ -113,21 +113,29 @@
     endif
     i = j = [];
     return;
-  elseif (n < 2)
+  elseif (n == 1)
     i = j = 1;
     return;
   endif
 
   if (optrows)
-    [y, i] = sortrows (y);
+    if (nargout > 1)
+      [y, i] = sortrows (y);
+    else
+      y = sortrows (y);
+    endif
     match = all (y(1:n-1,:) == y(2:n,:), 2);
     idx = find (match);
     y(idx,:) = [];
   else
-    if (size (y, 1) != 1)
+    if (! isvector (y))
       y = y(:);
     endif
-    [y, i] = sort (y);
+    if (nargout > 1)
+      [y, i] = sort (y);
+    else
+      y = sort (y);
+    endif
     if (iscell (y))
       match = strcmp (y(1:n-1), y(2:n));
     else
@@ -137,7 +145,7 @@
     y(idx) = [];
   endif
 
-  if (nargout >= 3)
+  if (isargout (3))
     j = i;
     if (dim == 1)
       j(i) = cumsum ([1; !match]);
@@ -146,10 +154,12 @@
     endif
   endif
 
-  if (optfirst)
-    i(idx+1) = [];
-  else
-    i(idx) = [];
+  if (isargout (2))
+    if (optfirst)
+      i(idx+1) = [];
+    else
+      i(idx) = [];
+    endif
   endif
 
 endfunction