Academic Integrity: tutoring, explanations, and feedback — we don’t complete graded work or submit on a student’s behalf.

Running Average Problem Description: Given a list of n measurements m1, m2, ...

ID: 638948 • Letter: R

Question

Running Average Problem Description:
Given a list of n measurements m1, m2, ... , mn the average measurement value is defined as

????

We are interested in taking the average value of incoming measurements without having to store all previous measurements in memory. This can be accomplished in the following way (using 3 and 4 measurement values as an example)

????

????

????
In general, given the nth measurement value ???? , and a new measurement value mn+1, the new

????

average can be found by

???????

This is known as a running average.

(a) Write a C program that:
(i) Prompts the user for a measurement value.
(ii) Displays the current value for the running average.
(iii) Prompts the user for the next measurement value (repeating the previous steps 10 times).

(b) Test your program using the following values

????

Entry Number

Measurement Value

Running Average Output

1

-68.47

-68.47

2

94.11

12.82

3

91.42

39.02

4

-2.9

28.54

5

60.04

34.84

6

-71.66

17.09

7

-60.12

6.06

8

6.06

6.06

9

58.44

11.88

10

-6.92

10.00

Entry Number

Measurement Value

Running Average Output

1

-68.47

-68.47

2

94.11

12.82

3

91.42

39.02

4

-2.9

28.54

5

60.04

34.84

6

-71.66

17.09

7

-60.12

6.06

8

6.06

6.06

9

58.44

11.88

10

-6.92

10.00

Explanation / Answer

#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>

typedef struct sma_obj {
double sma;
double sum;
int period;
double *values;
int lv;
} sma_obj_t;

typedef union sma_result {
sma_obj_t *handle;
double sma;
double *values;
} sma_result_t;

enum Action { SMA_NEW, SMA_FREE, SMA_VALUES, SMA_ADD, SMA_MEAN };
sma_result_t sma(enum Action action, ...)
{
va_list vl;
sma_result_t r;
sma_obj_t *o;
double v;

va_start(vl, action);
switch(action) {
case SMA_NEW: // args: int period
r.handle = malloc(sizeof(sma_obj_t));
r.handle->sma = 0.0;
r.handle->period = va_arg(vl, int);
r.handle->values = malloc(r.handle->period * sizeof(double));
r.handle->lv = 0;
r.handle->sum = 0.0;
break;
case SMA_FREE: // args: sma_obj_t *handle
r.handle = va_arg(vl, sma_obj_t *);
free(r.handle->values);
free(r.handle);
r.handle = NULL;
break;
case SMA_VALUES: // args: sma_obj_t *handle
o = va_arg(vl, sma_obj_t *);
r.values = o->values;
break;
case SMA_MEAN: // args: sma_obj_t *handle
o = va_arg(vl, sma_obj_t *);
r.sma = o->sma;
break;
case SMA_ADD: // args: sma_obj_t *handle, double value
o = va_arg(vl, sma_obj_t *);
v = va_arg(vl, double);
if ( o->lv < o->period ) {
o->values[o->lv++] = v;
o->sum += v;
o->sma = o->sum / o->lv;
} else {
o->sum -= o->values[ o->lv % o->period];
o->sum += v;
o->sma = o->sum / o->period;
o->values[ o->lv % o->period ] = v; o->lv++;
}
r.sma = o->sma;
break;
}
va_end(vl);
return r;
}
double v[] = { 1, 2, 3, 4, 5, 5, 4, 3, 2, 1 };

int main()
{
int i;

sma_obj_t *h3 = sma(SMA_NEW, 3).handle;
sma_obj_t *h5 = sma(SMA_NEW, 5).handle;

for(i=0; i < sizeof(v)/sizeof(double) ; i++) {
printf("next number %lf, SMA_3 = %lf, SMA_5 = %lf ",
   v[i], sma(SMA_ADD, h3, v[i]).sma, sma(SMA_ADD, h5, v[i]).sma);
}

sma(SMA_FREE, h3);
sma(SMA_FREE, h5);
return 0;
}