/** 
 * @file VCNormalize.cpp
 // refactor-nice.pl: check this substitution
 // old: * @brief Vector Transform
 * @brief NICE::Vector Transform
 * @author Michael Koch
 * @date 11/28/2007

 */
#include <iostream>
#include <fstream>

#include "vislearning/classifier/vclassifier/VCNormalize.h"
#include "core/basics/FileMgt.h"
#include "vislearning/math/ftransform/PCA.h"

using namespace OBJREC;

using namespace std;
using namespace NICE;

VCNormalize::VCNormalize(const Config *conf, VecClassifier * classifier)
{
	this->classifier = classifier;
	this->mode = conf->gI("FTransform", "mode", 0);
	transformedSet.clear();
}

VCNormalize::~VCNormalize()
{
}

/** classify using simple vector */
ClassificationResult VCNormalize::classify(const NICE::Vector & x) const
{
	NICE::Vector transformed_vector = getNormalizedVector(x);
	cerr << "VCNormalize: transformed-vector: " << transformed_vector << endl;
	return this->classifier->classify(transformed_vector);
}

void VCNormalize::teach(const LabeledSetVector & teachSet)
{
	maxClassNo = teachSet.getMaxClassno();

	int n = teachSet.count();
	int d = teachSet.dimension();
	vector_max.resize(d);
	vector_min.resize(d);
	vector_span.resize(d);
	//get input data
	uint featurecount = 0;
	LOOP_ALL(teachSet)
		{
			EACH(classno,x);
			for (uint k = 0; k < x.size(); ++k)
			{
				double value = x[k];
				if (featurecount == 0)
				{
					vector_max[k] = value;
					vector_min[k] = value;
				}
				else
				{
					if (value > vector_max[k])
					{
						vector_max[k] = value;
					}
					if (value < vector_min[k])
					{
						vector_min[k] = value;
					}
				}

			}

			++featurecount;
		}
	vector_span = vector_max - vector_min;

	//save transformed Vectors
	LOOP_ALL(teachSet)
		{
			EACH(classno,x);
			NICE::Vector transformed_vector=getNormalizedVector(x);

			cerr << "VCNormalize: transformed-vector: " << transformed_vector
					<< endl;
			transformedSet.add(classno, transformed_vector);

		}
	this->classifier->teach(transformedSet);

}

NICE::Vector VCNormalize::getNormalizedVector(const NICE::Vector &x) const
{
	NICE::Vector transformed_vector(x.size());
	for (uint k = 0; k < vector_min.size(); ++k)
	{
		if (vector_span[k] > 1e-10)
		{
			transformed_vector[k] = (x[k] - vector_min[k]) / vector_span[k];
		}
		else
		{
			transformed_vector[k] = 1.0;
		}
	}
	return transformed_vector;
}

void VCNormalize::finishTeaching()
{
	this->classifier->finishTeaching();
}

void VCNormalize::restore(std::istream & is, int format)
{
	fprintf(stderr, "NOT YET IMPLEMENTED !!\n");
	exit(-1);
}

void VCNormalize::store(std::ostream & is, int format) const
{
	fprintf(stderr, "NOT YET IMPLEMENTED !!\n");
	exit(-1);
}

void VCNormalize::clear()
{
	fprintf(stderr, "NOT YET IMPLEMENTED !!\n");
	exit(-1);
}