Averages/Simple moving average: Difference between revisions

→‎{{header|C}}: matches code in std deviation task.
(Mathematica)
(→‎{{header|C}}: matches code in std deviation task.)
Line 152:
 
=={{header|C}}==
The code in the first section duplicates the code for the Standard Deviation Task.
<lang c>#include <stdio.h>
#include <stdlib.h>
#include <stdargmath.h>
 
enum Action { STDDEV, MEAN, VAR, COUNT };
typedef struct sma_obj {
double sma;
typedef struct stat_obj_struct {
double sum;
double sum, sum2;
int period;
size_t num;
double *values;
Action action;
int lv;
} sStatObject, *StatObject;
} sma_obj_t;
 
StatObject NewStatObject( Action action )
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, ...)
{
so = (StatObject)malloc(sizeof(sStatObject));
va_list vl;
so->sum = 0.0;
sma_result_t r;
sma_obj_tso->sum2 *o= 0.0;
doubleso->num v= 0;
so->action = action;
 
return so;
va_start(vl, action);
}
#define FREE_STAT_OBJECT(so) \
free(so); so = NULL
double stat_obj_value(StatObject so, Action action)
{
double m;
if (so->num == 0.0) return 0.0;
switch(action) {
case SMA_NEWSTDDEV: // args: int period
m = so->sum/so->num;
r.handle = malloc(sizeof(sma_obj_t));
r.handlereturn sqrt(so->smasum2/so->num =- 0.0m*m);
case MEAN:
r.handle->period = va_arg(vl, int);
return so->sum/so->num;
r.handle->values = malloc(r.handle->period * sizeof(double));
case VAR:
r.handle->lv = 0;
r.handle->summ = 0.0so->sum/so->num;
return so->sum2/so->num - m*m;
break;
case COUNT:
case SMA_FREE: // args: sma_obj_t *handle
return 1.0*so->num;
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 stat_object_add(StatObject so, double v)
{
so->num++;
so->sum += v;
so->sum2 += v*v;
return stat_obj_value(so->action);
}</lang>
The following code creates the StatObject so that the add returns the running average.
 
<lang c>double v[] = { 1, 2, 3, 4, 5, 5, 4, 3, 2, 1 };
 
int main()
{
int i;
StatObject so = NewStatObject( MEAN );
 
sma_obj_t *h3 = sma(SMA_NEW, 3).handle;
for(i=0; i < sizeof(v)/sizeof(double) ; i++)
sma_obj_t *h5 = sma(SMA_NEW, 5).handle;
printf("val: %lf mean: %lf\n", v[i], stat_object_add(so, v[i]));
 
for(i=0; i < sizeof(v)/sizeof(double) ; i++) {
FREE_STAT_OBJECT(so);
printf("next number %lf, SMA_3 = %lf, SMA_5 = %lf\n",
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;
}</lang>
Anonymous user