/** 
* @file Kernel.cpp
* @brief Interface for Mercer Kernels
* @author Erik Rodner
* @date 10/24/2007

*/
#include <iostream>

#include "Kernel.h"

using namespace OBJREC;

using namespace std;
using namespace NICE;



Kernel::Kernel( bool _symmetric ) 
{
    symmetric = _symmetric;
}

Kernel::~Kernel()
{
}

	
void Kernel::calcGramMatrix ( const VVector & vecSet, NICE::Matrix & G ) const
{
	G.resize(vecSet.size(), vecSet.size());
    if ( symmetric )
    {
		int ii = 0;
		for ( VVector::const_iterator i  = vecSet.begin();
							   i != vecSet.end();
							   i++, ii++ )
		{
			const NICE::Vector & x = *i;
			int jj = ii;
			for ( VVector::const_iterator j  = i;
							   j != vecSet.end();
							   j++, jj++ )
			{
				const NICE::Vector & y = *j;
				double kval = K(x,y);
				G(ii, jj) = kval;
				G(jj, ii) = kval;
			}
		}
    } else {
		int ii = 0;
		for ( VVector::const_iterator i  = vecSet.begin();
							   i != vecSet.end();
							   i++, ii++ )
		{
			const NICE::Vector & x = *i;
			int jj = 0;
			for ( VVector::const_iterator j  = vecSet.begin();
							   j != vecSet.end();
								   j++, jj++ )
			{
				const NICE::Vector & y = *j;
				double kval = K(x,y);
				G(ii, jj) = kval;
			}
		}
    }
}
	
void Kernel::calcKernelVector ( const VVector & vecSet, const NICE::Vector & y, NICE::Vector & kstar ) const
{
	kstar.resize(vecSet.size());
	int ii = 0;
	for ( VVector::const_iterator i  = vecSet.begin();
						   i != vecSet.end();
						   i++, ii++ )
	{
			const NICE::Vector & x = *i;
			double kval = K(x, y);
			kstar[ii] = kval;
	}
}
	
void Kernel::calcKernelData ( const VVector & vecSet, KernelData *kernelData ) const
{
	//cerr << "Kernel::calcKernelData()" << endl;

	NICE::Matrix & kernelMatrix = kernelData->getKernelMatrix();
	calcGramMatrix ( vecSet, kernelMatrix );
}
	
Kernel *Kernel::clone(void) const
{
	fthrow(Exception, "clone() not yet implemented.");
}
