/* 
 * Thomas Pantzer: t_floating_avg.cc, v0.1b  8.6.99 16:49 
 * 
 * 
 * Copyright 1999 by Thomas Pantzer
 * 
 * Permission to use, copy, modify, and distribute this software for noncommercial 
 * use and without fee is hereby granted, provided that the above copyright notice 
 * appear in all copies and that both that copyright notice and this permission 
 * notice appear in supporting documentation, and that the name of the Author not be 
 * used in advertising or publicity pertaining to distribution of the software 
 * without specific, written prior permission. The Author makes no representations about
 * the suitability of this software for any purpose.  It is provided "as is" 
 * without expressed or implied warranty. 
 * 
 * 
 * pantec@isys2.informatik.uni-leipzig.de   (Thomas Pantzer) 
 * 
 */


#include "copyright.h"


#include "t_floating_avg.h"

#include <math.h>
#include <stdio.h>

//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
//
//		t_range
//
//_______________________________________________
void t_Range::Reset(void)
{
//	fprintf(stderr,"t_Range::Reset()\n");

	max = -1000000000.0;
	min = -max;
	size = 1.0;
}

char t_Range::Update(double d)
{
//	fprintf(stderr,"t_Range::Update()\n");

	char changed;
	changed = 0;

	if (d > max)
	   {
	    max = d;
	    changed = 1; 
	   }

	if (d < min)
	   {
	    min = d;
	    changed = -1; 
	   }

#ifdef DEBUG
	if (changed == true)
	   fprintf(stderr,"t_Range::Update(%g) %g<x<%g\t",d,min,max); 
#endif
	
	size = max - min;
	if (size == 0.0)
	   size = 1.0; 

	return changed;
}




void t_laverage::Add(double v)
{
	AvgV += ((v - AvgV) / alen);
}

double t_laverage::Range(void)
{
	return size;
}

void t_laverage::Reset(void)
{
	AvgV = 0.0;
	t_Range::Reset();
}





void t_average::Add(double v)
{
	t_laverage::Add(v);
	Update(v);
}

void t_average::Init(double l)
{
	alen = l;
//	AvgV = 0.0;
	t_laverage::Reset();
}


void t_window_stack::Init(int l)
{
	len = l;
	idx = 0;
	cnt = 0;

	V = new double [len];
	
	Reset();
}


void t_window_stack::Reset(void)
{
	ZeroIt();
	t_average::Reset();
}

void t_window_stack::ZeroIt(void)
{
	for (int i=0; i<len; i++)
	   V[i] = 0.0;	
}


void t_window_stack::Done(void)
{
//	fprintf(stderr,"this:0x%08lx\tV:0x%08lx\n",(long)this,(long)V);

	if (V != NULL)
	   delete V;

	V = NULL;
	len = 0;
}


void t_window_stack::Add(double v)
{
	V[idx] = v;

	if (cnt < len)
	   cnt++; 

	idx++;
	idx %= len;

	t_average::Add(v);
}


double t_window_stack::Get(int i)
{
//	if ((i >= len) || (i >= cnt))
//	   {
//	    return 0.0;
//	   }
	    
	int j = idx + len - 1 - i;
        j %= len;

        return V[j]; 
}

double t_window_stack::Get(double I)
{
	fprintf(stderr,"t_window_stack::Get(double %g)\n",I);

	double f = floor(I);
	double c = ceil(I);

	int v = (int)f;
	int w = (int)c;

	if ((w-v) == 0)
	   fprintf(stderr,"ceil == floor\n");

	double a = Get(v);
	double b = Get(w);

	double d = I - f;
	double e = (b - a) * d;

	return (a + e);
}

double t_window_stack::Value(void)
{
	double S = 0.0;
	for (int i=0; i<len; i++)
	  S += V[i];

        return S/(double)cnt;
}


double t_window_stack::Info(void)
{
	double S = 0.0;
	for (int i=0; i<len; i++)
	  S += (V[i] * log(V[i]));


	double	d = -S / log((double)len);
	return d;
}













/**/
/**/
/**/
/**/
/**/
/**/
/**/
/**/
/*****  End Of File  ****************************/
