Vector sliding average over different number of points

2 views (last 30 days)
Hi all,
I have a number of blocks, to be exact, and inside each block there is a certain number of points. The number of points in each block are defined within vector . The sum of these points is equal to .
I have a vector A with a size of and I want to take its average over the number of points in each block. In other words, I want to construct a vector with size where each element of the averaged vector represents the average of points in each block. Clearly my code is not doing this. Here is my code attempt:
close all;
clear all;
%number of points in each block
Ns = [4 2 2 1 3 1 1 2 3 1 1 2 1 2 3 1]; %sum of these points = 30. Number of blocks=16
%--------
%vector to be averaged over
A = [4.5 2 3 1.5 2.5 2.5 3 2 4.5 2 3 1.5 2.5 2.5 3 2 ...
4.5 2 3 1.5 2.5 2.5 3 2 3 1.5 2.5 2.5 3 2]; %vector size = 1x30
%visuliase it
figure;
subplot(1,2,1)
plot(A,'b')
xlabel('No of points')
ylabel('A')
hold on
%--------
%averaged vector
%initilaise the starting point
startrho0point = 1;
for indcell = 1:numel(Ns)
%calculate the sliding averge over the number of points in each block
A_ave(indcell) = sum(A(startrho0point:Ns(indcell)))/Ns(indcell);
%re-initilise the starting point so the next iteration starts from the
%last point reached in this current iteration
startrho0point = Ns(indcell)+1;
end
%visualise the average
subplot(1,2,2)
plot(A_ave,'k')
xlabel('No of blocks')
ylabel('A_{ave}')
%--------
Any help would be appreciated.
Thanks.

Accepted Answer

Dyuman Joshi
Dyuman Joshi on 20 Mar 2024
Edited: Dyuman Joshi on 20 Mar 2024
Here's a vectorized method -
%number of points in each block
Ns = [4 2 2 1 3 1 1 2 3 1 1 2 1 2 3 1]; %sum of these points = 30. Number of blocks=16
%--------
%vector to be averaged over
A = [4.5 2 3 1.5 2.5 2.5 3 2 4.5 2 3 1.5 2.5 2.5 3 2 ...
4.5 2 3 1.5 2.5 2.5 3 2 3 1.5 2.5 2.5 3 2]; %vector size = 1x30
%Groups to distribute indices into
vec = [1 cumsum(Ns)]
vec = 1x17
1 4 6 8 9 12 13 14 16 19 20 21 23 24 26 29 30
%discretize the indices (of each element in A) into groups
%note that numel(A)==sum(Ns)
idx = discretize(1:sum(Ns), vec, 'IncludedEdge', 'Right')
idx = 1x30
1 1 1 1 2 2 3 3 4 5 5 5 6 7 8 8 9 9 9 10 11 12 12 13 14 14 15 15 15 16
So, the 1st 4 elements are in the group 1, 5th and 6th elements are in group 2 and so on.
%Find the mean accordingly -
A_ave = accumarray(idx.', A.', [], @mean).'
A_ave = 1x16
2.7500 2.5000 2.5000 4.5000 2.1667 2.5000 2.5000 2.5000 3.1667 1.5000 2.5000 2.7500 2.0000 2.2500 2.6667 2.0000
%visuliase it
figure;
subplot(1,2,1)
plot(A,'b')
xlabel('No of points')
ylabel('A')
%visualise the average
subplot(1,2,2)
plot(A_ave,'k')
xlabel('No of blocks')
ylabel('A_{ave}')
%--------

More Answers (0)

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!