accumarray

September 9th, 2009 Posted in Functions

Construct array with accumulation

Syntax

A = accumarray(subs,val)
A = accumarray(subs,val,sz)
A = accumarray(subs,val,sz,fun)
A = accumarray(subs,val,sz,fun,fillval)
A = accumarray(subs,val,sz,fun,fillval,issparse)
A = accumarray({subs1, subs2, …}, val, …)

Description

accumarray groups elements from a data set and applies a function to each group. A = accumarray(subs,val) creates an array A by accumulating elements of the vector val using the elements of subs as indices. The position of an element in subs determines which value of vals it selects the accumulated vector; the value of an element in subs determines the position of the accumulated vector in the output.

A = accumarray(subs,val,sz) creates an array A with size sz, where sz is a vector of positive integers. subs is nonempty with N>1 columns, then sz must have N elements, where all(sz >= max(subs,[],1)). subs is a nonempty column vector, then sz must be [M 1], where M >= MAX(subs). Specify sz as [] the default behavior.

A = accumarray(subs,val,sz,fun) applies function fun to each subset of elements of val. The default accumulating function is sum. To specify another function fun, use the @ symbol (e.g., @max). The function fun must accept a column vector and a numeric, logical, or character scalar, or a scalar cell. value A has the same class as the values returned by fun. Specify fun as [] the default behavior.

A = accumarray(subs,val,sz,fun,fillval) puts the scalar value fillval in elements of A that are not referred to by any row of subs. example, subs is empty, then A is repmat(fillval,sz). fillval and the values returned by fun must belong to the same class. The default value of fillval is 0.

A = accumarray(subs,val,sz,fun,fillval,issparse) creates an array A that is sparse the scalar input issparse is equal to logical 1 (i.e., true), or full issparse is equal to logical 0 (false). A is full by default. issparse is true, then fillval must be zero or [], and val and the output of fun must be double.

A = accumarray({subs1, subs2, …}, val, …) passes multiple subs vectors in a cell array. You can use any of the four optional inputs (sz, fun, fillval, or issparse) with this syntax.

Note the subscripts in subs are not sorted, fun should not depend on the order of the values in its input data.

The function processes the input as follows:

1.

Find out how many unique indices there are in subs. Each unique index defines a bin in the output array. The maximum index value in subs determines the size of the output array.
2.

Find out how many times each index is repeated.

This determines how many elements of vals are going to be accumulated at each bin in the output array.
3.

Create an output array. The output array is of size max(subs) or of size sz.
4.

Accumulate the entries in vals into bins using the values of the indices in subs and apply fun to the entries in each bin.
5.

Fill the values in the output positions not referred to by subs. Default fill value is zero; use fillval to set a different value.

Note subs should contain positive integers. subs can also be a cell vector with one or more elements, each element a vector of positive integers. All the vectors must have the same length. In this case, subs is treated as the vectors formed columns of an index matrix.val must be a numeric, logical, or character vector with the same length as the number of rows in subs. val can also be a scalar whose value is repeated all the rows of subs.

Example 1

Create a 5-by-1 vector and sum values repeated 1-D subscripts:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
val = 101:105;
subs = [1; 2; 4; 2; 4]
subs =
     1 
     2 
     4 
     2 
     4 
 
A = accumarray(subs, val)
A =
   101       % A(1) = val(1) = 101
   206       % A(2) = val(2)+val(4) = 102+104 = 206
     0       % A(3) = 0
   208       % A(4) = val(3)+val(5) = 103+105 = 208

Example 2

Create a 4-by-4 matrix and subtract values repeated 2-D subscripts:

1
2
3
4
5
6
7
8
9
10
val = 101:106;
subs=[1 2; 1 2; 3 1; 4 1; 4 4; 4 1];
B = accumarray(subs,val,[],@(x)sum(diff(x)))
 
B =
 
     0    -1     0     0
     0     0     0     0
     0     0     0     0
     2     0     0     0

The order of the subscripts matters:

1
2
3
4
5
6
7
8
9
10
val = 101:106;
subs=[1 2; 3 1; 1 2; 4 4; 4 1; 4 1];
B1 = accumarray(subs,val,[],@(x)sum(diff(x)))
 
