Calculate the average of each matrix block
29 次查看(过去 30 天)
显示 更早的评论
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 个评论
采纳的回答
Vishnu
2023-7-11
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).
更多回答(4 个)
Malay Agarwal
2023-7-11
编辑:Malay Agarwal
2023-7-11
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 个评论
Kanishk Singhal
2023-7-11
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 个评论
Stephen23
2023-7-11
编辑:Stephen23
2023-7-11
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 个评论
Bruno Luong
2023-7-11
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 个评论
Bruno Luong
2023-7-11
编辑:Bruno Luong
2023-7-11
Take the average in first and third dimensions (after reshape).
另请参阅
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!