Code covered by the BSD License  

Highlights from
Accumulate Connected Components

from Accumulate Connected Components by Wolfgang Schwanghart
Construct array with accumulation of connected components

accumconncomps(a,b,fun)
function [anew,bnew] = accumconncomps(a,b,fun)

% Construct array with accumulation of connected components 
% 
%     [c,valnew] = accumconncomps(cc,val)
%     [c,valnew] = accumconncomps(cc,val,fun)
%     [c,valnew] = accumconncomps(cc)
%
% accumconncomps creates vectors by accumulating elements in val using
% connected components in cc. Connected components are subsequent,
% identical elements in the vector cc.
%
% The input vectors cc and val must have same size. The output array c 
% contains the values of each connected component 
% (e.g. cc=[1 1 2 2 2 1 2 3 3] returns c=[1 2 1 2 3]). valnew contains the
% aggregated values in val in each connected component.
%
% fun is a function handle that determines the aggregation mode (default:
% @sum). fun must be a function that takes a vector and returns a scalar 
% (e.g. @mean, @var, @(x) max(x)-min(x)).
%
% accumconncomps(subs) is an equal expression to 
% accumconncomps(subs,ones(size(subs)),@sum) and counts the number of
% elements in each connected component.
%
% Example 1:
%
% Sum the values in val according to the connected components in cc.
%
%     cc  = [1 1 2 1 1 1 3 3 3 4 2 2];
%     val = [2.3 1.2 5 3 2 5 3.2 4.5 2 2.2 1.2 2.2];
% 
%     [c,valnew] = accumconncomps(cc,val,@sum)
% 
%     c    =
% 
%          1     2     1     3     4     2
% 
%     valnew =
% 
%          3.5   5.0   10.0  9.7   2.2   3.4
%
%
% Example 2:
%
% What does a distribution of the lengths of connected components in a
% random sequence of zeros and ones look like?
%
%    cc  = round(rand(1000000,1));
%    [c,valnew] = accumconncomps(cc);
%    hist(valnew,20)
%
%
% See also: ACCUMARRAY
%
% Author: Wolfgang Schwanghart (w.schwanghart[at]unibas.ch)
% Date: 10. Sept. 2008


% check input arguments
if nargin == 1
    b   = ones(size(a));
    fun = @sum;
elseif nargin == 2
    fun = @sum;
elseif nargin == 3
    % check if functionhandle is provided
    if ~isa(fun,'function_handle')
        error('the third input argument must be a function handle')
    end
else
    error('wrong number of input arguments')
end

% are vectors provided?
if ~isvector(a)
    error('val and subs must be vectors')
end

% do they have the same size?
siza = size(a);
sizb = size(b);
if siza~= sizb;
    error('val and subs must have same size')
end

% transpose if both vectors are row vectors
if siza(1)<siza(2)
    a = a(:);
    b = b(:);
    flagtranspose = true;
else
    flagtranspose = false;
end

% find beginnings of connected components
ad = [true; diff(a)~=0];

% assign new subs to the vector 
adc = cumsum(ad);

% nr of independent layers
uniqueLayers = adc(end);

% use accumarray to construct new vector
bnew = accumarray(adc,b,[uniqueLayers 1],fun);
anew = a(ad);

% transpose back if row vectors were provided
if flagtranspose
    anew = anew';
    bnew = bnew';
end
    

Contact us at files@mathworks.com