Sum Blocks in 3D Matrix - MATLAB
For a 3N by 3N by 3N matrix A, I would like to get an N by N over N matrix B whose entries are taken from the block summation in A.
For example, B (1,1,1) = the sum of all elements of A (1: 3,1: 3,1: 3).
Basically, A is a kind of high resolution matrix and B is a low resolution matrix from summation in A.
source to share
reshape
+ sum
and as such should be quite efficient -
sumrows = sum(reshape(A,3,[]),1); %// Sum along rows
sumcols = sum(reshape(sumrows,N,3,[]),2); %// Sum along cols
B = reshape(sum(reshape(sumcols,N*N,3,[]),2),N,N,N); %// Sum along 3rd dim
If you are crazy about one-liners, here's what brings all the steps into one -
B = reshape(sum(reshape(sum(reshape(sum(reshape(A,3,[]),1),N,3,[]),2),N*N,3,[]),2),N,N,N);
source to share
If memory is not a concern, you can use the "tagging" approach: construct a three-way label to group the elements A
and use that label as the first input argument for accumarray
to make the sum. The label uses integers from 1
to N
, so the result accumarray
already has the desired shape ( N
x N
x N
).
N = 5; F = 3; %// block size per dimension A = rand(15,15,15); %// example data. Size FN x FN x FN [ii jj kk] = ind2sub(size(A), 1:numel(A)); label = ceil([ii.' jj.' kk.']/F); result = accumarray(label, A(:));
source to share