Averages/Simple moving average: Difference between revisions
Content added Content deleted
(Mathematica) |
(→{{header|C}}: matches code in std deviation task.) |
||
Line 152: | Line 152: | ||
=={{header|C}}== |
=={{header|C}}== |
||
The code in the first section duplicates the code for the Standard Deviation Task. |
|||
<lang c>#include <stdio.h> |
<lang c>#include <stdio.h> |
||
#include <stdlib.h> |
#include <stdlib.h> |
||
#include < |
#include <math.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; |
|||
so->sum2 = 0.0; |
|||
so->num = 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) { |
switch(action) { |
||
case |
case STDDEV: |
||
m = so->sum/so->num; |
|||
r.handle = malloc(sizeof(sma_obj_t)); |
|||
return sqrt(so->sum2/so->num - m*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; |
|||
m = so->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> |
}</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 }; |
<lang c>double v[] = { 1, 2, 3, 4, 5, 5, 4, 3, 2, 1 }; |
||
int main() |
int main() |
||
{ |
{ |
||
int i; |
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; |
return 0; |
||
}</lang> |
}</lang> |