B1 =
 
     0    -2     0     0
     0     0     0     0
     0     0     0     0
    -1     0     0     0

Example 3

Create a 2-by-3-by-2 array and sum values repeated 3-D subscripts:

1
2
3
4
5
6
7
8
9
10
val = 101:105;
subs = [1 1 1; 2 1 2; 2 3 2; 2 1 2; 2 3 2];
 
A = accumarray(subs, val)
A(:,:,1) =
   101     0     0
     0     0     0
A(:,:,2) =
     0     0     0
   206     0   208

Example 4

Create a 2-by-3-by-2 array, and sum values natively:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
val = 101:105;
subs = [1 1 1; 2 1 2; 2 3 2; 2 1 2; 2 3 2];
 
A = accumarray(subs, int8(val), [], @(x) sum(x,'native'))
A(:,:,1) =
  101    0    0
    0    0    0
A(:,:,2) =
    0    0    0
  127    0  127
 
class(A)
ans =
    int8

Example 5

Pass multiple subscript arguments in a cell array.

1.

Create a 12-element vector V:

1
V = 101:112;

2.

Create three 12-element vectors, one each dimension of the resulting array A. Note how the indices of these vectors determine which elements of V are accumulated in A:

1
2
3
4
5
6
7
8
9
10
      %        index 1   index 6 => V(1)+V(6) => A(1,3,1)
      %          |         |
      rowsubs = [1 3 3 2 3 1 2 2 3 3 1 2];
      colsubs = [3 4 2 1 4 3 4 2 2 4 3 4];
      pagsubs = [1 1 2 2 1 1 2 1 1 1 2 2];
      %                |
      %              index 4 => V(4) => A(2,1,2)
      %
      % A(1,3,1) = V(1) + V(6) = 101 + 106 = 207
      % A(2,1,2) = V(4) = 104

3.

Call accumarray, passing the subscript vectors in a cell array:

1
2
3
4
5
6
7
8
9
      A = accumarray({rowsubs colsubs pagsubs}, V)
      A(:,:,1) =
           0     0   207     0        % A(1,3,1) is 207
           0   108     0     0
           0   109     0   317
      A(:,:,2) =
           0     0   111     0
         104     0     0   219        % A(2,1,2) is 104
           0   103     0     0

Example 6

Create an array with the max function, and fill all empty elements of that array with NaN:

1
2
3
4
5
6
7
val = 101:105;
subs = [1 1; 2 1; 2 3; 2 1; 2 3];
 
A = accumarray(subs, val, [2 4], @max, NaN)
A =
   101   NaN   NaN   NaN
   104   NaN   105   NaN

Example 7

Create a sparse matrix using the prod function:

1
2
3
4
5
6
7
8
val = 101:105;
subs = [1 1; 2 1; 2 3; 2 1; 2 3];
 
A = accumarray(subs, val, [2 4], @prod, 0, true)
A =
   (1,1)            101
   (2,1)          10608
   (2,3)          10815

Example 8

Count the number of entries accumulated in each bin:

1
2
3
4
5
6
7
val = 1;
subs = [1 1; 2 1; 2 3; 2 1; 2 3];
 
A = accumarray(subs, val, [2 4])
A =
     1     0     0     0
     2     0     2     0

Example 9

Create a logical array that shows which bins will accumulate two or more values:

1
2
3
4
5
6
7
val = 101:105;
subs = [1 1; 2 1; 2 3; 2 1; 2 3];
 
A = accumarray(subs, val, [2 4], @(x) length(x) > 1)
A =
     0     0     0     0
     1     0     1     0

Example 10

Group values in a cell array:

1
2
3
4
5
6
7
8
9
10
11
12
val = 101:105;
subs = [1 1; 2 1; 2 3; 2 1; 2 3];
 
A = accumarray(subs, val, [2 4], @(x) {x})
A = 
    [       101]     []              []     []
    [2x1 double]     []    [2x1 double]     []
 
A{2}
ans =
   104
   102

See Also

full, sparse, sum

Related posts

Leave a Reply

You must be logged in to post a comment.