/** 
* @file PDFParzen.cpp
* @brief Normal Distribution / Gaussian PDF
* @author Erik Rodner
* @date 01/29/2008

*/

#include <iostream>

#include "vislearning/math/pdf/PDFParzen.h"

using namespace OBJREC;

const double sqrt_2_m_pi = sqrt(2*M_PI);

using namespace std;
// refactor-nice.pl: check this substitution
// old: using namespace ice;
using namespace NICE;



// refactor-nice.pl: check this substitution
// old: PDFParzen::PDFParzen( const Vector & _samples, double _kernel_h ) 
PDFParzen::PDFParzen( const NICE::Vector & _samples, double _kernel_h ) 
    : samples(_samples), kernel_h(_kernel_h)
{
}


PDFParzen::~PDFParzen()
{
}

double PDFParzen::kernel ( double val ) const
{
    return exp( - 0.5*val*val ) / sqrt_2_m_pi;
}

// refactor-nice.pl: check this substitution
// old: double PDFParzen::getNLogDensity ( const Vector & x ) const
double PDFParzen::getNLogDensity ( const NICE::Vector & x ) const
{
    if ( x.size() != 1 ) 
    {
	fprintf (stderr, "PDFParzen::getNLogDensity: one dimensional distribution !\n");
	exit(-1);
    }

    double result = 0.0;
    double val = x[0];
    for ( size_t k = 0 ; k < samples.size() ; k++ )
    {
	result += kernel((samples[k] - val) / kernel_h);
    }
    result /= (samples.size() * kernel_h);

    return - log(result);
}

int PDFParzen::getDimension () const
{
    return 1;
}

void PDFParzen::vis ( Gnuplot & gnuplot ) const
{
    // building histogram
    map<double, double> hist;

    
    for ( size_t k = 0 ; k < samples.size() ; k++ )
    {
	double val = samples[k];
	if ( hist.find(val) == hist.end() )
	    hist[val] = 1.0;
	else
	    hist[val]++;
    }
    

    // refactor-nice.pl: check this substitution
    // old: ostringstream osfkt;
    std::ostringstream osfkt;
    osfkt << "f(y,x) = (1.0/(" << sqrt_2_m_pi << "))*(";
    osfkt << "exp(-((x - y)/" << kernel_h << ")**2));";

    // refactor-nice.pl: check this substitution
    // old: ostringstream os;
    std::ostringstream os;
    for ( size_t k = 0 ; k < samples.size() ; k++ )
    {
	os << "f(" << samples[k] << "," << "x)";
	if ( k != samples.size()-1 )
	    os << "+";
    }

    gnuplot.cmd( osfkt.str().c_str() );

    gnuplot.set_style("lines");
    gnuplot.plot_equation ( os.str(), "parzen" );

    gnuplot.set_style("lines");
    gnuplot.plot_xy ( hist, "histogram" );
}
