// -*- 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 #include #include #include #include _RWSTD_NAMESPACE_BEGIN (std) template class complex; _RWSTD_SPECIALIZED_CLASS class complex; _RWSTD_SPECIALIZED_CLASS class complex; #ifndef _RWSTD_NO_LONG_DOUBLE _RWSTD_SPECIALIZED_CLASS class complex; #endif _RWSTD_SPECIALIZED_CLASS class complex { 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&); #ifndef _RWSTD_NO_LONG_DOUBLE _EXPLICIT complex (const complex&); #endif float imag () const { return _C_im; } float real () const { return _C_re; } #ifndef _RWSTD_NO_MEMBER_TEMPLATES template complex& operator= (const complex<_TypeX>& __rhs) {_C_re=__rhs.real(); _C_im=__rhs.imag(); return *this;} template complex& operator+= (const complex<_TypeX>& __rhs) {_C_re+=__rhs.real(); _C_im+=__rhs.imag(); return *this;} template complex& operator-= (const complex<_TypeX>& __rhs) {_C_re-=__rhs.real(); _C_im-=__rhs.imag(); return *this;} template complex& 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 complex& 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&); complex& operator+= (const complex&); complex& operator-= (const complex&); complex& operator*= (const complex&); complex& operator/= (const complex&); # ifndef _RWSTD_NO_LONG_DOUBLE complex& operator= (const complex&); complex& operator+= (const complex&); complex& operator-= (const complex&); complex& operator*= (const complex&); complex& operator/= (const complex&); # endif #endif complex& operator= (float); complex& operator+= (float); complex& operator-= (float); complex& operator*= (float); complex& operator/= (float); private: float _C_re, _C_im; }; _RWSTD_SPECIALIZED_CLASS class complex { 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&); #ifndef _RWSTD_NO_LONG_DOUBLE _EXPLICIT complex (const complex&); #endif double imag () const { return _C_im; } double real () const { return _C_re; } #ifndef _RWSTD_NO_MEMBER_TEMPLATES template complex& operator= (const complex<_TypeX>& __rhs) {_C_re=__rhs.real(); _C_im=__rhs.imag(); return *this;} template complex& operator+= (const complex<_TypeX>& __rhs) {_C_re+=__rhs.real(); _C_im+=__rhs.imag(); return *this;} template complex& operator-= (const complex<_TypeX>& __rhs) {_C_re-=__rhs.real(); _C_im-=__rhs.imag(); return *this;} template complex& 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 complex& operator/= (const complex<_TypeX>&); #else /* Have to specialize each one :-( */ complex& operator= (const complex&); complex& operator+= (const complex&); complex& operator-= (const complex&); complex& operator*= (const complex& __rhs); complex& operator/= (const complex&); complex& operator= (const complex& __rhs); complex& operator+= (const complex& __rhs); complex& operator-= (const complex& __rhs); complex& operator*= (const complex& __rhs); complex& operator/= (const complex&); # ifndef _RWSTD_NO_LONG_DOUBLE complex& operator= (const complex&); complex& operator+= (const complex&); complex& operator-= (const complex&); complex& operator*= (const complex&); complex& operator/= (const complex&); # endif #endif complex& operator= (double); complex& operator+= (double); complex& operator-= (double); complex& operator*= (double); complex& operator/= (double); private: double _C_re, _C_im; }; #ifndef _RWSTD_NO_LONG_DOUBLE _RWSTD_SPECIALIZED_CLASS class complex { 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&); complex (const complex&); long double imag () const { return _C_im; } long double real () const { return _C_re; } # ifndef _RWSTD_NO_MEMBER_TEMPLATES template complex& operator= (const complex<_TypeX>& __rhs) {_C_re=__rhs.real(); _C_im=__rhs.imag(); return *this;} template complex& operator+= (const complex<_TypeX>& __rhs) {_C_re+=__rhs.real(); _C_im+=__rhs.imag(); return *this;} template complex& operator-= (const complex<_TypeX>& __rhs) {_C_re-=__rhs.real(); _C_im-=__rhs.imag(); return *this;} template complex& 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 complex& operator/= (const complex<_TypeX>&); # else /* Have to specialize each one :-( */ complex& operator= (const complex&); complex& operator+= (const complex&); complex& operator-= (const complex&); complex& operator*= (const complex&); complex& operator/= (const complex&); complex& operator= (const complex&); complex& operator+= (const complex&); complex& operator-= (const complex&); complex& operator*= (const complex&); complex& operator/= (const complex&); complex& operator= (const complex&); complex& operator+= (const complex&); complex& operator-= (const complex&); complex& operator*= (const complex&); complex& operator/= (const complex&); # endif complex& operator= (long double); complex& operator+= (long double); complex& operator-= (long double); complex& operator*= (long double); complex& operator/= (long double); private: long double _C_re, _C_im; }; #endif template 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 complex (const complex<_TypeX>& __rhs) {_C_re=__rhs.real(); _C_im=__rhs.imag();} template complex<_TypeT>& operator= (const complex<_TypeX>& __rhs) {_C_re=__rhs.real(); _C_im=__rhs.imag(); return *this;} template complex<_TypeT>& operator+= (const complex<_TypeX>& __rhs) {_C_re+=__rhs.real(); _C_im+=__rhs.imag(); return *this;} template complex<_TypeT>& operator-= (const complex<_TypeX>& __rhs) {_C_re-=__rhs.real(); _C_im-=__rhs.imag(); return *this;} template 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 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 specializations. // inline complex::complex (const complex& cd) { _C_re = _RWSTD_STATIC_CAST(float,cd.real()); _C_im = _RWSTD_STATIC_CAST(float,cd.imag()); } #ifndef _RWSTD_NO_LONG_DOUBLE inline complex::complex (const complex& cld) { _C_re = _RWSTD_STATIC_CAST(float,cld.real()); _C_im = _RWSTD_STATIC_CAST(float,cld.imag()); } #endif inline complex& complex::operator= (float __rhs) { _C_re = __rhs; _C_im = 0.0; return *this; } inline complex& complex::operator+= (float __rhs) { _C_re += __rhs; return *this; } inline complex& complex::operator-= (float __rhs) { _C_re -= __rhs; return *this; } inline complex& complex::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& complex::operator= (const complex& __rhs) { _C_re = _RWSTD_STATIC_CAST(float,__rhs.real()); _C_im = _RWSTD_STATIC_CAST(float,__rhs.imag()); return *this; } inline complex& complex::operator+= (const complex& __rhs) { _C_re += _RWSTD_STATIC_CAST(float,__rhs.real()); _C_im += _RWSTD_STATIC_CAST(float,__rhs.imag()); return *this; } inline complex& complex::operator-= (const complex& __rhs) { _C_re -= _RWSTD_STATIC_CAST(float,__rhs.real()); _C_im -= _RWSTD_STATIC_CAST(float,__rhs.imag()); return *this; } inline complex& complex::operator*= (const complex& __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& complex::operator= (const complex& __rhs) { _C_re = _RWSTD_STATIC_CAST(float,__rhs.real()); _C_im = _RWSTD_STATIC_CAST(float,__rhs.imag()); return *this; } inline complex& complex::operator+= (const complex& __rhs) { _C_re += _RWSTD_STATIC_CAST(float,__rhs.real()); _C_im += _RWSTD_STATIC_CAST(float,__rhs.imag()); return *this; } inline complex& complex::operator-= (const complex& __rhs) { _C_re -= _RWSTD_STATIC_CAST(float,__rhs.real()); _C_im -= _RWSTD_STATIC_CAST(float,__rhs.imag()); return *this; } inline complex& complex::operator*= (const complex& __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 specializations. // inline complex::complex (const complex& cf) : _C_re(cf.real()), _C_im(cf.imag()) {} #ifndef _RWSTD_NO_LONG_DOUBLE inline complex::complex (const complex& cld) : _C_re(_RWSTD_STATIC_CAST(double,cld.real())), _C_im(_RWSTD_STATIC_CAST(double,cld.imag())) {} #endif inline complex& complex::operator= (double __rhs) { _C_re = __rhs; _C_im = 0.0; return *this; } inline complex& complex::operator+= (double __rhs) { _C_re += __rhs; return *this; } inline complex& complex::operator-= (double __rhs) { _C_re -= __rhs; return *this; } inline complex& complex::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& complex::operator= (const complex& __rhs) { _C_re = __rhs.real(); _C_im = __rhs.imag(); return *this; } inline complex& complex::operator+= (const complex& __rhs) { _C_re += __rhs.real(); _C_im += __rhs.imag(); return *this; } inline complex& complex::operator-= (const complex& __rhs) { _C_re -= __rhs.real(); _C_im -= __rhs.imag(); return *this; } inline complex& complex::operator*= (const complex& __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& complex::operator= (const complex& __rhs) { _C_re = __rhs.real(); _C_im = __rhs.imag(); return *this; } inline complex& complex::operator+= (const complex& __rhs) { _C_re += __rhs.real(); _C_im += __rhs.imag(); return *this; } inline complex& complex::operator-= (const complex& __rhs) { _C_re -= __rhs.real(); _C_im -= __rhs.imag(); return *this; } inline complex& complex::operator*= (const complex& __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& complex::operator= (const complex& __rhs) { _C_re = _RWSTD_STATIC_CAST(double,__rhs.real()); _C_im = _RWSTD_STATIC_CAST(double,__rhs.imag()); return *this; } inline complex& complex::operator+= (const complex& __rhs) { _C_re += _RWSTD_STATIC_CAST(double,__rhs.real()); _C_im += _RWSTD_STATIC_CAST(double,__rhs.imag()); return *this; } inline complex& complex::operator-= (const complex& __rhs) { _C_re -= _RWSTD_STATIC_CAST(double,__rhs.real()); _C_im -= _RWSTD_STATIC_CAST(double,__rhs.imag()); return *this; } inline complex& complex::operator*= (const complex& __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 specializations. // #ifndef _RWSTD_NO_LONG_DOUBLE inline complex::complex (const complex& cf) : _C_re(cf.real()), _C_im(cf.imag()) {} inline complex::complex (const complex& cd) : _C_re(cd.real()), _C_im(cd.imag()) {} inline complex& complex::operator+= (long double __rhs) { _C_re += __rhs; return *this; } inline complex& complex::operator= (long double __rhs) { _C_re = __rhs; _C_im = 0.0; return *this; } inline complex& complex::operator-= (long double __rhs) { _C_re -= __rhs; return *this; } inline complex& complex::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& complex::operator= (const complex& __rhs) { _C_re = __rhs.real(); _C_im = __rhs.imag(); return *this; } inline complex& complex::operator+= (const complex& __rhs) { _C_re += __rhs.real(); _C_im += __rhs.imag(); return *this; } inline complex& complex::operator-= (const complex& __rhs) { _C_re -= __rhs.real(); _C_im -= __rhs.imag(); return *this; } inline complex& complex::operator*= (const complex& __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& complex::operator= (const complex& __rhs) { _C_re = __rhs.real(); _C_im = __rhs.imag(); return *this; } inline complex& complex::operator+= (const complex& __rhs) { _C_re += __rhs.real(); _C_im += __rhs.imag(); return *this; } inline complex& complex::operator-= (const complex& __rhs) { _C_re -= __rhs.real(); _C_im -= __rhs.imag(); return *this; } inline complex& complex::operator*= (const complex& __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& complex::operator= (const complex& __rhs) { _C_re = __rhs.real(); _C_im = __rhs.imag(); return *this; } inline complex& complex::operator+= (const complex& __rhs) { _C_re += __rhs.real(); _C_im += __rhs.imag(); return *this; } inline complex& complex::operator-= (const complex& __rhs) { _C_re -= __rhs.real(); _C_im -= __rhs.imag(); return *this; } inline complex& complex::operator*= (const complex& __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 template 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 inline complex& complex::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 inline complex& complex::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 inline complex& complex::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& complex::operator/= (const complex& __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& complex::operator/= (const complex& __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& complex::operator/= (const complex& __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& complex::operator/= (const complex& __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& complex::operator/= (const complex& __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& complex::operator/= (const complex& __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& complex::operator/= (const complex& __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& complex::operator/= (const complex& __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& complex::operator/= (const complex& __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& complex::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& complex::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& complex::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 inline complex<_TypeT> operator+ (const complex<_TypeT>& __lhs, const complex<_TypeT>& __rhs) { complex<_TypeT> __tmp = __lhs; return __tmp += __rhs; } template inline complex<_TypeT> operator+ (const complex<_TypeT>& __lhs, const _TypeT& __rhs) { return complex<_TypeT>(__rhs+__lhs.real(), __lhs.imag()); } template inline complex<_TypeT> operator+ (const _TypeT& __lhs, const complex<_TypeT>& __rhs) { return complex<_TypeT>(__lhs+__rhs.real(), __rhs.imag()); } template inline complex<_TypeT> operator- (const complex<_TypeT>& __lhs, const complex<_TypeT>& __rhs) { complex<_TypeT> __tmp = __lhs; return __tmp -= __rhs; } template inline complex<_TypeT> operator- (const complex<_TypeT>& __lhs, const _TypeT& __rhs) { return complex<_TypeT>(__lhs.real()-__rhs, __lhs.imag()); } template inline complex<_TypeT> operator- (const _TypeT& __lhs, const complex<_TypeT>& __rhs) { return complex<_TypeT>(__lhs-__rhs.real(), -__rhs.imag()); } template inline complex<_TypeT> operator* (const complex<_TypeT>& __lhs, const complex<_TypeT>& __rhs) { complex<_TypeT> __tmp = __lhs; return __tmp *= __rhs; } template inline complex<_TypeT> operator* (const complex<_TypeT>& __lhs, const _TypeT& __rhs) { return complex<_TypeT>(__rhs*__lhs.real(), __rhs*__lhs.imag()); } template inline complex<_TypeT> operator* (const _TypeT& __lhs, const complex<_TypeT>& __rhs) { return complex<_TypeT>(__lhs*__rhs.real(), __lhs*__rhs.imag()); } template inline complex<_TypeT> operator/ (const complex<_TypeT>& __lhs, const complex<_TypeT>& __rhs) { complex<_TypeT> __tmp = __lhs; return __tmp /= __rhs; } template inline complex<_TypeT> operator/ (const complex<_TypeT>& __lhs, const _TypeT& __rhs) { return complex<_TypeT>(__lhs.real()/__rhs, __lhs.imag()/__rhs); } template 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 inline complex<_TypeT> operator+ (const complex<_TypeT>& __lhs) { return __lhs; } template inline complex<_TypeT> operator- (const complex<_TypeT>& __lhs) { return complex<_TypeT>(-__lhs.real(), -__lhs.imag()); } template inline bool operator== (const complex<_TypeT>& __lhs, const complex<_TypeT>& __rhs) { return __lhs.real() == __rhs.real() && __lhs.imag() == __rhs.imag(); } template inline bool operator== (const _TypeT& __lhs, const complex<_TypeT>& __rhs) { return __lhs == __rhs.real() && __rhs.imag() == 0; } template inline bool operator== (const complex<_TypeT>& __lhs, const _TypeT& __rhs) { return __lhs.real() == __rhs && __lhs.imag() == 0; } template inline bool operator!= (const complex<_TypeT>& __lhs, const complex<_TypeT>& __rhs) { return __lhs.real() != __rhs.real() || __lhs.imag() != __rhs.imag(); } template inline bool operator!= (const _TypeT& __lhs, const complex<_TypeT>& __rhs) { return __lhs != __rhs.real() || __rhs.imag() != 0; } template inline bool operator!= (const complex<_TypeT>& __lhs, const _TypeT& __rhs) { return __lhs.real() != __rhs || __lhs.imag() != 0; } // // complex value operations // template inline _TypeT real (const complex<_TypeT>& __a) { return __a.real(); } template inline _TypeT imag (const complex<_TypeT>& __a) { return __a.imag(); } template inline _TypeT norm (const complex<_TypeT>& __a) { return __a.real()*__a.real() + __a.imag()*__a.imag(); } template inline _TypeT abs (const complex<_TypeT>& __a) { return (_RWSTD_C::sqrt(norm(__a))); } // // We guarantee that arg(complex<_TypeT>(0,0)) == 0. // template inline _TypeT arg (const complex<_TypeT>& __a) { return __a == complex<_TypeT>(0,0) ? _TypeT(0) : _RWSTD_C::atan2(__a.imag(), __a.real()); } template complex<_TypeT> conj (const complex<_TypeT>& __a) { return complex<_TypeT>(__a.real(), -__a.imag()); } template 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 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 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 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 inline complex<_TypeT> log (const complex<_TypeT>& __a) { return complex<_TypeT>(_RWSTD_C::log(abs(__a)), arg(__a)); } template 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 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 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 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 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 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 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 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 inline complex<_TypeT> tan (const complex<_TypeT>& __a) { #ifndef _RWSTD_NO_LONG_DOUBLE complex longa((long double)__a.real(),(long double)__a.imag()); #else complex longa((double)__a.real(),(double)__a.imag()); #endif return complex<_TypeT>(sin(longa)/cos(longa)); } template inline complex<_TypeT> tanh (const complex<_TypeT>& __a) { #ifndef _RWSTD_NO_LONG_DOUBLE complex longa((long double)__a.real(),(long double)__a.imag()); #else complex longa((double)__a.real(),(double)__a.imag()); #endif return complex<_TypeT>(sinh(longa)/cosh(longa)); } template 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 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 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