# HG changeset patch # User Rik # Date 1281510845 25200 # Node ID 055b958636992185d0a6eec42e5fb0c964e4058a # Parent 22cd681a4e28a388457f23f375eff8cc671c2382 unique.m: Improve performance by only calculating necessary outputs. diff --git a/scripts/ChangeLog b/scripts/ChangeLog --- a/scripts/ChangeLog +++ b/scripts/ChangeLog @@ -1,3 +1,7 @@ +2010-08-10 Rik + + * set/unique.m: Check whether outputs are used before calculating. + 2010-08-10 Rik * statistics/base/module.mk, deprecated/module.mk, diff --git a/scripts/set/unique.m b/scripts/set/unique.m --- a/scripts/set/unique.m +++ b/scripts/set/unique.m @@ -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