octave-maintainers
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

accumarray as a patch against the CVS


From: David Bateman
Subject: accumarray as a patch against the CVS
Date: Thu, 05 Jul 2007 17:55:27 +0200
User-agent: Thunderbird 1.5.0.7 (X11/20060921)

Here is my latest (and fastest) version of accumarray as a patch against
the latest CVS

regards
David

-- 
David Bateman                                address@hidden
Motorola Labs - Paris                        +33 1 69 35 48 04 (Ph) 
Parc Les Algorithmes, Commune de St Aubin    +33 6 72 01 06 33 (Mob) 
91193 Gif-Sur-Yvette FRANCE                  +33 1 69 35 77 01 (Fax) 

The information contained in this communication has been classified as: 

[x] General Business Information 
[ ] Motorola Internal Use Only 
[ ] Motorola Confidential Proprietary

*** ./doc/interpreter/arith.txi.orig37  2007-07-05 17:24:07.491057577 +0200
--- ./doc/interpreter/arith.txi 2007-07-05 17:22:53.542494105 +0200
***************
*** 190,195 ****
--- 190,197 ----
  
  @DOCSTRING(sumsq)
  
+ @DOCSTRING(accumarray)
+ 
  @node Special Functions
  @section Special Functions
  
*** ./scripts/general/accumarray.m.orig37       2007-07-05 17:23:36.597499530 
+0200
--- ./scripts/general/accumarray.m      2007-07-05 17:05:34.342293633 +0200
***************
*** 0 ****
--- 1,134 ----
+ ## Copyright (C) 2007 David Bateman
+ ##
+ ## This program is free software; you can redistribute it and/or modify
+ ## it under the terms of the GNU General Public License as published by
+ ## the Free Software Foundation; either version 2 of the License, or
+ ## (at your option) any later version.
+ ##
+ ## This program is distributed in the hope that it will be useful,
+ ## but WITHOUT ANY WARRANTY; without even the implied warranty of
+ ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ ## GNU General Public License for more details.
+ ##
+ ## You should have received a copy of the GNU General Public License
+ ## along with this program; if not, write to the Free Software
+ ## Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ ## 02110-1301  USA
+ 
+ ## -*- texinfo -*-
+ ## @deftypefn {Function File} {} accumarray (@var{subs}, @var{vals}, 
@var{sz}, @var{fun}, @var{fillval}, @var{issparse})
+ ## @deftypefnx {Function File} {} accumarray (@var{csubs}, @var{vals}, 
@dots{})
+ ##
+ ## Creates an array by accumulating the elements of a vector into the
+ ## positions of 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 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{fun}
+ ## 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 assoicated 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.
+ ##
+ ## An example of the use of @code{accumarray} is:
+ ##
+ ## @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
+ ## @end deftypefn
+ 
+ function A = accumarray (subs, val, sz, fun, fillval, isspar)  
+ 
+   if (nargin < 2 || nargin > 6)
+     print_usage ();
+   endif
+ 
+   if (iscell(subs))
+     subs = cell2mat (cellfun (@(x) x(:), subs, 'UniformOutput', false));
+   endif
+   ndims = size (subs, 2);
+ 
+   if (nargin < 3 || isempty (sz))
+     sz = max (subs);
+     if (isscalar(sz))
+       sz = [sz, 1];
+     endif
+   else
+     if (length (sz) != ndims)
+       error ("accumarray: inconsistent dimensions");
+     endif
+   endif
+   
+   if (nargin < 4 || isempty (fun))
+     fun = @sum;
+   endif
+ 
+   if (nargin < 5 || isempty (fillval))
+     fillval = 0;
+   endif
+ 
+   if (nargin < 6 || isempty (isspar))
+     isspar = false;
+   endif
+   if (isspar)
+     if (ndims > 2)
+       error ("Can not have more than 2 dimensions in a sparse matrix");
+     endif
+   endif
+ 
+   [subs, idx] = sortrows (subs);
+   if (isscalar (val))
+     val = val * ones (size (idx));
+   else
+     val = val(idx);
+   endif
+   cidx = find([true; (sum (abs (diff (subs)), 2) != 0)]);
+   idx = cell (1, ndims);
+   for i = 1:ndims
+     idx{i} = subs (cidx, i);
+   endfor
+   x = cellfun (fun, mat2cell (val(:), diff ([cidx; length(val) + 1])));
+   if (isspar && fillval == 0)
+     A = sparse (idx{1}, idx{2}, x, sz(1), sz(2));
+   else
+     if (iscell (x))
+       ## Why did matlab choose to reverse the order of the elements
+       x = cellfun (@(x) flipud(x(:)), x, 'UniformOutput', false);
+       A = cell (sz);
+     elseif (fillval == 0)
+       A = zeros (sz, class(x));
+     else 
+       A = fillval .* ones (sz);
+     endif
+     A (sub2ind (sz, idx{:})) = x;
+   endif
+ endfunction
+ 
+ %!error (accumarray (1:5))
+ %!error (accumarray ([1,2,3],1:2))
+ %!assert (accumarray ([1;2;4;2;4],101:105), [101;206;0;208])
+ %!assert (accumarray ([1,1,1;2,1,2;2,3,2;2,1,2;2,3,2],101:105),cat(3, 
[101,0,0;0,0,0],[0,0,0;206,0,208]))
+ %!assert (accumarray 
([1,1,1;2,1,2;2,3,2;2,1,2;2,3,2],101:105,[],@(x)sin(sum(x))),sin(cat(3, 
[101,0,0;0,0,0],[0,0,0;206,0,208])))
+ %!assert (accumarray ({[1 3 3 2 3 1 2 2 3 3 1 2],[3 4 2 1 4 3 4 2 2 4 3 4],[1 
1 2 2 1 1 2 1 1 1 2 
2]},101:112),cat(3,[0,0,207,0;0,108,0,0;0,109,0,317],[0,0,111,0;104,0,0,219;0,103,0,0]))
+ %!assert (accumarray 
([1,1;2,1;2,3;2,1;2,3],101:105,[2,4],@max,NaN),[101,NaN,NaN,NaN;104,NaN,105,NaN])
+ %!assert (accumarray ([1 1; 2 1; 2 3; 2 1; 2 3],101:105,[2 
4],@prod,0,true),sparse([1,2,2],[1,1,3],[101,10608,10815],2,4))
+ %!assert (accumarray ([1 1; 2 1; 2 3; 2 1; 2 3],1,[2,4]), [1,0,0,0;2,0,2,0])
+ %!assert (accumarray ([1 1; 2 1; 2 3; 2 1; 2 
3],101:105,[2,4],@(x)length(x)>1),[false,false,false,false;true,false,true,false])
+ %!test
+ %! A = accumarray ([1 1; 2 1; 2 3; 2 1; 2 3],101:105,[2,4],@(x){x});
+ %! assert (A{2},[104;102])
2007-07-05  David Bateman  <address@hidden>

        * general/accumarray.m: New function to create an array by 
        accumulating the elements.

2007-07-05  David Bateman  <address@hidden>

        * interpreter/arith.txi: Add accumarray.


reply via email to

[Prev in Thread] Current Thread [Next in Thread]