# Computing the Moving Average of a Sequence

### Problem Statement

Given a sequence of n values x1, x2, ..., xn and a window size k>0, the k-th moving average of the given sequence is defined as follows:

The moving average sequence has n-k+1 elements as shown above.

The moving averages with k=4 of a ten-value sequence (n=10) is shown below

```  i     1   2   3   4   5   6   7   8   9 10
=====  ==  ==  ==  ==  ==  ==  ==  ==  ==  ==
Input  10  20  30  40  50  60  70  80  90 100
y1     25 = (10+20+30+40)/4
y2         35 = (20+30+40+50)/4
y3             45 = (30+40+50+60)/4
y4                 55 = (40+50+60+70)/4
y5                     65 = (50+60+70+80)/4
y6                         75 = (60+70+80+90)/4
y7                             85 = (70+80+90+100)/4
```
Thus, the moving average sequence has n-k+1=10-4+1=7 values.

Write a program to read in a set of real values and a window size, and use the above formulas to compute their moving averages.

### Solution

```! --------------------------------------------------------------------
! PROGRAM  MovingAverage:
!    This program reads in a set of input values and a window value,
! and computes the moving average of the input.  Let the values be
! x1, x2, x3, ..., xn and the window value is k.
! --------------------------------------------------------------------

PROGRAM  MovingAverage
IMPLICIT  NONE

INTEGER, PARAMETER :: MAX_SIZE = 30       ! array size
REAL, DIMENSION(1:MAX_SIZE) :: x, Avg     ! arrays
REAL               :: Sum                 ! for computation use
INTEGER            :: Window              ! window size
INTEGER            :: Size                ! actual array size
INTEGER            :: i, j                ! indices

READ(*,*)  Size, (x(i), i = 1, Size)      ! read in input data

WRITE(*,*) "**********************************"     ! display input
WRITE(*,*) "*   Moving Average Computation   *"
WRITE(*,*) "**********************************"
WRITE(*,*)
WRITE(*,*) "Input Array:"
WRITE(*,*) (x(i), i = 1, Size)
WRITE(*,*)
WRITE(*,*) "Window Size = ", Window

DO i = 1, Size-Window+1                   ! for each xi
Sum = 0.0                              ! compute the moving average
DO j = i, i+Window-1                   ! of xi, x(i+1), ...,
Sum = Sum + x(j)                    ! x(i+Window-1).
END DO
Avg(i) = Sum / Window                  ! save the result
END DO

WRITE(*,*)                                ! display the result
WRITE(*,*)  "Moving Average of the Given Array:"
WRITE(*,*)  (Avg(i), i = 1, Size-Window+1)
END PROGRAM  MovingAverage
```

### Program Input and Output

If the input data consist of the following:
```10
3.0  5.0  2.0  8.0  1.0
2.0  9.0  1.5  7.5  5.5
4
```
The out of the program is:
```**********************************
*   Moving Average Computation   *
**********************************

Input Array:
3.,  5.,  2.,  8.,  1.,  2.,  9.,  1.5,  7.5,  5.5

Window Size = 4

Moving Average of the Given Array:
4.5,  4.,  3.25,  5.,  3.375,  5.,  5.875
```

### Discussion

• Since the moving average has only Size-Window+1 elements, the outer DO-loop only iterates that many times.
• For iteration i, the sum of Window elements (i.e., x(i), x(i+1), x(i+2), ..., x(i+Window-1)) is computed to Sum.
• Then, the sum is divided by Window and stored into the moving average array Avg().