Calculate the average of each matrix block
29 views (last 30 days)
Show older comments
Hi,
I have a square matrix as shown below in my code and I would like to ocalculate the averge of each block of it. My code is follwoing:
close all;
clear all;
A = [1 2 3 4 1 2 3 4 1 2 3 4 7 6 5 4 ;
1 2 3 4 1 2 3 4 1 2 3 4 7 6 5 4 ;
1 2 3 4 1 2 3 4 1 2 3 4 7 6 5 4 ;
1 2 3 4 1 2 3 4 1 2 3 4 7 6 5 4 ;
1 2 3 4 1 2 3 4 1 2 3 4 7 6 5 4 ;
1 2 3 4 1 2 3 4 1 2 3 4 7 6 5 4 ;
1 2 3 4 1 2 3 4 1 2 3 4 7 6 5 4 ;
1 2 3 4 1 2 3 4 1 2 3 4 7 6 5 4 ;
1 2 3 4 1 2 3 4 1 2 3 4 7 6 5 4 ;
1 2 3 4 1 2 3 4 1 2 3 4 7 6 5 4 ;
1 2 3 4 1 2 3 4 1 2 3 4 7 6 5 4 ;
1 2 3 4 1 2 3 4 1 2 3 4 7 6 5 4 ;
1 2 3 4 1 2 3 4 1 2 3 4 7 6 5 4 ;
1 2 3 4 1 2 3 4 1 2 3 4 7 6 5 4 ;
1 2 3 4 1 2 3 4 1 2 3 4 7 6 5 4 ;
1 2 3 4 1 2 3 4 1 2 3 4 7 6 5 4 ];
cell_ndp = 2;
cell_nds = 2;
ObsPoints = cell_ndp*cell_nds; %number of total sp observables in each sub
subs = size(A,1)/ObsPoints; %number of main subdivisions
G_sam = zeros(subs); %the averaged sampled G matrix
% calculate the averages
for icell = 1:subs
obs_hor_start = (ObsPoints * (icell - 1)) + 1;
obs_hor_end = ObsPoints * icell;
for obs_hor = obs_hor_start:obs_hor_end
obs_ver_start = (ObsPoints * (icell - 1)) + 1;
obs_ver_end = ObsPoints * icell;
for obs_ver = obs_ver_start:obs_ver_end
G_sam(icell) = G_sam(icell) + A(obs_hor,obs_ver);
end
end
G_sam(icell) = G_sam(icell) / (ObsPoints*ObsPoints);
end
figure;
subplot(1,2,1)
spy(A)
subplot(1,2,2)
spy(G_sam)
However, this code calculates the averge of the diagonal blocks and leaving the rest, as shown in the spy figures below.
What I need is something like the following:
where the averages of all blocks are calculated in the same order of appearing.
Any help would be appreicted.
Thanks.
1 Comment
Accepted Answer
Vishnu
on 11 Jul 2023
Hi Lama Hamadeh,
To calculate the average of each block in the matrix in order, you need to modify the code as follows:
In this modified code, the outer loops iterate over the row and column indices of the blocks, and the inner loops calculate the sum of each block. The average of each block is then calculated and stored in the G_sam matrix. The resulting G_sam matrix will contain the averages of each block in order.
close all;
clear all;
A = [1 2 3 4 1 2 3 4 1 2 3 4 7 6 5 4 ;
1 2 3 4 1 2 3 4 1 2 3 4 7 6 5 4 ;
1 2 3 4 1 2 3 4 1 2 3 4 7 6 5 4 ;
1 2 3 4 1 2 3 4 1 2 3 4 7 6 5 4 ;
1 2 3 4 1 2 3 4 1 2 3 4 7 6 5 4 ;
1 2 3 4 1 2 3 4 1 2 3 4 7 6 5 4 ;
1 2 3 4 1 2 3 4 1 2 3 4 7 6 5 4 ;
1 2 3 4 1 2 3 4 1 2 3 4 7 6 5 4 ;
1 2 3 4 1 2 3 4 1 2 3 4 7 6 5 4 ;
1 2 3 4 1 2 3 4 1 2 3 4 7 6 5 4 ;
1 2 3 4 1 2 3 4 1 2 3 4 7 6 5 4 ;
1 2 3 4 1 2 3 4 1 2 3 4 7 6 5 4 ;
1 2 3 4 1 2 3 4 1 2 3 4 7 6 5 4 ;
1 2 3 4 1 2 3 4 1 2 3 4 7 6 5 4 ;
1 2 3 4 1 2 3 4 1 2 3 4 7 6 5 4 ;
1 2 3 4 1 2 3 4 1 2 3 4 7 6 5 4 ];
cell_ndp = 2;
cell_nds = 2;
ObsPoints = cell_ndp * cell_nds; % number of total sp observables in each sub
subs = size(A, 1) / ObsPoints; % number of main subdivisions
G_sam = zeros(subs); % the averaged sampled G matrix
% calculate the averages
for irow = 1:cell_ndp:subs*cell_ndp
for icol = 1:cell_nds:subs*cell_nds
block_sum = 0;
for obs_hor = irow:irow+cell_ndp-1
for obs_ver = icol:icol+cell_nds-1
block_sum = block_sum + A(obs_hor, obs_ver);
end
end
block_avg = block_sum / (cell_ndp * cell_nds);
block_row = ceil(irow / cell_ndp);
block_col = ceil(icol / cell_nds);
G_sam(block_row, block_col) = block_avg;
end
end
figure;
subplot(1, 2, 1)
spy(A)
subplot(1, 2, 2)
spy(G_sam)
You can also plot only the four slots provided by only taking the subarray of the averages(G_sam).
2 Comments
More Answers (4)
Malay Agarwal
on 11 Jul 2023
Edited: Malay Agarwal
on 11 Jul 2023
Hi Lama,
You can use something similar to a convolution operation in Machine Learning. You can start by creating a "filter", which is a 4x4 matrix of ones. Then, you can slide the filter over the 16x16 matrix in "strides" of 4. When the filter is on a 4x4 block in the 16x16 matrix, just multiply (element-wise) the elements in the block with the elements in the filter, take a sum and then divide by 16 to get the average. This opens up the avenue to doing weighted averages. Here's a code snippet which does this:
% Input image
data = randi([0, 255], 16, 16) % Replace with your actual data
% Filter
filter = ones(4, 4);
% Convolution parameters
stride = 4;
% Calculate output size
output_size = floor((size(data) - size(filter)) / stride) + 1
% Initialize output feature map
output = zeros(output_size);
% Scale
n = size(filter, 1) * size(filter, 2);
% Perform averaging
for i = 1:stride:size(data, 1)-size(filter, 1)+1
for j = 1:stride:size(data, 2)-size(filter, 2)+1
% Extract region of interest
roi = data(i:i+size(filter, 1)-1, j:j+size(filter, 2)-1);
% Perform element-wise multiplication and sum
summation = sum(sum(roi .* filter));
% Then divide
output((i+stride-1)/stride, (j+stride-1)/stride) = summation / n;
end
end
output
0 Comments
Kanishk Singhal
on 11 Jul 2023
You can use the mean function for calculating the average of submatrix.
Better way to iterate is using row, col rather than indexing.
It is general code also works for (4,4), (4,2)
close all;
clear all;
A = [1 2 3 4 1 2 3 4 1 2 3 4 7 6 5 4 ;
1 2 3 4 1 2 3 4 1 2 3 4 7 6 5 4 ;
1 2 3 4 1 2 3 4 1 2 3 4 7 6 5 4 ;
1 2 3 4 1 2 3 4 1 2 3 4 7 6 5 4 ;
1 2 3 4 1 2 3 4 1 2 3 4 7 6 5 4 ;
1 2 3 4 1 2 3 4 1 2 3 4 7 6 5 4 ;
1 2 3 4 1 2 3 4 1 2 3 4 7 6 5 4 ;
1 2 3 4 1 2 3 4 1 2 3 4 7 6 5 4 ;
1 2 3 4 1 2 3 4 1 2 3 4 7 6 5 4 ;
1 2 3 4 1 2 3 4 1 2 3 4 7 6 5 4 ;
1 2 3 4 1 2 3 4 1 2 3 4 7 6 5 4 ;
1 2 3 4 1 2 3 4 1 2 3 4 7 6 5 4 ;
1 2 3 4 1 2 3 4 1 2 3 4 7 6 5 4 ;
1 2 3 4 1 2 3 4 1 2 3 4 7 6 5 4 ;
1 2 3 4 1 2 3 4 1 2 3 4 7 6 5 4 ;
1 2 3 4 1 2 3 4 1 2 3 4 7 6 5 4 ];
cell_ndp = 2;
cell_nds = 2;
G_sam = zeros(cell_ndp, cell_nds);
for i=1:cell_ndp:size(A,1)
for j=1:cell_nds:size(A,2)
G_sam((i+cell_ndp-1)/cell_ndp, (j+cell_ndp-1)/cell_nds) = mean(A(i:i+cell_ndp-1,j:j+cell_nds-1), "all");
end
end
figure;
subplot(1,2,1)
spy(A)
subplot(1,2,2)
spy(G_sam)
G_sam
0 Comments
Stephen23
on 11 Jul 2023
Edited: Stephen23
on 11 Jul 2023
Here are some simple MATLAB approaches:
A = repmat([1,2,3,4,1,2,3,4,1,2,3,4,7,6,5,4],16,1)
M = mean(permute(reshape(A,4,4,4,4),[2,4,1,3]),3:4)
M = blockproc(A,[4,4], @(s)mean(s.data(:))) % requires image toolbox
V = 4*ones(1,4);
M = cellfun(@(m)mean(m(:)), mat2cell(A,V,V))
0 Comments
Bruno Luong
on 11 Jul 2023
A = [1 2 3 4 1 2 3 4 1 2 3 4 7 6 5 4 ;
1 2 3 4 1 2 3 4 1 2 3 4 7 6 5 4 ;
1 2 3 4 1 2 3 4 1 2 3 4 7 6 5 4 ;
1 2 3 4 1 2 3 4 1 2 3 4 7 6 5 4 ;
1 2 3 4 1 2 3 4 1 2 3 4 7 6 5 4 ;
1 2 3 4 1 2 3 4 1 2 3 4 7 6 5 4 ;
1 2 3 4 1 2 3 4 1 2 3 4 7 6 5 4 ;
1 2 3 4 1 2 3 4 1 2 3 4 7 6 5 4 ;
1 2 3 4 1 2 3 4 1 2 3 4 7 6 5 4 ;
1 2 3 4 1 2 3 4 1 2 3 4 7 6 5 4 ;
1 2 3 4 1 2 3 4 1 2 3 4 7 6 5 4 ;
1 2 3 4 1 2 3 4 1 2 3 4 7 6 5 4 ;
1 2 3 4 1 2 3 4 1 2 3 4 7 6 5 4 ;
1 2 3 4 1 2 3 4 1 2 3 4 7 6 5 4 ;
1 2 3 4 1 2 3 4 1 2 3 4 7 6 5 4 ;
1 2 3 4 1 2 3 4 1 2 3 4 7 6 5 4 ];
M = squeeze(mean(reshape(A,[4 4 4 4]),[1 3]))
2 Comments
Bruno Luong
on 11 Jul 2023
Edited: Bruno Luong
on 11 Jul 2023
Take the average in first and third dimensions (after reshape).
See Also
Categories
Find more on Sparse Matrices in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!