/***************************************************************************
                          linearregression.cpp  -  description
                             -------------------
    begin                : Tue Apr 8 2003
    copyright            : (C) 2003 by Martin Merck
    email                : merck@astro.uni-wuerzburg.de
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 ***************************************************************************/

#include "linearregression.h"
#include <math.h>
#include <qstring.h>

LinearRegression::LinearRegression()
{
	reset();
}

LinearRegression::~LinearRegression()
{
}

void LinearRegression::reset()
{
	m_dSX  = 0.0;
	m_dSXX = 0.0;
	m_dSY  = 0.0;
	m_dSYY = 0.0;
	m_dSXY = 0.0;
	m_iNum = 0;
	m_zReversed = false;
}

void LinearRegression::addPoint( int p_iX, int p_iY )
{
	if( p_iX != -1 && p_iY != -1 )
		addPoint( (double) p_iX, (double) p_iY);
}

void LinearRegression::addPoint( double p_dX, double p_dY )
{
	if( p_dX < 0. && p_dY < 0. )
		return;

	if( m_iNum == 0)
		qDebug( "Befor first point fit has Axis: %f   Slope: %f   with %d points", getAxis(), getSlope(), m_iNum );
	qDebug( "Adding Point %f %f", p_dX, p_dY );
	m_dSX += p_dX;
	m_dSXX += ( p_dX * p_dX );
	m_dSY += p_dY;
	m_dSYY += ( p_dY * p_dY );
	m_dSXY += ( p_dX * p_dY );
	m_iNum++;
	qDebug( "Fit has Axis: %f   Slope: %f   with %d points", getAxis(), getSlope(), m_iNum );
}

double LinearRegression::getAxis( )
{
	if( m_iNum > 1 )
	{
		if( m_zReversed )
			return ( (m_dSX - getSlope() * m_dSY) / m_iNum );
		else
			return ( (m_dSY - getSlope() * m_dSX) / m_iNum );
	}
	else
		return 0.0;
}

double LinearRegression::getSlope()
{
	double dSlope;
	if( m_iNum > 1 )
	{
		double help1 = ((double) m_iNum) * m_dSXY - m_dSX * m_dSY;
		double help2 = ((double) m_iNum) * m_dSXX - m_dSX * m_dSX;
		double help3 = ((double) m_iNum) * m_dSYY - m_dSY * m_dSY;

		dSlope = help1 / help2;
		if( m_zReversed )
			dSlope = help1 / help3;	
	}
	else
		dSlope = 0.0;
	return dSlope;
}

double LinearRegression::getR()
{
	double dR;
	if( m_iNum > 1 )
	{
		double help1 = ((double) m_iNum) * m_dSXY - m_dSX * m_dSY;
		double help2 = ((double) m_iNum) * m_dSXX - m_dSX * m_dSX;
		double help3 = ((double) m_iNum) * m_dSYY - m_dSY * m_dSY;

		dR = help1 / sqrt( help2 * help3 );
	}
	else
		dR = 0.0;
	return dR;
}
