/*
 * QrfeComplexNumber.cpp
 *
 *  Created on: 26.03.2012
 *      Author: stefan.detter
 */

#include "../inc/QrfeComplexNumber.h"

#include <math.h>
#include <iostream>
#include <limits>

QrfeComplexNumber::QrfeComplexNumber()
{
	m_realPart = 0;
	m_imaginaryPart = 0;
}

QrfeComplexNumber::QrfeComplexNumber(double re)
{
	m_realPart = re;
	m_imaginaryPart = 0;
}

QrfeComplexNumber::QrfeComplexNumber(double re, double im)
{
	m_realPart = re;
	m_imaginaryPart = im;
}

QrfeComplexNumber::QrfeComplexNumber(const QrfeComplexNumber& other)
{
	m_realPart = other.m_realPart;
	m_imaginaryPart = other.m_imaginaryPart;
}

double QrfeComplexNumber::realPart()
{
	return m_realPart;
}

double QrfeComplexNumber::imaginaryPart()
{
	return m_imaginaryPart;
}

void QrfeComplexNumber::setRealPart(double re)
{
	m_realPart = re;
}

void QrfeComplexNumber::setImaginaryPart(double im)
{
	m_imaginaryPart = im;
}

double QrfeComplexNumber::absoluteValue()
{
	return (sqrt(m_realPart * m_realPart + m_imaginaryPart * m_imaginaryPart));
}

double QrfeComplexNumber::phase()
{
	return atan2(m_imaginaryPart, m_realPart);
}

QString QrfeComplexNumber::toString ( int precision )
{
	QString str;
	str += QString::number(m_realPart, 'g', precision);
	str += " ";
	if(m_imaginaryPart < 0)
		str += "-";
	else
		str += "+";
	str += " ";
	int factor = 1;
	if(m_imaginaryPart < 0)
		factor = -1;
	str += QString::number(m_imaginaryPart*factor, 'g', precision);
	str += "i";

	return str;
}

QrfeComplexNumber& QrfeComplexNumber::operator=(const QrfeComplexNumber& c)
{
	m_realPart = c.m_realPart;
	m_imaginaryPart = c.m_imaginaryPart;
	return *this;
}

QrfeComplexNumber operator+(const QrfeComplexNumber& c1, const QrfeComplexNumber& c2)
{
	QrfeComplexNumber sum;
	sum.m_realPart = c1.m_realPart + c2.m_realPart;
	sum.m_imaginaryPart = c1.m_imaginaryPart + c2.m_imaginaryPart;
	return sum;
}

QrfeComplexNumber operator-(const QrfeComplexNumber& c1, const QrfeComplexNumber& c2)
{
	QrfeComplexNumber difference;
	difference.m_realPart = c1.m_realPart - c2.m_realPart;
	difference.m_imaginaryPart = c1.m_imaginaryPart - c2.m_imaginaryPart;
	return difference;
}

QrfeComplexNumber operator*(const QrfeComplexNumber& c1, const QrfeComplexNumber& c2)
{
	QrfeComplexNumber product;
	product.m_realPart = c1.m_realPart * c2.m_realPart
			- c1.m_imaginaryPart * c2.m_imaginaryPart;
	product.m_imaginaryPart = c1.m_realPart * c2.m_imaginaryPart
			+ c2.m_realPart * c1.m_imaginaryPart;
	return product;
}

QrfeComplexNumber operator/(const QrfeComplexNumber& c1, const QrfeComplexNumber& c2)
{
	QrfeComplexNumber quotient;
	double divisor;
	divisor = (c2.m_realPart * c2.m_realPart + c2.m_imaginaryPart * c2.m_imaginaryPart);
	if(divisor == 0)
	{
		quotient.m_realPart = std::numeric_limits<double>::max( );
		quotient.m_imaginaryPart = 0;
	}
	else
	{
		quotient.m_realPart = (c1.m_realPart * c2.m_realPart
				+ c1.m_imaginaryPart * c2.m_imaginaryPart)
				/ divisor;

		quotient.m_imaginaryPart = (c1.m_imaginaryPart * c2.m_realPart
				- c1.m_realPart * c2.m_imaginaryPart)
				/ divisor;
	}

	return quotient;
}

QDataStream& operator<< ( QDataStream& stream, const QrfeComplexNumber& complex)
{
	stream << complex.m_realPart;
	stream << complex.m_imaginaryPart;
	return stream;
}

QDataStream& operator>> ( QDataStream& stream, QrfeComplexNumber& complex)
{
	stream >> complex.m_realPart;
	stream >> complex.m_imaginaryPart;
	return stream;
}
