Moving average in a circle

Is there a way to calculate a moving average so that the values ​​at the beginning and at the end of the array are averaged with those at the opposite end?

For example, instead of this result:

A=[2 1 2 4 6 1 1]; movmean(A,2) ans = 2.0 1.5 1.5 3.0 5 3.5 1.0 

I want to get the vector [1.5 1.5 1.5 3 5 3.5 1.0] , since the initial element of array 2 will be averaged with the final element 1.

+5
source share
3 answers

Summarizing an arbitrary window size N , you can add the circular movmean behavior the way you want:

 movmean(A([(end-floor(N./2)+1):end 1:end 1:(ceil(N./2)-1)]), N, 'Endpoints', 'discard') 

For data A and N = 2 you get:

 ans = 1.5000 1.5000 1.5000 3.0000 5.0000 3.5000 1.0000 
+5
source

Convolution offers some good ways to do this. Although you may need to slightly modify your input if you only partially average the ends (i.e., the former is averaged with the latter in your example, but the latter is not averaged with the former).

 conv([A(end),A],[0.5 0.5],'valid') ans = 1.5000 1.5000 1.5000 3.0000 5.0000 3.5000 1.0000 

The generalized case here for the moving average size N is:

 conv(A([end-N+2:end, 1:end]),repmat(1/N,1,N),'valid') 
+2
source

For an arbitrary size of window n you can use circular convolution using the averaging mask defined as [1/n ... 1/n] (with n > in your example n = 2 ):

 result = cconv(A, repmat(1/n, 1, n), numel(A)); 
+2
source

Source: https://habr.com/ru/post/1271045/


All Articles