You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1364 lines
41 KiB
1364 lines
41 KiB
// -*- C++ -*-
|
|
/***************************************************************************
|
|
*
|
|
* complex - Declaration for the Standard Library complex class
|
|
*
|
|
* $Id: complex 172106 2011-11-02 17:04:12Z statham $
|
|
*
|
|
***************************************************************************
|
|
*
|
|
* Copyright (c) 1994-2001 Rogue Wave Software, Inc. All Rights Reserved.
|
|
*
|
|
* This computer software is owned by Rogue Wave Software, Inc. and is
|
|
* protected by U.S. copyright laws and other laws and by international
|
|
* treaties. This computer software is furnished by Rogue Wave Software,
|
|
* Inc. pursuant to a written license agreement and may be used, copied,
|
|
* transmitted, and stored only in accordance with the terms of such
|
|
* license and with the inclusion of the above copyright notice. This
|
|
* computer software or any other copies thereof may not be provided or
|
|
* otherwise made available to any other person.
|
|
*
|
|
* U.S. Government Restricted Rights. This computer software is provided
|
|
* with Restricted Rights. Use, duplication, or disclosure by the
|
|
* Government is subject to restrictions as set forth in subparagraph (c)
|
|
* (1) (ii) of The Rights in Technical Data and Computer Software clause
|
|
* at DFARS 252.227-7013 or subparagraphs (c) (1) and (2) of the
|
|
* Commercial Computer Software--Restricted Rights at 48 CFR 52.227-19,
|
|
* as applicable. Manufacturer is Rogue Wave Software, Inc., 5500
|
|
* Flatiron Parkway, Boulder, Colorado 80301 USA.
|
|
*
|
|
**************************************************************************/
|
|
|
|
#ifndef _RWSTD_COMPLEX_INCLUDED
|
|
#define _RWSTD_COMPLEX_INCLUDED
|
|
|
|
#include <sstream>
|
|
#include <iosfwd>
|
|
#include <utility>
|
|
|
|
#include <rw/_defs.h>
|
|
#include <rw/_math.h>
|
|
|
|
|
|
_RWSTD_NAMESPACE_BEGIN (std)
|
|
|
|
template <class _TypeT>
|
|
class complex;
|
|
|
|
_RWSTD_SPECIALIZED_CLASS class complex<float>;
|
|
_RWSTD_SPECIALIZED_CLASS class complex<double>;
|
|
#ifndef _RWSTD_NO_LONG_DOUBLE
|
|
_RWSTD_SPECIALIZED_CLASS class complex<long double>;
|
|
#endif
|
|
|
|
|
|
_RWSTD_SPECIALIZED_CLASS
|
|
class complex<float>
|
|
{
|
|
public:
|
|
typedef float value_type;
|
|
|
|
complex (const float& __re=0.0f, const float& __im=0.0f)
|
|
: _C_re(__re), _C_im(__im)
|
|
{ ; }
|
|
|
|
_EXPLICIT complex (const complex<double>&);
|
|
|
|
#ifndef _RWSTD_NO_LONG_DOUBLE
|
|
_EXPLICIT complex (const complex<long double>&);
|
|
#endif
|
|
|
|
float imag () const { return _C_im; }
|
|
float real () const { return _C_re; }
|
|
|
|
#ifndef _RWSTD_NO_MEMBER_TEMPLATES
|
|
template <class _TypeX> complex<float>& operator= (const complex<_TypeX>& __rhs) {_C_re=__rhs.real(); _C_im=__rhs.imag(); return *this;}
|
|
template <class _TypeX> complex<float>& operator+= (const complex<_TypeX>& __rhs) {_C_re+=__rhs.real(); _C_im+=__rhs.imag(); return *this;}
|
|
template <class _TypeX> complex<float>& operator-= (const complex<_TypeX>& __rhs) {_C_re-=__rhs.real(); _C_im-=__rhs.imag(); return *this;}
|
|
template <class _TypeX> complex<float>& operator*= (const complex<_TypeX>& __rhs) {float __tmp=_C_re*__rhs.real()-_C_im*__rhs.imag(); _C_im=_C_im*__rhs.real()+_C_re*__rhs.imag(); _C_re=__tmp; return *this;}
|
|
template <class _TypeX> complex<float>& operator/= (const complex<_TypeX>&);
|
|
#else /* Have to specialize each one :-( */
|
|
|
|
complex& operator= (const complex &__rhs) {
|
|
_C_re = __rhs.real();
|
|
_C_im = __rhs.imag();
|
|
return *this;
|
|
}
|
|
|
|
complex& operator+= (const complex &__rhs) {
|
|
_C_re += __rhs.real();
|
|
_C_im += __rhs.imag();
|
|
return *this;
|
|
}
|
|
|
|
complex& operator-= (const complex &__rhs) {
|
|
_C_re -= __rhs.real();
|
|
_C_im -= __rhs.imag();
|
|
return *this;
|
|
}
|
|
|
|
complex& operator*= (const complex &__rhs) {
|
|
value_type __tmp = real () * __rhs.real () - imag () * __rhs.imag();
|
|
_C_im = imag () * __rhs.real () + real () * __rhs.imag();
|
|
_C_re = __tmp;
|
|
return *this;
|
|
}
|
|
|
|
complex& operator/= (const complex&);
|
|
|
|
complex& operator= (const complex<double>&);
|
|
complex& operator+= (const complex<double>&);
|
|
complex& operator-= (const complex<double>&);
|
|
complex& operator*= (const complex<double>&);
|
|
complex& operator/= (const complex<double>&);
|
|
|
|
# ifndef _RWSTD_NO_LONG_DOUBLE
|
|
complex& operator= (const complex<long double>&);
|
|
complex& operator+= (const complex<long double>&);
|
|
complex& operator-= (const complex<long double>&);
|
|
complex& operator*= (const complex<long double>&);
|
|
complex& operator/= (const complex<long double>&);
|
|
# endif
|
|
#endif
|
|
|
|
complex<float>& operator= (float);
|
|
complex<float>& operator+= (float);
|
|
complex<float>& operator-= (float);
|
|
complex<float>& operator*= (float);
|
|
complex<float>& operator/= (float);
|
|
|
|
private:
|
|
float _C_re, _C_im;
|
|
};
|
|
|
|
_RWSTD_SPECIALIZED_CLASS
|
|
class complex<double>
|
|
{
|
|
public:
|
|
typedef double value_type;
|
|
|
|
complex (const double& __re=0.0, const double& __im=0.0)
|
|
: _C_re(__re), _C_im(__im)
|
|
{ ; }
|
|
|
|
complex (const complex<float>&);
|
|
|
|
#ifndef _RWSTD_NO_LONG_DOUBLE
|
|
_EXPLICIT complex (const complex<long double>&);
|
|
#endif
|
|
|
|
double imag () const { return _C_im; }
|
|
double real () const { return _C_re; }
|
|
|
|
#ifndef _RWSTD_NO_MEMBER_TEMPLATES
|
|
template <class _TypeX> complex<double>& operator= (const complex<_TypeX>& __rhs) {_C_re=__rhs.real(); _C_im=__rhs.imag(); return *this;}
|
|
template <class _TypeX> complex<double>& operator+= (const complex<_TypeX>& __rhs) {_C_re+=__rhs.real(); _C_im+=__rhs.imag(); return *this;}
|
|
template <class _TypeX> complex<double>& operator-= (const complex<_TypeX>& __rhs) {_C_re-=__rhs.real(); _C_im-=__rhs.imag(); return *this;}
|
|
template <class _TypeX> complex<double>& operator*= (const complex<_TypeX>& __rhs) {double __tmp=_C_re*__rhs.real()-_C_im*__rhs.imag(); _C_im=_C_im*__rhs.real()+_C_re*__rhs.imag(); _C_re=__tmp; return *this;}
|
|
template <class _TypeX> complex<double>& operator/= (const complex<_TypeX>&);
|
|
|
|
#else /* Have to specialize each one :-( */
|
|
|
|
complex<double>& operator= (const complex<float>&);
|
|
complex<double>& operator+= (const complex<float>&);
|
|
complex<double>& operator-= (const complex<float>&);
|
|
complex<double>& operator*= (const complex<float>& __rhs);
|
|
complex<double>& operator/= (const complex<float>&);
|
|
|
|
complex<double>& operator= (const complex<double>& __rhs);
|
|
complex<double>& operator+= (const complex<double>& __rhs);
|
|
complex<double>& operator-= (const complex<double>& __rhs);
|
|
complex<double>& operator*= (const complex<double>& __rhs);
|
|
complex<double>& operator/= (const complex<double>&);
|
|
|
|
# ifndef _RWSTD_NO_LONG_DOUBLE
|
|
complex<double>& operator= (const complex<long double>&);
|
|
complex<double>& operator+= (const complex<long double>&);
|
|
complex<double>& operator-= (const complex<long double>&);
|
|
complex<double>& operator*= (const complex<long double>&);
|
|
complex<double>& operator/= (const complex<long double>&);
|
|
# endif
|
|
#endif
|
|
|
|
complex<double>& operator= (double);
|
|
complex<double>& operator+= (double);
|
|
complex<double>& operator-= (double);
|
|
complex<double>& operator*= (double);
|
|
complex<double>& operator/= (double);
|
|
|
|
|
|
private:
|
|
double _C_re, _C_im;
|
|
};
|
|
|
|
#ifndef _RWSTD_NO_LONG_DOUBLE
|
|
|
|
_RWSTD_SPECIALIZED_CLASS
|
|
class complex<long double>
|
|
{
|
|
public:
|
|
typedef long double value_type;
|
|
|
|
complex (const long double& __re=0.0L, const long double& __im=0.0L)
|
|
: _C_re(__re), _C_im(__im)
|
|
{ ; }
|
|
complex (const complex<float>&);
|
|
complex (const complex<double>&);
|
|
|
|
long double imag () const { return _C_im; }
|
|
long double real () const { return _C_re; }
|
|
|
|
# ifndef _RWSTD_NO_MEMBER_TEMPLATES
|
|
template <class _TypeX> complex<long double>& operator= (const complex<_TypeX>& __rhs) {_C_re=__rhs.real(); _C_im=__rhs.imag(); return *this;}
|
|
template <class _TypeX> complex<long double>& operator+= (const complex<_TypeX>& __rhs) {_C_re+=__rhs.real(); _C_im+=__rhs.imag(); return *this;}
|
|
template <class _TypeX> complex<long double>& operator-= (const complex<_TypeX>& __rhs) {_C_re-=__rhs.real(); _C_im-=__rhs.imag(); return *this;}
|
|
template <class _TypeX> complex<long double>& operator*= (const complex<_TypeX>& __rhs) {long double __tmp=_C_re*__rhs.real()-_C_im*__rhs.imag(); _C_im=_C_im*__rhs.real()+_C_re*__rhs.imag(); _C_re=__tmp; return *this;}
|
|
template <class _TypeX> complex<long double>& operator/= (const complex<_TypeX>&);
|
|
|
|
# else /* Have to specialize each one :-( */
|
|
|
|
complex<long double>& operator= (const complex<float>&);
|
|
complex<long double>& operator+= (const complex<float>&);
|
|
complex<long double>& operator-= (const complex<float>&);
|
|
complex<long double>& operator*= (const complex<float>&);
|
|
complex<long double>& operator/= (const complex<float>&);
|
|
|
|
complex<long double>& operator= (const complex<double>&);
|
|
complex<long double>& operator+= (const complex<double>&);
|
|
complex<long double>& operator-= (const complex<double>&);
|
|
complex<long double>& operator*= (const complex<double>&);
|
|
complex<long double>& operator/= (const complex<double>&);
|
|
|
|
complex<long double>& operator= (const complex<long double>&);
|
|
complex<long double>& operator+= (const complex<long double>&);
|
|
complex<long double>& operator-= (const complex<long double>&);
|
|
complex<long double>& operator*= (const complex<long double>&);
|
|
complex<long double>& operator/= (const complex<long double>&);
|
|
# endif
|
|
|
|
complex<long double>& operator= (long double);
|
|
complex<long double>& operator+= (long double);
|
|
complex<long double>& operator-= (long double);
|
|
complex<long double>& operator*= (long double);
|
|
complex<long double>& operator/= (long double);
|
|
|
|
|
|
private:
|
|
long double _C_re, _C_im;
|
|
};
|
|
#endif
|
|
|
|
|
|
template <class _TypeT>
|
|
class complex
|
|
{
|
|
public:
|
|
typedef _TypeT value_type;
|
|
|
|
complex (const _TypeT& __re=0, const _TypeT& __im=0)
|
|
: _C_re(__re), _C_im(__im)
|
|
{ ; }
|
|
|
|
_TypeT imag () const { return _C_im; }
|
|
_TypeT real () const { return _C_re; }
|
|
|
|
#ifndef _RWSTD_NO_MEMBER_TEMPLATES
|
|
template <class _TypeX> complex (const complex<_TypeX>& __rhs) {_C_re=__rhs.real(); _C_im=__rhs.imag();}
|
|
|
|
template <class _TypeX> complex<_TypeT>& operator= (const complex<_TypeX>& __rhs) {_C_re=__rhs.real(); _C_im=__rhs.imag(); return *this;}
|
|
template <class _TypeX> complex<_TypeT>& operator+= (const complex<_TypeX>& __rhs) {_C_re+=__rhs.real(); _C_im+=__rhs.imag(); return *this;}
|
|
template <class _TypeX> complex<_TypeT>& operator-= (const complex<_TypeX>& __rhs) {_C_re-=__rhs.real(); _C_im-=__rhs.imag(); return *this;}
|
|
template <class _TypeX> complex<_TypeT>& operator*= (const complex<_TypeX>& __rhs) {_TypeT __tmp=_C_re*__rhs.real()-_C_im*__rhs.imag(); _C_im=_C_im*__rhs.real()+_C_re*__rhs.imag(); _C_re=__tmp; return *this;}
|
|
template <class _TypeX> complex<_TypeT>& operator/= (const complex<_TypeX>&);
|
|
#endif
|
|
|
|
complex<_TypeT>& operator= (const _TypeT&);
|
|
complex<_TypeT>& operator+= (const _TypeT&);
|
|
complex<_TypeT>& operator-= (const _TypeT&);
|
|
complex<_TypeT>& operator*= (const _TypeT&);
|
|
complex<_TypeT>& operator/= (const _TypeT&);
|
|
|
|
private:
|
|
_TypeT _C_re, _C_im;
|
|
};
|
|
|
|
//
|
|
// complex<float> specializations.
|
|
//
|
|
|
|
inline
|
|
complex<float>::complex (const complex<double>& cd)
|
|
{
|
|
_C_re = _RWSTD_STATIC_CAST(float,cd.real());
|
|
_C_im = _RWSTD_STATIC_CAST(float,cd.imag());
|
|
}
|
|
|
|
#ifndef _RWSTD_NO_LONG_DOUBLE
|
|
inline
|
|
complex<float>::complex (const complex<long double>& cld)
|
|
{
|
|
_C_re = _RWSTD_STATIC_CAST(float,cld.real());
|
|
_C_im = _RWSTD_STATIC_CAST(float,cld.imag());
|
|
}
|
|
#endif
|
|
|
|
inline complex<float>&
|
|
complex<float>::operator= (float __rhs)
|
|
{
|
|
_C_re = __rhs; _C_im = 0.0; return *this;
|
|
}
|
|
|
|
inline complex<float>&
|
|
complex<float>::operator+= (float __rhs)
|
|
{
|
|
_C_re += __rhs; return *this;
|
|
}
|
|
|
|
inline complex<float>&
|
|
complex<float>::operator-= (float __rhs)
|
|
{
|
|
_C_re -= __rhs; return *this;
|
|
}
|
|
|
|
inline complex<float>&
|
|
complex<float>::operator*= (float __rhs)
|
|
{
|
|
float __tmp = _C_re*__rhs;
|
|
_C_im = _C_im*__rhs;
|
|
_C_re = __tmp;
|
|
return *this;
|
|
}
|
|
|
|
|
|
#ifdef _RWSTD_NO_MEMBER_TEMPLATES
|
|
|
|
inline complex<float>&
|
|
complex<float>::operator= (const complex<double>& __rhs)
|
|
{
|
|
_C_re = _RWSTD_STATIC_CAST(float,__rhs.real());
|
|
_C_im = _RWSTD_STATIC_CAST(float,__rhs.imag());
|
|
return *this;
|
|
}
|
|
|
|
inline complex<float>&
|
|
complex<float>::operator+= (const complex<double>& __rhs)
|
|
{
|
|
_C_re += _RWSTD_STATIC_CAST(float,__rhs.real());
|
|
_C_im += _RWSTD_STATIC_CAST(float,__rhs.imag());
|
|
return *this;
|
|
}
|
|
|
|
inline complex<float>&
|
|
complex<float>::operator-= (const complex<double>& __rhs)
|
|
{
|
|
_C_re -= _RWSTD_STATIC_CAST(float,__rhs.real());
|
|
_C_im -= _RWSTD_STATIC_CAST(float,__rhs.imag());
|
|
return *this;
|
|
}
|
|
|
|
inline complex<float>&
|
|
complex<float>::operator*= (const complex<double>& __rhs)
|
|
{
|
|
float __tmp = _C_re*_RWSTD_STATIC_CAST(float,__rhs.real())-
|
|
_C_im*_RWSTD_STATIC_CAST(float,__rhs.imag());
|
|
_C_im = _C_im*_RWSTD_STATIC_CAST(float,__rhs.real())+
|
|
_C_re*_RWSTD_STATIC_CAST(float,__rhs.imag());
|
|
_C_re = __tmp;
|
|
return *this;
|
|
}
|
|
|
|
# ifndef _RWSTD_NO_LONG_DOUBLE
|
|
inline complex<float>&
|
|
complex<float>::operator= (const complex<long double>& __rhs)
|
|
{
|
|
_C_re = _RWSTD_STATIC_CAST(float,__rhs.real());
|
|
_C_im = _RWSTD_STATIC_CAST(float,__rhs.imag());
|
|
return *this;
|
|
}
|
|
|
|
inline complex<float>&
|
|
complex<float>::operator+= (const complex<long double>& __rhs)
|
|
{
|
|
_C_re += _RWSTD_STATIC_CAST(float,__rhs.real());
|
|
_C_im += _RWSTD_STATIC_CAST(float,__rhs.imag());
|
|
return *this;
|
|
}
|
|
|
|
inline complex<float>&
|
|
complex<float>::operator-= (const complex<long double>& __rhs)
|
|
{
|
|
_C_re -= _RWSTD_STATIC_CAST(float,__rhs.real());
|
|
_C_im -= _RWSTD_STATIC_CAST(float,__rhs.imag());
|
|
return *this;
|
|
}
|
|
|
|
inline complex<float>&
|
|
complex<float>::operator*= (const complex<long double>& __rhs)
|
|
{
|
|
float __tmp = _C_re*_RWSTD_STATIC_CAST(float,__rhs.real())-
|
|
_C_im*_RWSTD_STATIC_CAST(float,__rhs.imag());
|
|
_C_im = _C_im*_RWSTD_STATIC_CAST(float,__rhs.real())+
|
|
_C_re*_RWSTD_STATIC_CAST(float,__rhs.imag());
|
|
_C_re = __tmp;
|
|
return *this;
|
|
}
|
|
# endif
|
|
#endif /* _RWSTD_NO_MEMBER_TEMPLATES */
|
|
//
|
|
// complex<double> specializations.
|
|
//
|
|
inline
|
|
complex<double>::complex (const complex<float>& cf)
|
|
: _C_re(cf.real()), _C_im(cf.imag()) {}
|
|
|
|
#ifndef _RWSTD_NO_LONG_DOUBLE
|
|
inline
|
|
complex<double>::complex (const complex<long double>& cld)
|
|
: _C_re(_RWSTD_STATIC_CAST(double,cld.real())),
|
|
_C_im(_RWSTD_STATIC_CAST(double,cld.imag())) {}
|
|
#endif
|
|
|
|
inline complex<double>&
|
|
complex<double>::operator= (double __rhs)
|
|
{
|
|
_C_re = __rhs; _C_im = 0.0; return *this;
|
|
}
|
|
|
|
inline complex<double>&
|
|
complex<double>::operator+= (double __rhs)
|
|
{
|
|
_C_re += __rhs; return *this;
|
|
}
|
|
|
|
inline complex<double>&
|
|
complex<double>::operator-= (double __rhs)
|
|
{
|
|
_C_re -= __rhs; return *this;
|
|
}
|
|
|
|
inline complex<double>&
|
|
complex<double>::operator*= (double __rhs)
|
|
{
|
|
double __tmp = _C_re*__rhs;
|
|
_C_im = _C_im*__rhs;
|
|
_C_re = __tmp;
|
|
return *this;
|
|
}
|
|
|
|
|
|
#ifdef _RWSTD_NO_MEMBER_TEMPLATES
|
|
inline complex<double>&
|
|
complex<double>::operator= (const complex<float>& __rhs)
|
|
{
|
|
_C_re = __rhs.real(); _C_im = __rhs.imag(); return *this;
|
|
}
|
|
|
|
inline complex<double>&
|
|
complex<double>::operator+= (const complex<float>& __rhs)
|
|
{
|
|
_C_re += __rhs.real(); _C_im += __rhs.imag(); return *this;
|
|
}
|
|
|
|
inline complex<double>&
|
|
complex<double>::operator-= (const complex<float>& __rhs)
|
|
{
|
|
_C_re -= __rhs.real(); _C_im -= __rhs.imag(); return *this;
|
|
}
|
|
|
|
inline complex<double>&
|
|
complex<double>::operator*= (const complex<float>& __rhs)
|
|
{
|
|
double __tmp = _C_re*__rhs.real()-_C_im*__rhs.imag();
|
|
_C_im = _C_im*__rhs.real()+_C_re*__rhs.imag();
|
|
_C_re = __tmp;
|
|
return *this;
|
|
}
|
|
|
|
inline complex<double>&
|
|
complex<double>::operator= (const complex<double>& __rhs)
|
|
{
|
|
_C_re = __rhs.real(); _C_im = __rhs.imag(); return *this;
|
|
}
|
|
|
|
inline complex<double>&
|
|
complex<double>::operator+= (const complex<double>& __rhs)
|
|
{
|
|
_C_re += __rhs.real(); _C_im += __rhs.imag(); return *this;
|
|
}
|
|
|
|
inline complex<double>&
|
|
complex<double>::operator-= (const complex<double>& __rhs)
|
|
{
|
|
_C_re -= __rhs.real(); _C_im -= __rhs.imag(); return *this;
|
|
}
|
|
|
|
inline complex<double>&
|
|
complex<double>::operator*= (const complex<double>& __rhs)
|
|
{
|
|
double __tmp = _C_re*__rhs.real()-_C_im*__rhs.imag();
|
|
_C_im = _C_im*__rhs.real()+_C_re*__rhs.imag();
|
|
_C_re = __tmp;
|
|
return *this;
|
|
}
|
|
|
|
|
|
# ifndef _RWSTD_NO_LONG_DOUBLE
|
|
inline complex<double>&
|
|
complex<double>::operator= (const complex<long double>& __rhs)
|
|
{
|
|
_C_re = _RWSTD_STATIC_CAST(double,__rhs.real());
|
|
_C_im = _RWSTD_STATIC_CAST(double,__rhs.imag());
|
|
return *this;
|
|
}
|
|
|
|
inline complex<double>&
|
|
complex<double>::operator+= (const complex<long double>& __rhs)
|
|
{
|
|
_C_re += _RWSTD_STATIC_CAST(double,__rhs.real());
|
|
_C_im += _RWSTD_STATIC_CAST(double,__rhs.imag());
|
|
return *this;
|
|
}
|
|
|
|
inline complex<double>&
|
|
complex<double>::operator-= (const complex<long double>& __rhs)
|
|
{
|
|
_C_re -= _RWSTD_STATIC_CAST(double,__rhs.real());
|
|
_C_im -= _RWSTD_STATIC_CAST(double,__rhs.imag());
|
|
return *this;
|
|
}
|
|
|
|
inline complex<double>&
|
|
complex<double>::operator*= (const complex<long double>& __rhs)
|
|
{
|
|
double __tmp = _C_re*_RWSTD_STATIC_CAST(double,__rhs.real())-
|
|
_C_im*_RWSTD_STATIC_CAST(double,__rhs.imag());
|
|
_C_im = _C_im*_RWSTD_STATIC_CAST(double,__rhs.real())+
|
|
_C_re*_RWSTD_STATIC_CAST(double,__rhs.imag());
|
|
_C_re = __tmp;
|
|
return *this;
|
|
}
|
|
# endif
|
|
#endif /* _RWSTD_NO_MEMBER_TEMPLATES */
|
|
|
|
//
|
|
// complex<long double> specializations.
|
|
//
|
|
|
|
#ifndef _RWSTD_NO_LONG_DOUBLE
|
|
inline
|
|
complex<long double>::complex (const complex<float>& cf)
|
|
: _C_re(cf.real()), _C_im(cf.imag()) {}
|
|
|
|
inline
|
|
complex<long double>::complex (const complex<double>& cd)
|
|
: _C_re(cd.real()), _C_im(cd.imag()) {}
|
|
|
|
inline complex<long double>&
|
|
complex<long double>::operator+= (long double __rhs)
|
|
{
|
|
_C_re += __rhs; return *this;
|
|
}
|
|
|
|
inline complex<long double>&
|
|
complex<long double>::operator= (long double __rhs)
|
|
{
|
|
_C_re = __rhs; _C_im = 0.0; return *this;
|
|
}
|
|
|
|
inline complex<long double>&
|
|
complex<long double>::operator-= (long double __rhs)
|
|
{
|
|
_C_re -= __rhs; return *this;
|
|
}
|
|
|
|
inline complex<long double>&
|
|
complex<long double>::operator*= (long double __rhs)
|
|
{
|
|
long double __tmp = _C_re*__rhs;
|
|
_C_im = _C_im*__rhs;
|
|
_C_re = __tmp;
|
|
return *this;
|
|
}
|
|
|
|
|
|
# ifdef _RWSTD_NO_MEMBER_TEMPLATES
|
|
inline complex<long double>&
|
|
complex<long double>::operator= (const complex<float>& __rhs)
|
|
{
|
|
_C_re = __rhs.real(); _C_im = __rhs.imag(); return *this;
|
|
}
|
|
|
|
inline complex<long double>&
|
|
complex<long double>::operator+= (const complex<float>& __rhs)
|
|
{
|
|
_C_re += __rhs.real(); _C_im += __rhs.imag(); return *this;
|
|
}
|
|
|
|
inline complex<long double>&
|
|
complex<long double>::operator-= (const complex<float>& __rhs)
|
|
{
|
|
_C_re -= __rhs.real(); _C_im -= __rhs.imag(); return *this;
|
|
}
|
|
|
|
inline complex<long double>&
|
|
complex<long double>::operator*= (const complex<float>& __rhs)
|
|
{
|
|
long double __tmp = _C_re*__rhs.real()-_C_im*__rhs.imag();
|
|
_C_im = _C_im*__rhs.real()+_C_re*__rhs.imag();
|
|
_C_re = __tmp;
|
|
return *this;
|
|
}
|
|
|
|
inline complex<long double>&
|
|
complex<long double>::operator= (const complex<double>& __rhs)
|
|
{
|
|
_C_re = __rhs.real(); _C_im = __rhs.imag(); return *this;
|
|
}
|
|
|
|
inline complex<long double>&
|
|
complex<long double>::operator+= (const complex<double>& __rhs)
|
|
{
|
|
_C_re += __rhs.real(); _C_im += __rhs.imag(); return *this;
|
|
}
|
|
|
|
inline complex<long double>&
|
|
complex<long double>::operator-= (const complex<double>& __rhs)
|
|
{
|
|
_C_re -= __rhs.real(); _C_im -= __rhs.imag(); return *this;
|
|
}
|
|
|
|
inline complex<long double>&
|
|
complex<long double>::operator*= (const complex<double>& __rhs)
|
|
{
|
|
long double __tmp = _C_re*__rhs.real()-_C_im*__rhs.imag();
|
|
_C_im = _C_im*__rhs.real()+_C_re*__rhs.imag();
|
|
_C_re = __tmp;
|
|
return *this;
|
|
}
|
|
|
|
inline complex<long double>&
|
|
complex<long double>::operator= (const complex<long double>& __rhs)
|
|
{
|
|
_C_re = __rhs.real(); _C_im = __rhs.imag(); return *this;
|
|
}
|
|
|
|
inline complex<long double>&
|
|
complex<long double>::operator+= (const complex<long double>& __rhs)
|
|
{
|
|
_C_re += __rhs.real(); _C_im += __rhs.imag(); return *this;
|
|
}
|
|
|
|
inline complex<long double>&
|
|
complex<long double>::operator-= (const complex<long double>& __rhs)
|
|
{
|
|
_C_re -= __rhs.real(); _C_im -= __rhs.imag(); return *this;
|
|
}
|
|
|
|
inline complex<long double>&
|
|
complex<long double>::operator*= (const complex<long double>& __rhs)
|
|
{
|
|
long double __tmp = _C_re*__rhs.real()-_C_im*__rhs.imag();
|
|
_C_im = _C_im*__rhs.real()+_C_re*__rhs.imag();
|
|
_C_re = __tmp;
|
|
return *this;
|
|
}
|
|
# endif
|
|
#endif /* _RWSTD_NO_MEMBER_TEMPLATES */
|
|
|
|
#ifndef _RWSTD_NO_MEMBER_TEMPLATES
|
|
template <class _TypeT>
|
|
template <class _TypeX>
|
|
complex<_TypeT>&
|
|
complex<_TypeT>::operator/= (const complex<_TypeX>& __rhs)
|
|
{
|
|
_TypeT denom = __rhs.real()*__rhs.real() + __rhs.imag()*__rhs.imag();
|
|
_TypeT re = (_C_re*__rhs.real()+_C_im*__rhs.imag())/denom;
|
|
_TypeT im = (__rhs.real()*_C_im-_C_re*__rhs.imag())/denom;
|
|
_C_re = re;
|
|
_C_im = im;
|
|
return *this;
|
|
}
|
|
|
|
template <class _TypeX>
|
|
inline complex<float>&
|
|
complex<float>::operator/= (const complex<_TypeX>& __rhs)
|
|
{
|
|
float denom = __rhs.real()*__rhs.real() + __rhs.imag()*__rhs.imag();
|
|
float re = (_C_re*__rhs.real()+_C_im*__rhs.imag())/denom;
|
|
float im = (__rhs.real()*_C_im-_C_re*__rhs.imag())/denom;
|
|
_C_re = re;
|
|
_C_im = im;
|
|
return *this;
|
|
}
|
|
|
|
template <class _TypeX>
|
|
inline complex<double>&
|
|
complex<double>::operator/= (const complex<_TypeX>& __rhs)
|
|
{
|
|
double denom = __rhs.real()*__rhs.real() + __rhs.imag()*__rhs.imag();
|
|
double re = (_C_re*__rhs.real()+_C_im*__rhs.imag())/denom;
|
|
double im = (__rhs.real()*_C_im-_C_re*__rhs.imag())/denom;
|
|
_C_re = re;
|
|
_C_im = im;
|
|
return *this;
|
|
}
|
|
|
|
# ifndef _RWSTD_NO_LONG_DOUBLE
|
|
template <class _TypeX>
|
|
inline complex<long double>&
|
|
complex<long double>::operator/= (const complex<_TypeX>& __rhs)
|
|
{
|
|
long double denom = __rhs.real()*__rhs.real() + __rhs.imag()*__rhs.imag();
|
|
long double re = (_C_re*__rhs.real()+_C_im*__rhs.imag())/denom;
|
|
long double im = (__rhs.real()*_C_im-_C_re*__rhs.imag())/denom;
|
|
_C_re = re;
|
|
_C_im = im;
|
|
return *this;
|
|
}
|
|
# endif
|
|
|
|
#else /* No member function templates, have to specialize :-( */
|
|
|
|
inline complex<float>&
|
|
complex<float>::operator/= (const complex<float>& __rhs)
|
|
{
|
|
float denom = __rhs.real()*__rhs.real() + __rhs.imag()*__rhs.imag();
|
|
float re = (_C_re*__rhs.real()+_C_im*__rhs.imag())/denom;
|
|
float im = (__rhs.real()*_C_im-_C_re*__rhs.imag())/denom;
|
|
_C_re = re;
|
|
_C_im = im;
|
|
return *this;
|
|
}
|
|
|
|
inline complex<float>&
|
|
complex<float>::operator/= (const complex<double>& __rhs)
|
|
{
|
|
float denom = _RWSTD_STATIC_CAST(float,__rhs.real())*
|
|
_RWSTD_STATIC_CAST(float,__rhs.real()) +
|
|
_RWSTD_STATIC_CAST(float,__rhs.imag())*
|
|
_RWSTD_STATIC_CAST(float,__rhs.imag());
|
|
float re = (_C_re*_RWSTD_STATIC_CAST(float,__rhs.real())+
|
|
_C_im*_RWSTD_STATIC_CAST(float,__rhs.imag()))/denom;
|
|
float im = (_RWSTD_STATIC_CAST(float,__rhs.real())*_C_im-_C_re*
|
|
_RWSTD_STATIC_CAST(float,__rhs.imag()))/denom;
|
|
_C_re = re;
|
|
_C_im = im;
|
|
return *this;
|
|
}
|
|
|
|
# ifndef _RWSTD_NO_LONG_DOUBLE
|
|
inline complex<float>&
|
|
complex<float>::operator/= (const complex<long double>& __rhs)
|
|
{
|
|
float denom = _RWSTD_STATIC_CAST(float,__rhs.real())*
|
|
_RWSTD_STATIC_CAST(float,__rhs.real()) +
|
|
_RWSTD_STATIC_CAST(float,__rhs.imag())*
|
|
_RWSTD_STATIC_CAST(float,__rhs.imag());
|
|
float re = (_C_re*_RWSTD_STATIC_CAST(float,__rhs.real())+
|
|
_C_im*_RWSTD_STATIC_CAST(float,__rhs.imag()))/denom;
|
|
float im = (_RWSTD_STATIC_CAST(float,__rhs.real())*_C_im-
|
|
_C_re*_RWSTD_STATIC_CAST(float,__rhs.imag()))/denom;
|
|
_C_re = re;
|
|
_C_im = im;
|
|
return *this;
|
|
}
|
|
# endif
|
|
|
|
inline complex<double>&
|
|
complex<double>::operator/= (const complex<float>& __rhs)
|
|
{
|
|
double denom = __rhs.real()*__rhs.real() + __rhs.imag()*__rhs.imag();
|
|
double re = (_C_re*__rhs.real()+_C_im*__rhs.imag())/denom;
|
|
double im = (__rhs.real()*_C_im-_C_re*__rhs.imag())/denom;
|
|
_C_re = re;
|
|
_C_im = im;
|
|
return *this;
|
|
}
|
|
|
|
inline complex<double>&
|
|
complex<double>::operator/= (const complex<double>& __rhs)
|
|
{
|
|
double denom = __rhs.real()*__rhs.real() + __rhs.imag()*__rhs.imag();
|
|
double re = (_C_re*__rhs.real()+_C_im*__rhs.imag())/denom;
|
|
double im = (__rhs.real()*_C_im-_C_re*__rhs.imag())/denom;
|
|
_C_re = re;
|
|
_C_im = im;
|
|
return *this;
|
|
}
|
|
|
|
#ifndef _RWSTD_NO_LONG_DOUBLE
|
|
inline complex<double>&
|
|
complex<double>::operator/= (const complex<long double>& __rhs)
|
|
{
|
|
double denom = _RWSTD_STATIC_CAST(double,__rhs.real())*
|
|
_RWSTD_STATIC_CAST(double,__rhs.real()) +
|
|
_RWSTD_STATIC_CAST(double,__rhs.imag())*
|
|
_RWSTD_STATIC_CAST(double,__rhs.imag());
|
|
double re = (_C_re*_RWSTD_STATIC_CAST(double,__rhs.real())+
|
|
_C_im*_RWSTD_STATIC_CAST(double,__rhs.imag()))/denom;
|
|
double im = (_RWSTD_STATIC_CAST(double,__rhs.real())*_C_im-
|
|
_C_re*_RWSTD_STATIC_CAST(double,__rhs.imag()))/denom;
|
|
_C_re = re;
|
|
_C_im = im;
|
|
return *this;
|
|
}
|
|
#endif
|
|
|
|
#ifndef _RWSTD_NO_LONG_DOUBLE
|
|
inline complex<long double>&
|
|
complex<long double>::operator/= (const complex<float>& __rhs)
|
|
{
|
|
long double denom = __rhs.real()*__rhs.real() + __rhs.imag()*__rhs.imag();
|
|
long double re = (_C_re*__rhs.real()+_C_im*__rhs.imag())/denom;
|
|
long double im = (__rhs.real()*_C_im-_C_re*__rhs.imag())/denom;
|
|
_C_re = re;
|
|
_C_im = im;
|
|
return *this;
|
|
}
|
|
|
|
inline complex<long double>&
|
|
complex<long double>::operator/= (const complex<double>& __rhs)
|
|
{
|
|
long double denom = __rhs.real()*__rhs.real() + __rhs.imag()*__rhs.imag();
|
|
long double re = (_C_re*__rhs.real()+_C_im*__rhs.imag())/denom;
|
|
long double im = (__rhs.real()*_C_im-_C_re*__rhs.imag())/denom;
|
|
_C_re = re;
|
|
_C_im = im;
|
|
return *this;
|
|
}
|
|
|
|
inline complex<long double>&
|
|
complex<long double>::operator/= (const complex<long double>& __rhs)
|
|
{
|
|
long double denom = __rhs.real()*__rhs.real() + __rhs.imag()*__rhs.imag();
|
|
long double re = (_C_re*__rhs.real()+_C_im*__rhs.imag())/denom;
|
|
long double im = (__rhs.real()*_C_im-_C_re*__rhs.imag())/denom;
|
|
_C_re = re;
|
|
_C_im = im;
|
|
return *this;
|
|
}
|
|
#endif
|
|
#endif
|
|
|
|
inline complex<float>&
|
|
complex<float>::operator/= (float __rhs)
|
|
{
|
|
float denom = __rhs*__rhs;
|
|
float re = (_C_re*__rhs)/denom;
|
|
float im = (__rhs*_C_im)/denom;
|
|
_C_re = re;
|
|
_C_im = im;
|
|
return *this;
|
|
}
|
|
|
|
inline complex<double>&
|
|
complex<double>::operator/= (double __rhs)
|
|
{
|
|
double denom = __rhs*__rhs;
|
|
double re = (_C_re*__rhs)/denom;
|
|
double im = (__rhs*_C_im)/denom;
|
|
_C_re = re;
|
|
_C_im = im;
|
|
return *this;
|
|
}
|
|
|
|
|
|
#ifndef _RWSTD_NO_LONG_DOUBLE
|
|
inline complex<long double>&
|
|
complex<long double>::operator/= (long double __rhs)
|
|
{
|
|
long double denom = __rhs*__rhs;
|
|
long double re = (_C_re*__rhs)/denom;
|
|
long double im = (__rhs*_C_im)/denom;
|
|
_C_re = re;
|
|
_C_im = im;
|
|
return *this;
|
|
}
|
|
#endif
|
|
|
|
|
|
//
|
|
// complex non-member operations
|
|
//
|
|
|
|
template <class _TypeT>
|
|
inline complex<_TypeT> operator+ (const complex<_TypeT>& __lhs, const complex<_TypeT>& __rhs)
|
|
{
|
|
complex<_TypeT> __tmp = __lhs; return __tmp += __rhs;
|
|
}
|
|
|
|
template <class _TypeT>
|
|
inline complex<_TypeT> operator+ (const complex<_TypeT>& __lhs, const _TypeT& __rhs)
|
|
{
|
|
return complex<_TypeT>(__rhs+__lhs.real(), __lhs.imag());
|
|
}
|
|
|
|
template <class _TypeT>
|
|
inline complex<_TypeT> operator+ (const _TypeT& __lhs, const complex<_TypeT>& __rhs)
|
|
{
|
|
return complex<_TypeT>(__lhs+__rhs.real(), __rhs.imag());
|
|
}
|
|
|
|
template <class _TypeT>
|
|
inline complex<_TypeT> operator- (const complex<_TypeT>& __lhs, const complex<_TypeT>& __rhs)
|
|
{
|
|
complex<_TypeT> __tmp = __lhs; return __tmp -= __rhs;
|
|
}
|
|
|
|
template <class _TypeT>
|
|
inline complex<_TypeT> operator- (const complex<_TypeT>& __lhs, const _TypeT& __rhs)
|
|
{
|
|
return complex<_TypeT>(__lhs.real()-__rhs, __lhs.imag());
|
|
}
|
|
|
|
template <class _TypeT>
|
|
inline complex<_TypeT> operator- (const _TypeT& __lhs, const complex<_TypeT>& __rhs)
|
|
{
|
|
return complex<_TypeT>(__lhs-__rhs.real(), -__rhs.imag());
|
|
}
|
|
|
|
template <class _TypeT>
|
|
inline complex<_TypeT> operator* (const complex<_TypeT>& __lhs, const complex<_TypeT>& __rhs)
|
|
{
|
|
complex<_TypeT> __tmp = __lhs; return __tmp *= __rhs;
|
|
}
|
|
|
|
template <class _TypeT>
|
|
inline complex<_TypeT> operator* (const complex<_TypeT>& __lhs, const _TypeT& __rhs)
|
|
{
|
|
return complex<_TypeT>(__rhs*__lhs.real(), __rhs*__lhs.imag());
|
|
}
|
|
|
|
template <class _TypeT>
|
|
inline complex<_TypeT> operator* (const _TypeT& __lhs, const complex<_TypeT>& __rhs)
|
|
{
|
|
return complex<_TypeT>(__lhs*__rhs.real(), __lhs*__rhs.imag());
|
|
}
|
|
|
|
template <class _TypeT>
|
|
inline complex<_TypeT> operator/ (const complex<_TypeT>& __lhs, const complex<_TypeT>& __rhs)
|
|
{
|
|
complex<_TypeT> __tmp = __lhs; return __tmp /= __rhs;
|
|
}
|
|
|
|
template <class _TypeT>
|
|
inline complex<_TypeT> operator/ (const complex<_TypeT>& __lhs, const _TypeT& __rhs)
|
|
{
|
|
return complex<_TypeT>(__lhs.real()/__rhs, __lhs.imag()/__rhs);
|
|
}
|
|
|
|
template <class _TypeT>
|
|
inline complex<_TypeT> operator/ (const _TypeT& __lhs, const complex<_TypeT>& __rhs)
|
|
{
|
|
register _TypeT denom = __rhs.real()*__rhs.real() + __rhs.imag()*__rhs.imag();
|
|
return complex<_TypeT>(__lhs*__rhs.real()/denom,(-__lhs*__rhs.imag())/denom);
|
|
}
|
|
|
|
template <class _TypeT>
|
|
inline complex<_TypeT> operator+ (const complex<_TypeT>& __lhs) { return __lhs; }
|
|
|
|
template <class _TypeT>
|
|
inline complex<_TypeT> operator- (const complex<_TypeT>& __lhs)
|
|
{
|
|
return complex<_TypeT>(-__lhs.real(), -__lhs.imag());
|
|
}
|
|
|
|
template <class _TypeT>
|
|
inline bool operator== (const complex<_TypeT>& __lhs, const complex<_TypeT>& __rhs)
|
|
{
|
|
return __lhs.real() == __rhs.real() && __lhs.imag() == __rhs.imag();
|
|
}
|
|
|
|
template <class _TypeT>
|
|
inline bool operator== (const _TypeT& __lhs, const complex<_TypeT>& __rhs)
|
|
{
|
|
return __lhs == __rhs.real() && __rhs.imag() == 0;
|
|
}
|
|
|
|
template <class _TypeT>
|
|
inline bool operator== (const complex<_TypeT>& __lhs, const _TypeT& __rhs)
|
|
{
|
|
return __lhs.real() == __rhs && __lhs.imag() == 0;
|
|
}
|
|
|
|
template <class _TypeT>
|
|
inline bool operator!= (const complex<_TypeT>& __lhs,
|
|
const complex<_TypeT>& __rhs)
|
|
{
|
|
return __lhs.real() != __rhs.real() || __lhs.imag() != __rhs.imag();
|
|
}
|
|
|
|
template <class _TypeT>
|
|
inline bool operator!= (const _TypeT& __lhs, const complex<_TypeT>& __rhs)
|
|
{
|
|
return __lhs != __rhs.real() || __rhs.imag() != 0;
|
|
}
|
|
|
|
template <class _TypeT>
|
|
inline bool operator!= (const complex<_TypeT>& __lhs, const _TypeT& __rhs)
|
|
{
|
|
return __lhs.real() != __rhs || __lhs.imag() != 0;
|
|
}
|
|
|
|
//
|
|
// complex value operations
|
|
//
|
|
|
|
template<class _TypeT>
|
|
inline _TypeT real (const complex<_TypeT>& __a) { return __a.real(); }
|
|
|
|
template<class _TypeT>
|
|
inline _TypeT imag (const complex<_TypeT>& __a) { return __a.imag(); }
|
|
|
|
template <class _TypeT>
|
|
inline _TypeT norm (const complex<_TypeT>& __a)
|
|
{
|
|
return __a.real()*__a.real() + __a.imag()*__a.imag();
|
|
}
|
|
|
|
template <class _TypeT>
|
|
inline _TypeT abs (const complex<_TypeT>& __a) { return (_RWSTD_C::sqrt(norm(__a))); }
|
|
|
|
//
|
|
// We guarantee that arg(complex<_TypeT>(0,0)) == 0.
|
|
//
|
|
|
|
template <class _TypeT>
|
|
inline _TypeT arg (const complex<_TypeT>& __a)
|
|
{
|
|
return __a == complex<_TypeT>(0,0) ? _TypeT(0) : _RWSTD_C::atan2(__a.imag(), __a.real());
|
|
}
|
|
|
|
template <class _TypeT>
|
|
complex<_TypeT> conj (const complex<_TypeT>& __a)
|
|
{
|
|
return complex<_TypeT>(__a.real(), -__a.imag());
|
|
}
|
|
|
|
template <class _TypeT>
|
|
inline complex<_TypeT> polar (const _TypeT& __r, const _TypeT& theta = 0)
|
|
{
|
|
return complex<_TypeT>(__r*_RWSTD_C::cos(theta), __r*_RWSTD_C::sin(theta));
|
|
}
|
|
|
|
//
|
|
// transcendentals
|
|
//
|
|
|
|
//
|
|
// complex<_TypeT> cosine of complex<_TypeT> number __a
|
|
// cos (__a) = cos u * cosh v - i * sin u * sinh v
|
|
//
|
|
|
|
template <class _TypeT>
|
|
inline complex<_TypeT> cos (const complex<_TypeT>& __a)
|
|
{
|
|
return complex<_TypeT>(_RWSTD_C::cos(__a.real())*_RWSTD_C::cosh(__a.imag()),
|
|
-_RWSTD_C::sin(__a.real())*_RWSTD_C::sinh(__a.imag()));
|
|
}
|
|
|
|
//
|
|
// complex<_TypeT> hyperbolic cosine of complex<_TypeT> number __a
|
|
// cosh (__a) = cosh u * cosv + i * sinh u * sin v
|
|
//
|
|
|
|
template <class _TypeT>
|
|
inline complex<_TypeT> cosh (const complex<_TypeT>& __a)
|
|
{
|
|
return complex<_TypeT>(_RWSTD_C::cosh(__a.real())*_RWSTD_C::cos(__a.imag()),
|
|
_RWSTD_C::sinh(__a.real())*_RWSTD_C::sin(__a.imag()));
|
|
}
|
|
|
|
//
|
|
// complex<_TypeT> exponential of complex<_TypeT> number __a
|
|
// exp (__a) = exp(u) * (cos v + i * sin v)
|
|
//
|
|
|
|
template <class _TypeT>
|
|
inline complex<_TypeT> exp (const complex<_TypeT>& __a)
|
|
{
|
|
_TypeT __e = _RWSTD_C::exp(__a.real());
|
|
return complex<_TypeT>(__e*_RWSTD_C::cos(__a.imag()), __e*_RWSTD_C::sin(__a.imag()));
|
|
}
|
|
|
|
//
|
|
// complex<_TypeT> natural log of complex<_TypeT> number __a
|
|
// log(__a) = log(__r) + i * theta
|
|
//
|
|
|
|
template <class _TypeT>
|
|
inline complex<_TypeT> log (const complex<_TypeT>& __a)
|
|
{
|
|
return complex<_TypeT>(_RWSTD_C::log(abs(__a)), arg(__a));
|
|
}
|
|
|
|
template <class _TypeT>
|
|
complex<_TypeT> log10 (const complex<_TypeT>& __a);
|
|
|
|
//
|
|
// For all the power functions:
|
|
//
|
|
// 0**0 == 1
|
|
// 0**x == 0 for x != 0
|
|
//
|
|
|
|
//
|
|
// complex<_TypeT> number __a raised to an integer power __n
|
|
//
|
|
// __a**__n = __r**__n * (cos(__n theta) + i sin (__n theta))
|
|
//
|
|
|
|
template <class _TypeT>
|
|
inline complex<_TypeT> pow (const complex<_TypeT>& __a, int __n)
|
|
{
|
|
if (__a == complex<_TypeT>(0,0))
|
|
{
|
|
if (__n == 0)
|
|
return complex<_TypeT>(1,0);
|
|
else
|
|
return complex<_TypeT>(0,0);
|
|
}
|
|
|
|
if (__a.imag() == 0)
|
|
{
|
|
if (__a.real() < 0)
|
|
return pow(__a, complex<_TypeT>(__n,0));
|
|
else
|
|
#ifndef _RWSTD_NO_OVERLOAD_C_POW
|
|
return complex<_TypeT>(_RWSTD_C::pow(__a.real(),_TypeT(__n)), 0);
|
|
#else
|
|
return complex<_TypeT>(_RWSTD_C::pow(double(__a.real()),double(__n)), 0);
|
|
#endif /* _RWSTD_NO_OVERLOAD_C_POW */
|
|
}
|
|
|
|
#ifndef _RWSTD_NO_OVERLOAD_C_POW
|
|
register _TypeT __r = _RWSTD_C::pow(_TypeT(abs(__a)), _TypeT(__n));
|
|
#else
|
|
register _TypeT __r = _RWSTD_C::pow(double(abs(__a)), double(__n));
|
|
#endif
|
|
|
|
register _TypeT th = _TypeT(__n) * arg(__a);
|
|
|
|
return complex<_TypeT>(__r*_RWSTD_C::cos(th), __r*_RWSTD_C::sin(th));
|
|
}
|
|
|
|
|
|
//
|
|
// complex<_TypeT> number __a raised to __a real power __s
|
|
//
|
|
// __a**__s = exp(__s * log(__a))
|
|
//
|
|
|
|
template <class _TypeT>
|
|
inline complex<_TypeT> pow (const complex<_TypeT>& __a, const _TypeT& __s)
|
|
{
|
|
if (__a == complex<_TypeT>(0,0))
|
|
{
|
|
if (__s == _TypeT(0))
|
|
return complex<_TypeT>(1,0);
|
|
else
|
|
return complex<_TypeT>(0,0);
|
|
}
|
|
if (__a.imag() == 0)
|
|
{
|
|
if (__a.real() < 0)
|
|
return pow(__a, complex<_TypeT>(__s,0));
|
|
else
|
|
#ifndef _RWSTD_NO_OVERLOAD_C_POW
|
|
return complex<_TypeT>(_RWSTD_C::pow(__a.real(),__s), 0);
|
|
#else
|
|
return complex<_TypeT>(_RWSTD_C::pow(double(__a.real()),double(__s)), 0);
|
|
#endif /* _RWSTD_NO_OVERLOAD_C_POW */
|
|
}
|
|
return exp(__s*log(__a));
|
|
}
|
|
|
|
|
|
//
|
|
// real number __s raised to __a complex<_TypeT> power __a
|
|
//
|
|
// __s**__a = exp(__a * log (__s))
|
|
//
|
|
|
|
template <class _TypeT>
|
|
inline complex<_TypeT> pow (const _TypeT& __s, const complex<_TypeT>& __a)
|
|
{
|
|
if (__s == _TypeT(0))
|
|
{
|
|
if (__a == complex<_TypeT>(0,0))
|
|
return complex<_TypeT>(1,0);
|
|
else
|
|
return complex<_TypeT>(0,0);
|
|
}
|
|
if (__s < 0)
|
|
return pow(complex<_TypeT>(__s,0), __a);
|
|
|
|
if (__a.imag() == 0)
|
|
#ifndef _RWSTD_NO_OVERLOAD_C_POW
|
|
return complex<_TypeT>(_RWSTD_C::pow(__s, __a.real()), 0);
|
|
#else
|
|
return complex<_TypeT>(_RWSTD_C::pow(double(__s), double(__a.real())), 0);
|
|
#endif /* _RWSTD_NO_OVERLOAD_C_POW */
|
|
|
|
return complex<_TypeT>(exp(__a * (_TypeT) _RWSTD_C::log(__s)));
|
|
}
|
|
|
|
//
|
|
// complex<_TypeT> number a1 raised to __a complex<_TypeT> power a2
|
|
//
|
|
// a1**a2 = rho * (cos(phi) + i sin(phi))
|
|
// rho = __r1 **__u2 * exp (-__v2* theta1)
|
|
// phi = __v2 * log(__r1) + __u2 * theta1
|
|
//
|
|
|
|
template <class _TypeT>
|
|
inline complex<_TypeT>
|
|
pow (const complex<_TypeT>& __x, const complex<_TypeT>& __y)
|
|
{
|
|
if (__x == complex<_TypeT>(0,0))
|
|
{
|
|
if (__y == complex<_TypeT>(0,0))
|
|
return complex<_TypeT>(1,0);
|
|
else
|
|
return complex<_TypeT>(0,0);
|
|
}
|
|
|
|
_TypeT __r1 = abs(__x);
|
|
_TypeT __u2 = real(__y);
|
|
_TypeT __v2 = imag(__y);
|
|
_TypeT __th1 = arg(__x);
|
|
#ifndef _RWSTD_NO_OVERLOAD_C_POW
|
|
_TypeT rho = _RWSTD_C::pow(__r1, __u2) * _RWSTD_C::exp(-__v2 *__th1);
|
|
#else
|
|
_TypeT rho = _RWSTD_C::pow(double(__r1), double(__u2)) * _RWSTD_C::exp(-__v2 *__th1);
|
|
#endif /* _RWSTD_NO_OVERLOAD_C_POW */
|
|
_TypeT phi = __v2 * _RWSTD_C::log(__r1) + __u2 * __th1;
|
|
|
|
return complex<_TypeT>(rho*_RWSTD_C::cos(phi), rho*_RWSTD_C::sin(phi));
|
|
}
|
|
|
|
|
|
//
|
|
// complex<_TypeT> sine of complex<_TypeT> number __a
|
|
// sin (__a) = sin u * cosh v + i * cos u * sinh v
|
|
//
|
|
template <class _TypeT>
|
|
inline complex<_TypeT> sin (const complex<_TypeT>& __a)
|
|
{
|
|
|
|
return complex<_TypeT>(_RWSTD_C::sin(__a.real())*_RWSTD_C::cosh(__a.imag()),
|
|
_RWSTD_C::cos(__a.real())*_RWSTD_C::sinh(__a.imag()));
|
|
}
|
|
|
|
//
|
|
// complex<_TypeT> hyperbolic sine of complex<_TypeT> number __a
|
|
// sinh (__a) = sinh u cos v + i cosh u sin v
|
|
//
|
|
template <class _TypeT>
|
|
inline complex<_TypeT> sinh (const complex<_TypeT>& __a)
|
|
{
|
|
return complex<_TypeT>(_RWSTD_C::sinh(__a.real())*_RWSTD_C::cos(__a.imag()),
|
|
_RWSTD_C::cosh(__a.real())*_RWSTD_C::sin(__a.imag()));
|
|
}
|
|
|
|
//
|
|
// complex<_TypeT> square root of complex<_TypeT> number __a
|
|
// sqrt(__a) = sqrt(__r) * ( cos (theta/2) + i sin (theta/2) )
|
|
//
|
|
template <class _TypeT>
|
|
inline complex<_TypeT> sqrt (const complex<_TypeT>& __a)
|
|
{
|
|
register _TypeT __r = _RWSTD_C::sqrt(abs(__a));
|
|
register _TypeT th = arg(__a)/2.;
|
|
return complex<_TypeT>(__r*_RWSTD_C::cos(th), __r*_RWSTD_C::sin(th));
|
|
}
|
|
|
|
template <class _TypeT>
|
|
inline complex<_TypeT> tan (const complex<_TypeT>& __a)
|
|
{
|
|
#ifndef _RWSTD_NO_LONG_DOUBLE
|
|
complex<long double> longa((long double)__a.real(),(long double)__a.imag());
|
|
#else
|
|
complex<double> longa((double)__a.real(),(double)__a.imag());
|
|
#endif
|
|
return complex<_TypeT>(sin(longa)/cos(longa));
|
|
}
|
|
|
|
template <class _TypeT>
|
|
inline complex<_TypeT> tanh (const complex<_TypeT>& __a)
|
|
{
|
|
#ifndef _RWSTD_NO_LONG_DOUBLE
|
|
complex<long double> longa((long double)__a.real(),(long double)__a.imag());
|
|
#else
|
|
complex<double> longa((double)__a.real(),(double)__a.imag());
|
|
#endif
|
|
return complex<_TypeT>(sinh(longa)/cosh(longa));
|
|
}
|
|
|
|
|
|
template <class _TypeT>
|
|
inline complex<_TypeT> log10 (const complex<_TypeT>& __a)
|
|
{
|
|
static const _TypeT log10e = _RWSTD_C::log10(_RWSTD_C::exp(_TypeT(1)));
|
|
return log10e * log(__a);
|
|
}
|
|
|
|
|
|
// 26.2.6, p12: MT-safe extractor (not atomic)
|
|
template <class _TypeT, class _CharT, class _Traits>
|
|
inline basic_istream<_CharT, _Traits >&
|
|
operator>> (basic_istream<_CharT, _Traits>& __strm, complex<_TypeT> &__val)
|
|
{
|
|
// read __a complex number in one of the following forms:
|
|
// "__r", "(__r)", "(__r, i)"
|
|
|
|
_TypeT __re = _TypeT (),
|
|
__im = _TypeT ();
|
|
|
|
char __ch;
|
|
|
|
if (!(__strm >> __ch))
|
|
return __strm;
|
|
|
|
if ('(' == __ch) {
|
|
__strm >> __re >> __ch;
|
|
|
|
if (',' == __ch)
|
|
__strm >> __im >> __ch;
|
|
|
|
if (')' != __ch)
|
|
__strm.setstate (__strm.failbit);
|
|
}
|
|
else if (__strm) {
|
|
__strm.putback (__ch);
|
|
__strm >> __re;
|
|
}
|
|
|
|
if (__strm)
|
|
__val = complex<_TypeT>(__re, __im);
|
|
|
|
return __strm;
|
|
}
|
|
|
|
|
|
// 26.2.6, p15: MT-safe atomic inserter
|
|
template <class _TypeT, class _CharT, class _Traits>
|
|
inline basic_ostream<_CharT, _Traits>&
|
|
operator<< (basic_ostream<_CharT, _Traits >& __strm,
|
|
const complex<_TypeT>& __val)
|
|
{
|
|
basic_ostringstream<_CharT, _Traits, allocator<_CharT> > __ss;
|
|
__ss.flags (__strm.flags ());
|
|
__ss.imbue (__strm.getloc ());
|
|
__ss.precision (__strm.precision ());
|
|
__ss << '(' << __val.real () << ',' << __val.imag () << ')';
|
|
return __strm << __ss.str ();
|
|
}
|
|
|
|
|
|
_RWSTD_NAMESPACE_END // std
|
|
|
|
|
|
#endif // _RWSTD_COMPLEX_INCLUDED
|
|
|