#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <rc/math/ring_buffer.h>
#include "algebra_common.h"
rc_ringbuf_t rc_ringbuf_empty(void)
{
rc_ringbuf_t out = RC_RINGBUF_INITIALIZER;
return out;
}
int rc_ringbuf_alloc(rc_ringbuf_t* buf, int size)
{
if(unlikely(buf==NULL)){
fprintf(stderr,"ERROR in rc_ringbuf_alloc, received NULL pointer\n");
return -1;
}
if(unlikely(size<2)){
fprintf(stderr,"ERROR in rc_ringbuf_alloc, size must be >=2\n");
return -1;
}
if(buf->initialized && buf->size==size && buf->d!=NULL) return 0;
buf->size = 0;
buf->index = 0;
buf->initialized = 0;
free(buf->d);
buf->d = (double*)calloc(size,sizeof(double));
if(buf->d==NULL){
fprintf(stderr,"ERROR in rc_ringbuf_alloc, failed to allocate memory\n");
return -1;
}
buf->size = size;
buf->initialized = 1;
return 0;
}
int rc_ringbuf_free(rc_ringbuf_t* buf)
{
rc_ringbuf_t new = RC_RINGBUF_INITIALIZER;
if(unlikely(buf==NULL)){
fprintf(stderr, "ERROR in rc_ringbuf_free, received NULL pointer\n");
return -1;
}
if(buf->initialized) free(buf->d);
*buf = new;
return 0;
}
int rc_ringbuf_reset(rc_ringbuf_t* buf)
{
if(unlikely(buf==NULL)){
fprintf(stderr, "ERROR in rc_ringbuf_reset, received NULL pointer\n");
return -1;
}
if(unlikely(!buf->initialized)){
fprintf(stderr,"ERROR rc_ringbuf_reset, ringbuf uninitialized\n");
return -1;
}
memset(buf->d,0,buf->size*sizeof(double));
buf->index=0;
return 0;
}
int rc_ringbuf_insert(rc_ringbuf_t* buf, double val)
{
int new_index;
if(unlikely(buf==NULL)){
fprintf(stderr,"ERROR in rc_ringbuf_insert, received NULL pointer\n");
return -1;
}
if(unlikely(!buf->initialized)){
fprintf(stderr,"ERROR in rc_ringbuf_insert, ringbuf uninitialized\n");
return -1;
}
new_index=buf->index+1;
if(new_index>=buf->size) new_index=0;
buf->d[new_index]=val;
buf->index=new_index;
return 0;
}
double rc_ringbuf_get_value(rc_ringbuf_t* buf, int pos)
{
int return_index;
if(unlikely(buf==NULL)){
fprintf(stderr,"ERROR in rc_ringbuf_get_value, received NULL pointer\n");
return -1.0f;
}
if(unlikely(pos<0 || pos>buf->size-1)){
fprintf(stderr,"ERROR in rc_ringbuf_get_value, position out of bounds\n");
return -1.0f;
}
if(unlikely(!buf->initialized)){
fprintf(stderr,"ERROR in rc_ringbuf_get_value, ringbuf uninitialized\n");
return -1.0f;
}
return_index=buf->index-pos;
if(return_index<0) return_index+=buf->size;
return buf->d[return_index];
}
double rc_ringbuf_std_dev(rc_ringbuf_t buf)
{
int i;
double mean, mean_sqr, diff;
if(unlikely(!buf.initialized)){
fprintf(stderr,"ERROR in rc_ringbuf_std_dev, ringbuf not initialized yet\n");
return -1.0f;
}
if(buf.size == 1) return 0.0f;
mean = 0.0f;
for(i=0;i<buf.size;i++) mean+=buf.d[i];
mean = mean/(double)buf.size;
mean_sqr = 0.0f;
for(i=0;i<buf.size;i++){
diff = buf.d[i]-mean;
mean_sqr += diff*diff;
}
return sqrt(mean_sqr/(double)(buf.size-1));
}