//////////////////////////////////////////////////////////////////////////
//                                                                      
// complex -                                                             
//                                                                      
//      limited realization of c++ standart complex numbers 
//         , 
//         (, , , ).
//          .    
//		   .
//
// Copyright (c) 2001 RC Module Inc.                                    
//                                                                      
//                                                                     
//    $Revision::      $      $Date::  $               
//                                                                      
//////////////////////////////////////////////////////////////////////////

#ifndef	_COMPLEX_HEADER
#define	_COMPLEX_HEADER

namespace std {

extern "C" double sqrt( double );

template<class T>
class complex 
{
	T r;
	T i;
public:
	typedef T value_type;

	complex(const T& re = T(), const T& im = T())	:r(re), i(im) {}
	complex(const complex& c)						:r(c.r), i(c.i) {}
	template<class X> explicit complex(const complex<X>& c)	:r(c.real()), i(c.imag()) {}

	T real() const	{	return r;	}
	T imag() const	{	return i;	}
	T norm() const	{	return r*r+i*i;	}
	T abs() const	{	return T( sqrt( double(norm()) ) );	}

	complex<T>& operator= (const T& t)	{	r = t;	i = 0;	return *this;	}
	complex<T>& operator+=(const T& t)	{	r+= t;			return *this;	}
	complex<T>& operator-=(const T& t)	{	r-= t;			return *this;	}
	complex<T>& operator*=(const T& t)	{	r*= t;	i*= t;	return *this;	}
	complex<T>& operator/=(const T& t)	{	r/= t;	i/= t;	return *this;	}

	complex& operator=(const complex&);
	template<class X> complex<T>& operator= (const complex<X>& c)
		{	r = c.real(), i = c.imag();	return *this;	}
};

template<class T> complex<T> operator+(const complex<T>& a, const complex<T>& b)
{	
	return complex( a.real() + b.real(), a.imag() + b.imag() );	
}
template<class T> complex<T> operator+(const complex<T>& a, const T& b)
{	
	return complex( a.real() + b, a.imag() );	
}
template<class T> complex<T> operator+(const T& a, const complex<T>& b)
{	
	return complex( a + b.real(), b.imag() );	
}

template<class T> complex<T> operator-(const complex<T>& a, const complex<T>& b)
{	
	return complex( a.real() - b.real(), a.imag() - b.imag() );	
}
template<class T> complex<T> operator-(const complex<T>& a, const T& b)
{	
	return complex( a.real() - b, a.imag() );	
}
template<class T> complex<T> operator-(const T& a, const complex<T>& b)
{	
	return complex( a - b.real(), -b.imag() );	
}

template<class T> complex<T> operator*(const complex<T>& a, const complex<T>& b)
{	
	return complex( a.real()*b.real() - a.imag()*b.imag(), 
		a.real()*b.imag() + a.imag()*b.real() );	
}
template<class T> complex<T> operator*(const complex<T>& a, const T& b)
{	
	return complex( a.real()*b, a.imag()*b );	
}
template<class T> complex<T> operator*(const T& a, const complex<T>& b)
{	
	return complex( b.real()*a, b.imag()*a );	
}

template<class T> complex<T> operator/(const complex<T>& a, const T& b)
{	
	return complex( a.real()/b, a.imag()/b );	
}

template<class T> complex<T> operator-(const complex<T>& a)
{
	return complex( -a.real(), -a.imag() );	
}

template<class T> bool operator==(const complex<T>& a, const complex<T>& b)
{
	return a.real() == b.real() && a.imag() == b.imag();
}
template<class T> bool operator==(const complex<T>& a, const T& b)
{
	return a.real() == b && a.imag() == 0;
}
template<class T> bool operator==(const T& a, const complex<T>& b)
{
	return b.real() == a && b.imag() == 0;
}

template<class T> bool operator!=(const complex<T>& a, const complex<T>& b)
	{	return !(a==b);}
template<class T> bool operator!=(const complex<T>& a, const T& b)
	{	return !(a==b);}
template<class T> bool operator!=(const T& a, const complex<T>& b)
	{	return !(a==b);}

template<class T> T real(const complex<T>& c){	return c.real();	}
template<class T> T imag(const complex<T>& c){	return c.imag();	}
template<class T> T norm(const complex<T>& c){	return c.norm();	}
template<class T> T abs(const complex<T>& c){	return c.abs();	}

};	//	std

#endif  // _COMPLEX_HEADER
