/**
 * @file RunningStatVector.cpp
 * @brief B. P. Welford Computation of Mean and Variance download at: http://www.johndcook.com/standard_deviation.html
 * @author Michael Koch
 * @date 19/01/2010
 */

#ifdef NOVISUAL
#include <vislearning/nice_nonvis.h>
#else
#include <vislearning/nice.h>
#endif

#include "vislearning/baselib/RunningStatVector.h"

using namespace OBJREC;
using namespace std;
using namespace NICE;

void RunningStatVector::Clear()
{
	m_n = 0;
	for (size_t k = 0; k < datavector.size(); k++)
	{
		if (datavector[k] != NULL)
		{
			delete datavector[k];
		}
	}
	datavector.clear();
}

RunningStatVector::~RunningStatVector()
{
	Clear();
}

void RunningStatVector::Push(NICE::Vector x)
{
	m_n++;

	// See Knuth TAOCP vol 2, 3rd edition, page 232
	if ((size_t) x.size() != this->size)
	{
		if (m_n == 1)
		{
			this->size = x.size();
		}
		else
		{
			fthrow(Exception,"RunningStatVector::Push(): this->size != x.size()\n");
		}
	}
	else
	{
		for (size_t k = 0; k < x.size(); k++)
		{
			if (m_n == 1)
			{
				RunningStat * rs = new RunningStat();
				datavector.push_back(rs);
			}
			datavector[k]->Push(x[k]);
		}
	}

}

size_t RunningStatVector::NumDataValues() const
{
return m_n;
}

size_t RunningStatVector::Size() const
{
return size;
}

NICE::Vector RunningStatVector::Mean() const
{
NICE::Vector mean(datavector.size(), 0.0);
for (size_t k = 0; k < datavector.size(); k++)
{
	mean[k] = datavector[k]->Mean();
}
return mean;
}

NICE::Vector RunningStatVector::Variance() const
{
NICE::Vector variance(datavector.size(), 0.0);
for (size_t k = 0; k < datavector.size(); k++)
{
	variance[k] = datavector[k]->Variance();
}
return variance;
}

NICE::Vector RunningStatVector::StandardDeviation() const
{
NICE::Vector std(Variance());
for (size_t k = 0; k < std.size(); k++)
{
	std[k] = sqrt(std[k]);
}
return std;
}