# Data Smoothing and Two-Column Table WARNING: This example assumes spaces are ignored for the I and F descriptors.

### Problem Statement

Suppose we have an input like the following. The first line gives the number of input values. Each of the input line has five fields with 10 positions each.
```         1    1    2    2    3    3    4    4
....5....0....5....0....5....0....5....0....5
17
13.5      17.23     9.0       20.9      23.0
16.3      15.9      21.5      14.78     18.5
16.54     13.67     10.78     9.5       13.2
19.6      20.0
```
Write a Fortran program that reads in the above input, computes the 2-moving average, and prints the following two-column table:
```         1    1    2    2    3    3    4    4    5
....5....0....5....0....5....0....5....0....5....0
**************************
*  Data Smoothing Table  *
**************************

No       x         y      No       x         y
---  --------  --------   ---  --------  --------
1     13.50        NA     2     17.23     15.36
3      9.00     13.11     4     20.90     14.95
5     23.00     21.95     6     16.30     19.65
7     15.90     16.10     8     21.50     18.70
9     14.78     18.14    10     18.50     16.64
11     16.54     17.52    12     13.67     15.11
13     10.78     12.23    14      9.50     10.14
15     13.20     11.35    16     19.60     16.40
17     20.00     19.80
```
Suppose the input values are x(1), x(2) and so on. The 2-moving average is computed as follows: y(1)=(x(1)+x(2))/2, y(2)=(x(2)+x(3))/2, y(3)=(x(3)+x(4))/2 and so on. In general, y(i)=(x(i)+x(i+1))/2. If x has n entries, y will have n-1 (i.e., y(n) cannot be computed).

Note that the first position is always for printer control. ### Solution

```PROGRAM  Smoothing
IMPLICIT  NONE
INTEGER, PARAMETER           :: MAX_SIZE = 20
REAL, DIMENSION(1:MAX_SIZE)  :: x, y
INTEGER                      :: Number
INTEGER                      :: i

DO i = 1, Number-1
y(i) = (x(i) + x(i+1)) / 2.0
END DO
WRITE(*,"(A)")   "             **************************"
WRITE(*,"(A)")   "             *  Data Smoothing Table  *"
WRITE(*,"(A)")   "             **************************"
WRITE(*,*)
WRITE(*,"(4A)")  (" ", " No       x         y    ", i = 1, 2)
WRITE(*,"(4A)")  (" ", "---  --------  --------  ", i = 1, 2)
WRITE(*,"(I4,F10.2,A10,I6,2F10.2)")  1, x(1), "NA", 2, x(2), y(1)
WRITE(*,"(I4,2F10.2,I6,2F10.2)")     (i, x(i), y(i-1), i = 3, Number)
END PROGRAM  Smoothing
```
Click here to download this program. ### Program Input and Output

The output of the program is:
```         1    1    2    2    3    3    4    4    5
....5....0....5....0....5....0....5....0....5....0
**************************
*  Data Smoothing Table  *
**************************

No       x         y      No       x         y
---  --------  --------   ---  --------  --------
1     13.50        NA     2     17.23     15.36
3      9.00     13.11     4     20.90     14.95
5     23.00     21.95     6     16.30     19.65
7     15.90     16.10     8     21.50     18.70
9     14.78     18.14    10     18.50     16.64
11     16.54     17.52    12     13.67     15.11
13     10.78     12.23    14      9.50     10.14
15     13.20     11.35    16     19.60     16.40
17     20.00     19.80
``` ### Discussion

• This program uses the format rescanning feature. More precisely, if all format edit descriptors are used and there still are input/output items, Fortran will skip to the next line and reuse the format. Due to this fact, the way of reading all values into array x() is the following:
```READ(*,"(I5)")  Number
```
The first READ reads in the number of values and the second READ reads the input values into array x(). The implied DO is equivalent to
```READ(*,"(5F10.0)")  x(1), x(2), ..., x(Number-1), x(Number)
```
After the first five entries of x() have been filled with values, all edit descriptors have been used. Therefore, Fortran skips to next line and reuses the format. As a result, the next five entries of x() are read in with the same format. Recall that the remaining edit descriptors are ignored if all data items have been filled with input. Since there are 17 input values in the input, after values are read into x(16) and x(17), there still are three unused edit descriptors in the format and they are ignored.
• Let us study the way of printing the two-column table. The first line of the table is so special, since it has a NA. We decided to print it in a different way using a different format.
```WRITE(*,"(I4,F10.2,A10,I6,2F10.2)")  1, x(1), "NA", 2, x(2), y(1)
```
As you can see, 1, x(1) and "NA" are printed with I4, F10.2 and A10, and 2, x(2) and y(1) are printed with i6 and 2F10.2.

For "NA", since its length is 2 and is printed with A10, "NA" is printed right-justified. If you print it with A, it becomes left-justified using 2 positions and 2, x(2) and y(1) will be shifted to the left. This ruins the alignment of the table.

Note that 2 is printed using I6 rather than I4. This is because we have two spaces between the third and the fourth columns. Please also note that we do not have printer control explicitly. It is incorporated into I4. More precisely, of these first four positions, the first one is for printer control and the remaining three are for the value.

• The remaining lines are easy. They are printed with the following format:
```WRITE(*,"(I4,2F10.2,I6,2F10.2)")  (i, x(i), y(i-1), i = 3, Number)
```
Since the first two entries were printed using another format, the remaining entries should start with 3, x(3) and y(2). This is the reason that the counter of the implied DO starts with 3. Note that we use a single WRITE to finish the job. Each iteration of this implied DO generates three items. However, the format has six edit descriptors and as a result it takes two iterations to use these six edit descriptors. Therefore, we have a two-column table. After these six items are printed, the format will be reused to print the next six items.