home *** CD-ROM | disk | FTP | other *** search
/ Magazyn Internet 2000 May / MICD_2000_05.iso / CBuilder5 / INSTALL / DATA1.CAB / Program_Built_Files / Include / complex.h < prev    next >
C/C++ Source or Header  |  2000-02-01  |  45KB  |  1,490 lines

  1. #ifndef __COMPLEX_H
  2. #define __COMPLEX_H
  3. #pragma option push -b -a8 -pc -Vx- -Ve- -w-inl -w-aus -w-sig
  4. // -*- C++ -*-
  5. #ifndef __STD_COMPLEX
  6. #define __STD_COMPLEX
  7.  
  8. /***************************************************************************
  9.  *
  10.  * complex - Declaration for the Standard Library complex class
  11.  *
  12.  ***************************************************************************
  13.  *
  14.  * Copyright (c) 1994-1999 Rogue Wave Software, Inc.  All Rights Reserved.
  15.  *
  16.  * This computer software is owned by Rogue Wave Software, Inc. and is
  17.  * protected by U.S. copyright laws and other laws and by international
  18.  * treaties.  This computer software is furnished by Rogue Wave Software,
  19.  * Inc. pursuant to a written license agreement and may be used, copied,
  20.  * transmitted, and stored only in accordance with the terms of such
  21.  * license and with the inclusion of the above copyright notice.  This
  22.  * computer software or any other copies thereof may not be provided or
  23.  * otherwise made available to any other person.
  24.  *
  25.  * U.S. Government Restricted Rights.  This computer software is provided
  26.  * with Restricted Rights.  Use, duplication, or disclosure by the
  27.  * Government is subject to restrictions as set forth in subparagraph (c)
  28.  * (1) (ii) of The Rights in Technical Data and Computer Software clause
  29.  * at DFARS 252.227-7013 or subparagraphs (c) (1) and (2) of the
  30.  * Commercial Computer Software û Restricted Rights at 48 CFR 52.227-19,
  31.  * as applicable.  Manufacturer is Rogue Wave Software, Inc., 5500
  32.  * Flatiron Parkway, Boulder, Colorado 80301 USA.
  33.  *
  34.  **************************************************************************/
  35.  
  36. #include <stdcomp.h>
  37. #include <rw/stddefs.h>
  38. #include <rw/math.h>
  39.  
  40. #include <utility>
  41.  
  42. #ifndef _RW_STD_IOSTREAM
  43. #include <iostream.h>
  44. #else
  45. #include <iostream>
  46. #endif
  47.  
  48. #ifndef _RWSTD_NO_NAMESPACE 
  49. namespace std {
  50. #endif
  51.  
  52. #ifdef _RWSTD_NO_FORWARD_SPECIALIZATIONS
  53.   template <class T>
  54.   class _RWSTDExportTemplate complex
  55.   {
  56.   public:
  57.     typedef T value_type;
  58.  
  59.     complex (const T& re_arg=0, const T& imag_arg=0) 
  60.       : __re(re_arg), __im(imag_arg)
  61.     { ; } 
  62.  
  63.     T imag () const { return __im; }
  64.     T real () const { return __re; }
  65.  
  66. #ifndef _RWSTD_NO_MEMBER_TEMPLATES
  67.  
  68.     template <class X> complex<T>& operator=  (const complex<X>& rhs) {__re=rhs.real(); __im=rhs.imag(); return *this;}
  69.     template <class X> complex<T>& operator+= (const complex<X>& rhs) {__re+=rhs.real(); __im+=rhs.imag(); return *this;}
  70.     template <class X> complex<T>& operator-= (const complex<X>& rhs) {__re-=rhs.real(); __im-=rhs.imag(); return *this;}
  71.     template <class X> complex<T>& operator*= (const complex<X>& rhs) {T tmp=__re*rhs.real()-__im*rhs.imag(); __im=__im*rhs.real()+__re*rhs.imag(); __re=tmp; return *this;}
  72.     template <class X> complex<T>& operator/= (const complex<X>&); 
  73. #endif
  74.     
  75.     complex<T>& operator=  (const T&); 
  76.     complex<T>& operator+= (const T&); 
  77.     complex<T>& operator-= (const T&); 
  78.     complex<T>& operator*= (const T&); 
  79.     complex<T>& operator/= (const T&); 
  80.  
  81.   private:
  82.     T __re, __im;
  83.   };
  84. #else
  85.  
  86. //
  87. // The complex template definition must be placed after specializations to 
  88. // satisfy several compilers' rather bizarre preference.
  89. //
  90.   template <class T>
  91.   class _RWSTDExportTemplate complex;
  92. #endif
  93.  
  94. #ifndef _RWSTD_NO_FORWARD_SPECIALIZATIONS 
  95.   _RWSTD_TEMPLATE class _RWSTDExport complex<float>;
  96.   _RWSTD_TEMPLATE class _RWSTDExport complex<double>;
  97. #ifndef _RWSTD_NO_LONGDOUBLE
  98.   _RWSTD_TEMPLATE class _RWSTDExport complex<long double>;
  99. #endif
  100. #endif
  101.  
  102.   _RWSTD_TEMPLATE
  103.   class _RWSTDExport complex<float>
  104.   {
  105.   public:
  106.     typedef float value_type;
  107.  
  108.     complex (const float& re_arg=0.0f, const float& imag_arg=0.0f) 
  109.       : __re(re_arg), __im(imag_arg)
  110.     { ; }
  111. #ifndef _RWSTD_NO_FORWARD_SPECIALIZATIONS
  112.     _EXPLICIT complex (const complex<double>&); 
  113. #ifndef _RWSTD_NO_LONGDOUBLE
  114.     _EXPLICIT complex (const complex<long double>&);
  115. #endif
  116. #endif // _RWSTD_NO_FORWARD_SPECIALIZATIONS
  117.  
  118.     float imag () const { return __im; }
  119.     float real () const { return __re; }
  120.  
  121. #ifndef _RWSTD_NO_MEMBER_TEMPLATES
  122.     template <class X> complex<float>& operator=  (const complex<X>& rhs) {__re=rhs.real(); __im=rhs.imag(); return *this;}
  123.     template <class X> complex<float>& operator+= (const complex<X>& rhs) {__re+=rhs.real(); __im+=rhs.imag(); return *this;}
  124.     template <class X> complex<float>& operator-= (const complex<X>& rhs) {__re-=rhs.real(); __im-=rhs.imag(); return *this;}
  125.     template <class X> complex<float>& operator*= (const complex<X>& rhs) {float tmp=__re*rhs.real()-__im*rhs.imag(); __im=__im*rhs.real()+__re*rhs.imag(); __re=tmp; return *this;}
  126.     template <class X> complex<float>& operator/= (const complex<X>&); 
  127. #else /* Have to specialize each one :-( */
  128.  
  129.     complex<float>& operator=  (const complex<float>&); 
  130.     complex<float>& operator+= (const complex<float>&); 
  131.     complex<float>& operator-= (const complex<float>&); 
  132.     complex<float>& operator*= (const complex<float>&); 
  133.     complex<float>& operator/= (const complex<float>&); 
  134.  
  135. #ifndef _RWSTD_NO_FORWARD_SPECIALIZATIONS
  136.     complex<float>& operator=  (const complex<double>&); 
  137.     complex<float>& operator+= (const complex<double>&); 
  138.     complex<float>& operator-= (const complex<double>&); 
  139.     complex<float>& operator*= (const complex<double>&); 
  140.     complex<float>& operator/= (const complex<double>&); 
  141.  
  142. #ifndef _RWSTD_NO_LONGDOUBLE
  143.     complex<float>& operator=  (const complex<long double>&); 
  144.     complex<float>& operator+= (const complex<long double>&); 
  145.     complex<float>& operator-= (const complex<long double>&); 
  146.     complex<float>& operator*= (const complex<long double>&); 
  147.     complex<float>& operator/= (const complex<long double>&);
  148. #endif
  149. #endif  
  150. #endif
  151.  
  152.     complex<float>& operator=  (float); 
  153.     complex<float>& operator+= (float); 
  154.     complex<float>& operator-= (float); 
  155.     complex<float>& operator*= (float); 
  156.     complex<float>& operator/= (float); 
  157.  
  158.   private:
  159.     float __re, __im;
  160.   };
  161.  
  162.   _RWSTD_TEMPLATE
  163.   class  _RWSTDExport complex<double>
  164.   {
  165.   public:
  166.     typedef double value_type;
  167.  
  168.     complex (const double& re_arg=0.0, const double& imag_arg=0.0) 
  169.       : __re(re_arg), __im(imag_arg)
  170.     { ; } 
  171.     complex (const complex<float>&); 
  172. #ifndef _RWSTD_NO_FORWARD_SPECIALIZATIONS
  173. #ifndef _RWSTD_NO_LONGDOUBLE  
  174.     _EXPLICIT complex (const complex<long double>&); 
  175. #endif
  176. #endif // _RWSTD_NO_FORWARD_SPECIALIZATIONS
  177.  
  178.     double imag () const { return __im; }
  179.     double real () const { return __re; }
  180.  
  181. #ifndef _RWSTD_NO_MEMBER_TEMPLATES
  182.     template <class X> complex<double>& operator=  (const complex<X>& rhs) {__re=rhs.real(); __im=rhs.imag(); return *this;}
  183.     template <class X> complex<double>& operator+= (const complex<X>& rhs) {__re+=rhs.real(); __im+=rhs.imag(); return *this;}
  184.     template <class X> complex<double>& operator-= (const complex<X>& rhs) {__re-=rhs.real(); __im-=rhs.imag(); return *this;}
  185.     template <class X> complex<double>& operator*= (const complex<X>& rhs) {double tmp=__re*rhs.real()-__im*rhs.imag(); __im=__im*rhs.real()+__re*rhs.imag(); __re=tmp; return *this;}
  186.     template <class X> complex<double>& operator/= (const complex<X>&);
  187.  
  188. #else /* Have to specialize each one :-( */
  189.  
  190.     complex<double>& operator=  (const complex<float>&); 
  191.     complex<double>& operator+= (const complex<float>&); 
  192.     complex<double>& operator-= (const complex<float>&);
  193.     complex<double>& operator*= (const complex<float>& rhs); 
  194.     complex<double>& operator/= (const complex<float>&); 
  195.  
  196.     complex<double>& operator=  (const complex<double>& rhs); 
  197.     complex<double>& operator+= (const complex<double>& rhs); 
  198.     complex<double>& operator-= (const complex<double>& rhs); 
  199.     complex<double>& operator*= (const complex<double>& rhs); 
  200.     complex<double>& operator/= (const complex<double>&); 
  201.  
  202. #ifndef _RWSTD_NO_FORWARD_SPECIALIZATIONS
  203. #ifndef _RWSTD_NO_LONGDOUBLE  
  204.     complex<double>& operator=  (const complex<long double>&); 
  205.     complex<double>& operator+= (const complex<long double>&); 
  206.     complex<double>& operator-= (const complex<long double>&); 
  207.     complex<double>& operator*= (const complex<long double>&); 
  208.     complex<double>& operator/= (const complex<long double>&);
  209. #endif
  210. #endif 
  211. #endif
  212.  
  213.     complex<double>& operator=  (double); 
  214.     complex<double>& operator+= (double); 
  215.     complex<double>& operator-= (double); 
  216.     complex<double>& operator*= (double); 
  217.     complex<double>& operator/= (double); 
  218.   private:
  219.     double __re, __im;
  220.   };
  221.  
  222. #ifndef _RWSTD_NO_LONGDOUBLE  
  223.  
  224.   _RWSTD_TEMPLATE
  225.   class _RWSTDExport complex<long double>
  226.   {
  227.   public:
  228.     typedef long double value_type;
  229.  
  230.     complex (const long double& re_arg=0.0L, const long double& imag_arg=0.0L)
  231.       : __re(re_arg), __im(imag_arg)
  232.     { ; } 
  233.     complex (const complex<float>&);
  234.     complex (const complex<double>&);
  235.  
  236.     long double imag () const { return __im; }
  237.     long double real () const { return __re; }
  238.  
  239. #ifndef _RWSTD_NO_MEMBER_TEMPLATES
  240.     template <class X> complex<long double>& operator=  (const complex<X>& rhs) {__re=rhs.real(); __im=rhs.imag(); return *this;}
  241.     template <class X> complex<long double>& operator+= (const complex<X>& rhs) {__re+=rhs.real(); __im+=rhs.imag(); return *this;}
  242.     template <class X> complex<long double>& operator-= (const complex<X>& rhs) {__re-=rhs.real(); __im-=rhs.imag(); return *this;}
  243.     template <class X> complex<long double>& operator*= (const complex<X>& rhs) {long double tmp=__re*rhs.real()-__im*rhs.imag(); __im=__im*rhs.real()+__re*rhs.imag(); __re=tmp; return *this;}
  244.     template <class X> complex<long double>& operator/= (const complex<X>&); 
  245.  
  246. #else /* Have to specialize each one :-( */
  247.  
  248.     complex<long double>& operator=  (const complex<float>&); 
  249.     complex<long double>& operator+= (const complex<float>&); 
  250.     complex<long double>& operator-= (const complex<float>&); 
  251.     complex<long double>& operator*= (const complex<float>&); 
  252.     complex<long double>& operator/= (const complex<float>&); 
  253.  
  254.     complex<long double>& operator=  (const complex<double>&); 
  255.     complex<long double>& operator+= (const complex<double>&); 
  256.     complex<long double>& operator-= (const complex<double>&); 
  257.     complex<long double>& operator*= (const complex<double>&); 
  258.     complex<long double>& operator/= (const complex<double>&); 
  259.  
  260.     complex<long double>& operator=  (const complex<long double>&); 
  261.     complex<long double>& operator+= (const complex<long double>&); 
  262.     complex<long double>& operator-= (const complex<long double>&); 
  263.     complex<long double>& operator*= (const complex<long double>&); 
  264.     complex<long double>& operator/= (const complex<long double>&); 
  265. #endif
  266.  
  267.     complex<long double>& operator=  (long double); 
  268.     complex<long double>& operator+= (long double); 
  269.     complex<long double>& operator-= (long double); 
  270.     complex<long double>& operator*= (long double); 
  271.     complex<long double>& operator/= (long double); 
  272.   private:
  273.     long double __re, __im;
  274.   };
  275. #endif
  276.  
  277. #ifndef _RWSTD_NO_FORWARD_SPECIALIZATIONS
  278.   template <class T>
  279.   class _RWSTDExportTemplate complex
  280.   {
  281.   public:
  282.     typedef T value_type;
  283.  
  284.     complex (const T& re_arg=0, const T& imag_arg=0) 
  285.       : __re(re_arg), __im(imag_arg)
  286.     { ; } 
  287.  
  288.     T imag () const { return __im; }
  289.     T real () const { return __re; }
  290.  
  291. #ifndef _RWSTD_NO_MEMBER_TEMPLATES
  292.     template <class X> complex (const complex<X>& rhs) {__re=rhs.real(); __im=rhs.imag();}
  293.  
  294.     template <class X> complex<T>& operator=  (const complex<X>& rhs) {__re=rhs.real(); __im=rhs.imag(); return *this;}
  295.     template <class X> complex<T>& operator+= (const complex<X>& rhs) {__re+=rhs.real(); __im+=rhs.imag(); return *this;}
  296.     template <class X> complex<T>& operator-= (const complex<X>& rhs) {__re-=rhs.real(); __im-=rhs.imag(); return *this;}
  297.     template <class X> complex<T>& operator*= (const complex<X>& rhs) {T tmp=__re*rhs.real()-__im*rhs.imag(); __im=__im*rhs.real()+__re*rhs.imag(); __re=tmp; return *this;}
  298.     template <class X> complex<T>& operator/= (const complex<X>&); 
  299. #endif
  300.     
  301.     complex<T>& operator=  (const T&); 
  302.     complex<T>& operator+= (const T&); 
  303.     complex<T>& operator-= (const T&); 
  304.     complex<T>& operator*= (const T&); 
  305.     complex<T>& operator/= (const T&); 
  306.  
  307.   private:
  308.     T __re, __im;
  309.   };
  310. #endif
  311.  
  312. //
  313. // Temporarily turn off the warnings under the Borland compiler that
  314. // say 'Functions containing ... cannot be inlined'
  315. //
  316. #if defined(__BORLANDC__)
  317. #pragma option -w-inl
  318. #endif
  319.  
  320.   template <class T>
  321.   inline complex<T>&
  322.   complex<T>::operator= (const T& rhs) 
  323.   {
  324.     __re = rhs; __im = 0.0; return *this;
  325.   }
  326.  
  327.   template <class T>
  328.   inline complex<T>&
  329.   complex<T>::operator+= (const T& rhs) 
  330.   {
  331.     __re += rhs; return *this;
  332.   }
  333.  
  334.   template <class T>
  335.   inline complex<T>&
  336.   complex<T>::operator-= (const T& rhs) 
  337.   {
  338.     __re -= rhs;  return *this;
  339.   }
  340.  
  341.   template <class T>
  342.   inline complex<T>&
  343.   complex<T>::operator*= (const T& rhs) 
  344.   {     
  345.     T tmp = __re*rhs; 
  346.     __im       = __im*rhs; 
  347.     __re       = tmp;
  348.     return *this;
  349.   }
  350.  
  351.   template <class T>
  352.   inline complex<T>& 
  353.   complex<T>::operator/= (const T& rhs)  
  354.   {
  355.     T denom = rhs*rhs;
  356.     T re    = (__re*rhs)/denom;
  357.     T im    = (rhs*__im)/denom;
  358.     __re               = re;
  359.     __im               = im;
  360.     return *this;
  361.   }
  362. //
  363. // complex<float> specializations.
  364. //
  365.  
  366. #ifndef _RWSTD_NO_FORWARD_SPECIALIZATIONS 
  367.   inline
  368.   complex<float>::complex (const complex<double>& cd)
  369.   {
  370.     __re = _RWSTD_STATIC_CAST(float,cd.real()); 
  371.     __im = _RWSTD_STATIC_CAST(float,cd.imag());
  372.   }
  373.  
  374. #ifndef _RWSTD_NO_LONGDOUBLE
  375.   inline
  376.   complex<float>::complex (const complex<long double>& cld)
  377.   {
  378.     __re = _RWSTD_STATIC_CAST(float,cld.real()); 
  379.     __im = _RWSTD_STATIC_CAST(float,cld.imag());
  380.   }
  381. #endif
  382. #endif
  383.  
  384.   inline complex<float>&
  385.   complex<float>::operator= (float rhs) 
  386.   {
  387.     __re = rhs; __im = 0.0; return *this;
  388.   }
  389.  
  390.   inline complex<float>&
  391.   complex<float>::operator+= (float rhs) 
  392.   {
  393.     __re += rhs; return *this;
  394.   }
  395.  
  396.   inline complex<float>&
  397.   complex<float>::operator-= (float rhs) 
  398.   {
  399.     __re -= rhs;  return *this;
  400.   }
  401.  
  402.   inline complex<float>&
  403.   complex<float>::operator*= (float rhs) 
  404.   {     
  405.     float tmp = __re*rhs; 
  406.     __im       = __im*rhs; 
  407.     __re       = tmp;
  408.     return *this;
  409.   }
  410. #ifdef _RWSTD_NO_MEMBER_TEMPLATES 
  411.   inline complex<float>&
  412.   complex<float>::operator= (const complex<float>& rhs) 
  413.   {
  414.     __re = rhs.real(); __im = rhs.imag(); return *this;
  415.   }
  416.  
  417.   inline complex<float>&
  418.   complex<float>::operator+= (const complex<float>& rhs) 
  419.   {
  420.     __re += rhs.real(); __im += rhs.imag(); return *this;
  421.   }
  422.  
  423.   inline complex<float>&
  424.   complex<float>::operator-= (const complex<float>& rhs) 
  425.   {
  426.     __re -= rhs.real(); __im -= rhs.imag(); return *this;
  427.   }
  428.  
  429.   inline complex<float>&
  430.   complex<float>::operator*= (const complex<float>& rhs) 
  431.   {     
  432.     float tmp = __re*rhs.real()-__im*rhs.imag(); 
  433.     __im       = __im*rhs.real()+__re*rhs.imag(); 
  434.     __re       = tmp;
  435.     return *this;
  436.   }
  437.  
  438. #ifndef _RWSTD_NO_FORWARD_SPECIALIZATIONS 
  439.   inline complex<float>&
  440.   complex<float>::operator= (const complex<double>& rhs) 
  441.   {
  442.     __re = _RWSTD_STATIC_CAST(float,rhs.real()); 
  443.     __im = _RWSTD_STATIC_CAST(float,rhs.imag()); 
  444.     return *this;
  445.   }
  446.  
  447.   inline complex<float>&
  448.   complex<float>::operator+= (const complex<double>& rhs) 
  449.   {
  450.     __re += _RWSTD_STATIC_CAST(float,rhs.real()); 
  451.     __im += _RWSTD_STATIC_CAST(float,rhs.imag()); 
  452.     return *this;
  453.   }
  454.  
  455.   inline complex<float>&
  456.   complex<float>::operator-= (const complex<double>& rhs) 
  457.   {     
  458.     __re -= _RWSTD_STATIC_CAST(float,rhs.real()); 
  459.     __im -= _RWSTD_STATIC_CAST(float,rhs.imag()); 
  460.     return *this;
  461.   }
  462.  
  463.   inline complex<float>&
  464.   complex<float>::operator*= (const complex<double>& rhs) 
  465.   {     
  466.     float tmp = __re*_RWSTD_STATIC_CAST(float,rhs.real())-
  467.     __im*_RWSTD_STATIC_CAST(float,rhs.imag()); 
  468.     __im       = __im*_RWSTD_STATIC_CAST(float,rhs.real())+
  469.     __re*_RWSTD_STATIC_CAST(float,rhs.imag()); 
  470.     __re       = tmp;
  471.     return *this;
  472.   }
  473.  
  474. #ifndef _RWSTD_NO_LONGDOUBLE
  475.   inline complex<float>&
  476.   complex<float>::operator= (const complex<long double>& rhs) 
  477.   {     
  478.     __re = _RWSTD_STATIC_CAST(float,rhs.real()); 
  479.     __im = _RWSTD_STATIC_CAST(float,rhs.imag()); 
  480.     return *this;
  481.   }
  482.  
  483.   inline complex<float>&
  484.   complex<float>::operator+= (const complex<long double>& rhs) 
  485.   {     
  486.     __re += _RWSTD_STATIC_CAST(float,rhs.real()); 
  487.     __im += _RWSTD_STATIC_CAST(float,rhs.imag()); 
  488.     return *this;
  489.   }
  490.  
  491.   inline complex<float>&
  492.   complex<float>::operator-= (const complex<long double>& rhs) 
  493.   {
  494.     __re -= _RWSTD_STATIC_CAST(float,rhs.real()); 
  495.     __im -= _RWSTD_STATIC_CAST(float,rhs.imag()); 
  496.     return *this;
  497.   }
  498.  
  499.   inline complex<float>&
  500.   complex<float>::operator*= (const complex<long double>& rhs) 
  501.   {     
  502.     float tmp = __re*_RWSTD_STATIC_CAST(float,rhs.real())-
  503.     __im*_RWSTD_STATIC_CAST(float,rhs.imag()); 
  504.     __im      = __im*_RWSTD_STATIC_CAST(float,rhs.real())+
  505.     __re*_RWSTD_STATIC_CAST(float,rhs.imag()); 
  506.     __re      = tmp; 
  507.     return *this;
  508.   }
  509. #endif
  510. #endif
  511. #endif /* _RWSTD_NO_MEMBER_TEMPLATES */
  512. //
  513. // complex<double> specializations.
  514. //
  515.   inline
  516.   complex<double>::complex (const complex<float>& cf)
  517.   : __re(cf.real()), __im(cf.imag()) {}
  518.  
  519. #ifndef _RWSTD_NO_FORWARD_SPECIALIZATIONS 
  520. #ifndef _RWSTD_NO_LONGDOUBLE
  521.   inline 
  522.   complex<double>::complex (const complex<long double>& cld)
  523.   : __re(_RWSTD_STATIC_CAST(double,cld.real())), 
  524.   __im(_RWSTD_STATIC_CAST(double,cld.imag())) {}
  525. #endif
  526. #endif
  527.  
  528.   inline complex<double>&
  529.   complex<double>::operator= (double rhs) 
  530.   {
  531.     __re = rhs; __im = 0.0; return *this;
  532.   }
  533.  
  534.   inline complex<double>&
  535.   complex<double>::operator+= (double rhs) 
  536.   {
  537.     __re += rhs; return *this;
  538.   }
  539.  
  540.   inline complex<double>&
  541.   complex<double>::operator-= (double rhs) 
  542.   {
  543.     __re -= rhs;  return *this;
  544.   }
  545.  
  546.   inline complex<double>&
  547.   complex<double>::operator*= (double rhs) 
  548.   {     
  549.     double tmp = __re*rhs; 
  550.     __im       = __im*rhs; 
  551.     __re       = tmp;
  552.     return *this;
  553.   }
  554. #ifdef _RWSTD_NO_MEMBER_TEMPLATES 
  555.   inline complex<double>&
  556.   complex<double>::operator= (const complex<float>& rhs) 
  557.   {
  558.     __re = rhs.real(); __im = rhs.imag(); return *this;
  559.   }
  560.  
  561.   inline complex<double>&
  562.   complex<double>::operator+= (const complex<float>& rhs) 
  563.   {
  564.     __re += rhs.real(); __im += rhs.imag(); return *this;
  565.   }
  566.  
  567.   inline complex<double>&
  568.   complex<double>::operator-= (const complex<float>& rhs) 
  569.   {
  570.     __re -= rhs.real(); __im -= rhs.imag(); return *this;
  571.   }
  572.  
  573.   inline complex<double>&
  574.   complex<double>::operator*= (const complex<float>& rhs) 
  575.   {     
  576.     double tmp = __re*rhs.real()-__im*rhs.imag(); 
  577.     __im        = __im*rhs.real()+__re*rhs.imag(); 
  578.     __re        = tmp;
  579.     return *this;
  580.   }
  581.  
  582.   inline complex<double>&
  583.   complex<double>::operator= (const complex<double>& rhs) 
  584.   {
  585.     __re = rhs.real(); __im = rhs.imag(); return *this;
  586.   }
  587.  
  588.   inline complex<double>&
  589.   complex<double>::operator+= (const complex<double>& rhs) 
  590.   {
  591.     __re += rhs.real(); __im += rhs.imag(); return *this;
  592.   }
  593.  
  594.   inline complex<double>&
  595.   complex<double>::operator-= (const complex<double>& rhs) 
  596.   {     
  597.     __re -= rhs.real(); __im -= rhs.imag(); return *this;
  598.   }
  599.  
  600.   inline complex<double>& 
  601.   complex<double>::operator*= (const complex<double>& rhs) 
  602.   {     
  603.     double tmp = __re*rhs.real()-__im*rhs.imag(); 
  604.     __im       = __im*rhs.real()+__re*rhs.imag(); 
  605.     __re       = tmp;
  606.     return *this;
  607.   }
  608. #ifndef _RWSTD_NO_FORWARD_SPECIALIZATIONS 
  609. #ifndef _RWSTD_NO_LONGDOUBLE
  610.   inline complex<double>&
  611.   complex<double>::operator= (const complex<long double>& rhs) 
  612.   {     
  613.     __re = _RWSTD_STATIC_CAST(double,rhs.real()); 
  614.     __im = _RWSTD_STATIC_CAST(double,rhs.imag()); 
  615.     return *this;
  616.   }
  617.  
  618.   inline complex<double>&
  619.   complex<double>::operator+= (const complex<long double>& rhs) 
  620.   {     
  621.     __re += _RWSTD_STATIC_CAST(double,rhs.real()); 
  622.     __im += _RWSTD_STATIC_CAST(double,rhs.imag()); 
  623.     return *this;
  624.   }
  625.  
  626.   inline complex<double>& 
  627.   complex<double>::operator-= (const complex<long double>& rhs) 
  628.   {
  629.     __re -= _RWSTD_STATIC_CAST(double,rhs.real()); 
  630.     __im -= _RWSTD_STATIC_CAST(double,rhs.imag()); 
  631.     return *this;
  632.   }
  633.  
  634.   inline complex<double>& 
  635.   complex<double>::operator*= (const complex<long double>& rhs) 
  636.   {     
  637.     double tmp = __re*_RWSTD_STATIC_CAST(double,rhs.real())-
  638.     __im*_RWSTD_STATIC_CAST(double,rhs.imag()); 
  639.     __im       = __im*_RWSTD_STATIC_CAST(double,rhs.real())+
  640.     __re*_RWSTD_STATIC_CAST(double,rhs.imag()); 
  641.     __re       = tmp; 
  642.     return *this;
  643.   }
  644. #endif
  645. #endif
  646. #endif /* _RWSTD_NO_MEMBER_TEMPLATES */
  647.  
  648. //
  649. // complex<long double> specializations.
  650. //
  651.  
  652. #ifndef _RWSTD_NO_LONGDOUBLE
  653.   inline 
  654.   complex<long double>::complex (const complex<float>& cf)
  655.   : __re(cf.real()), __im(cf.imag()) {}
  656.  
  657.   inline 
  658.   complex<long double>::complex (const complex<double>& cd)
  659.   : __re(cd.real()), __im(cd.imag()) {}
  660.  
  661.   inline complex<long double>&
  662.   complex<long double>::operator+= (long double rhs) 
  663.   {
  664.     __re += rhs; return *this;
  665.   }
  666.  
  667.   inline complex<long double>&
  668.   complex<long double>::operator= (long double rhs) 
  669.   {
  670.     __re = rhs; __im = 0.0; return *this;
  671.   }
  672.  
  673.   inline complex<long double>&
  674.   complex<long double>::operator-= (long double rhs) 
  675.   {
  676.     __re -= rhs;  return *this;
  677.   }
  678.  
  679.   inline complex<long double>&
  680.   complex<long double>::operator*= (long double rhs) 
  681.   {     
  682.     long double tmp = __re*rhs; 
  683.     __im       = __im*rhs; 
  684.     __re       = tmp;
  685.     return *this;
  686.   }
  687. #ifdef _RWSTD_NO_MEMBER_TEMPLATES
  688.   inline complex<long double>& 
  689.   complex<long double>::operator= (const complex<float>& rhs) 
  690.   {
  691.     __re = rhs.real(); __im = rhs.imag(); return *this;
  692.   }
  693.  
  694.   inline complex<long double>& 
  695.   complex<long double>::operator+= (const complex<float>& rhs) 
  696.   {
  697.     __re += rhs.real(); __im += rhs.imag(); return *this;
  698.   }
  699.  
  700.   inline complex<long double>&
  701.   complex<long double>::operator-= (const complex<float>& rhs) 
  702.   {
  703.     __re -= rhs.real(); __im -= rhs.imag(); return *this;
  704.   }
  705.  
  706.   inline complex<long double>& 
  707.   complex<long double>::operator*= (const complex<float>& rhs) 
  708.   {     
  709.     long double tmp = __re*rhs.real()-__im*rhs.imag(); 
  710.     __im             = __im*rhs.real()+__re*rhs.imag(); 
  711.     __re             = tmp;
  712.     return *this;
  713.   }
  714.  
  715.   inline complex<long double>& 
  716.   complex<long double>::operator= (const complex<double>& rhs) 
  717.   {
  718.     __re = rhs.real(); __im = rhs.imag(); return *this;
  719.   }
  720.  
  721.   inline complex<long double>& 
  722.   complex<long double>::operator+= (const complex<double>& rhs) 
  723.   {
  724.     __re += rhs.real(); __im += rhs.imag(); return *this;
  725.   }
  726.  
  727.   inline complex<long double>&
  728.   complex<long double>::operator-= (const complex<double>& rhs) 
  729.   {     
  730.     __re -= rhs.real(); __im -= rhs.imag(); return *this;
  731.   }
  732.  
  733.   inline complex<long double>& 
  734.   complex<long double>::operator*= (const complex<double>& rhs) 
  735.   {     
  736.     long double tmp = __re*rhs.real()-__im*rhs.imag(); 
  737.     __im             = __im*rhs.real()+__re*rhs.imag(); 
  738.     __re             = tmp;
  739.     return *this;
  740.   }
  741.  
  742.   inline complex<long double>&
  743.   complex<long double>::operator= (const complex<long double>& rhs) 
  744.   {     
  745.     __re = rhs.real(); __im = rhs.imag(); return *this;
  746.   }
  747.  
  748.   inline complex<long double>&
  749.   complex<long double>::operator+= (const complex<long double>& rhs) 
  750.   {     
  751.     __re += rhs.real(); __im += rhs.imag(); return *this;
  752.   }
  753.  
  754.   inline complex<long double>& 
  755.   complex<long double>::operator-= (const complex<long double>& rhs) 
  756.   {
  757.     __re -= rhs.real(); __im -= rhs.imag(); return *this;
  758.   }
  759.  
  760.   inline complex<long double>& 
  761.   complex<long double>::operator*= (const complex<long double>& rhs) 
  762.   {     
  763.     long double tmp = __re*rhs.real()-__im*rhs.imag(); 
  764.     __im            = __im*rhs.real()+__re*rhs.imag(); 
  765.     __re            = tmp; 
  766.     return *this;
  767.   }
  768. #endif
  769. #endif /* _RWSTD_NO_MEMBER_TEMPLATES */
  770.  
  771. #ifndef _RWSTD_NO_MEMBER_TEMPLATES
  772.   template <class T>
  773.   template <class X>
  774.   complex<T>&
  775.   complex<T>::operator/= (const complex<X>& rhs)
  776.   {
  777.     T denom = rhs.real()*rhs.real() + rhs.imag()*rhs.imag();
  778.     T re    = (__re*rhs.real()+__im*rhs.imag())/denom;
  779.     T im    = (rhs.real()*__im-__re*rhs.imag())/denom;
  780.     __re    = re;
  781.     __im    = im;
  782.     return *this;
  783.   }
  784.  
  785.   template <class X>
  786.   inline complex<float>& 
  787.   complex<float>::operator/= (const complex<X>& rhs)  
  788.   {
  789.     float denom = rhs.real()*rhs.real() + rhs.imag()*rhs.imag();
  790.     float re    = (__re*rhs.real()+__im*rhs.imag())/denom;
  791.     float im    = (rhs.real()*__im-__re*rhs.imag())/denom;
  792.     __re        = re;
  793.     __im        = im;
  794.     return *this;
  795.   }
  796.  
  797.   template <class X>
  798.   inline complex<double>& 
  799.   complex<double>::operator/= (const complex<X>& rhs)  
  800.   {
  801.     double denom = rhs.real()*rhs.real() + rhs.imag()*rhs.imag();
  802.     double re    = (__re*rhs.real()+__im*rhs.imag())/denom;
  803.     double im    = (rhs.real()*__im-__re*rhs.imag())/denom;
  804.     __re        = re;
  805.     __im        = im;
  806.     return *this;
  807.   }
  808.  
  809. #ifndef _RWSTD_NO_LONGDOUBLE
  810.   template <class X>
  811.   inline complex<long double>& 
  812.   complex<long double>::operator/= (const complex<X>& rhs)  
  813.   {
  814.     long double denom = rhs.real()*rhs.real() + rhs.imag()*rhs.imag();
  815.     long double re    = (__re*rhs.real()+__im*rhs.imag())/denom;
  816.     long double im    = (rhs.real()*__im-__re*rhs.imag())/denom;
  817.     __re        = re;
  818.     __im        = im;
  819.     return *this;
  820.   }
  821. #endif
  822. #else /* No member function templates, have to specialize :-( */
  823.  
  824.   inline complex<float>& 
  825.   complex<float>::operator/= (const complex<float>& rhs)  
  826.   {
  827.     float denom = rhs.real()*rhs.real() + rhs.imag()*rhs.imag();
  828.     float re    = (__re*rhs.real()+__im*rhs.imag())/denom;
  829.     float im    = (rhs.real()*__im-__re*rhs.imag())/denom;
  830.     __re         = re;
  831.     __im         = im;
  832.     return *this;
  833.   }
  834.  
  835. #ifndef _RWSTD_NO_FORWARD_SPECIALIZATIONS
  836.   inline complex<float>& 
  837.   complex<float>::operator/= (const complex<double>& rhs)  
  838.   {
  839.     float denom = _RWSTD_STATIC_CAST(float,rhs.real())*
  840.     _RWSTD_STATIC_CAST(float,rhs.real()) + 
  841.     _RWSTD_STATIC_CAST(float,rhs.imag())*
  842.     _RWSTD_STATIC_CAST(float,rhs.imag());
  843.     float re    = (__re*_RWSTD_STATIC_CAST(float,rhs.real())+
  844.                    __im*_RWSTD_STATIC_CAST(float,rhs.imag()))/denom;
  845.     float im    = (_RWSTD_STATIC_CAST(float,rhs.real())*__im-__re*
  846.                    _RWSTD_STATIC_CAST(float,rhs.imag()))/denom;
  847.     __re        = re;
  848.     __im        = im;
  849.     return *this;
  850.   }
  851.  
  852. #ifndef _RWSTD_NO_LONGDOUBLE
  853.   inline complex<float>& 
  854.   complex<float>::operator/= (const complex<long double>& rhs)  
  855.   {
  856.     float denom = _RWSTD_STATIC_CAST(float,rhs.real())*
  857.     _RWSTD_STATIC_CAST(float,rhs.real()) + 
  858.     _RWSTD_STATIC_CAST(float,rhs.imag())*
  859.     _RWSTD_STATIC_CAST(float,rhs.imag());
  860.     float re    = (__re*_RWSTD_STATIC_CAST(float,rhs.real())+
  861.                    __im*_RWSTD_STATIC_CAST(float,rhs.imag()))/denom;
  862.     float im    = (_RWSTD_STATIC_CAST(float,rhs.real())*__im-
  863.                    __re*_RWSTD_STATIC_CAST(float,rhs.imag()))/denom;
  864.     __re        = re;
  865.     __im        = im;
  866.     return *this;
  867.   }
  868. #endif 
  869. #endif
  870.  
  871.   inline complex<double>& 
  872.   complex<double>::operator/= (const complex<float>& rhs)  
  873.   {
  874.     double denom = rhs.real()*rhs.real() + rhs.imag()*rhs.imag();
  875.     double re    = (__re*rhs.real()+__im*rhs.imag())/denom;
  876.     double im    = (rhs.real()*__im-__re*rhs.imag())/denom;
  877.     __re         = re;
  878.     __im         = im;
  879.     return *this;
  880.   }
  881.  
  882.   inline complex<double>&
  883.   complex<double>::operator/= (const complex<double>& rhs)
  884.   {
  885.     double denom = rhs.real()*rhs.real() + rhs.imag()*rhs.imag();
  886.     double re    = (__re*rhs.real()+__im*rhs.imag())/denom;
  887.     double im    = (rhs.real()*__im-__re*rhs.imag())/denom;
  888.     __re         = re;
  889.     __im         = im;
  890.     return *this;
  891.   }
  892.  
  893. #ifndef _RWSTD_NO_FORWARD_SPECIALIZATIONS
  894. #ifndef _RWSTD_NO_LONGDOUBLE
  895.   inline complex<double>& 
  896.   complex<double>::operator/= (const complex<long double>& rhs)  
  897.   {
  898.     double denom = _RWSTD_STATIC_CAST(double,rhs.real())*
  899.     _RWSTD_STATIC_CAST(double,rhs.real()) + 
  900.     _RWSTD_STATIC_CAST(double,rhs.imag())*
  901.     _RWSTD_STATIC_CAST(double,rhs.imag());
  902.     double re    = (__re*_RWSTD_STATIC_CAST(double,rhs.real())+
  903.                     __im*_RWSTD_STATIC_CAST(double,rhs.imag()))/denom;
  904.     double im    = (_RWSTD_STATIC_CAST(double,rhs.real())*__im-
  905.                     __re*_RWSTD_STATIC_CAST(double,rhs.imag()))/denom;
  906.     __re         = re;
  907.     __im         = im;
  908.     return *this;
  909.   }
  910. #endif
  911. #endif
  912.  
  913. #ifndef _RWSTD_NO_LONGDOUBLE
  914.   inline complex<long double>& 
  915.   complex<long double>::operator/= (const complex<float>& rhs)  
  916.   {
  917.     long double denom = rhs.real()*rhs.real() + rhs.imag()*rhs.imag();
  918.     long double re    = (__re*rhs.real()+__im*rhs.imag())/denom;
  919.     long double im    = (rhs.real()*__im-__re*rhs.imag())/denom;
  920.     __re              = re;
  921.     __im              = im;
  922.     return *this;
  923.   }
  924.  
  925.   inline complex<long double>& 
  926.   complex<long double>::operator/= (const complex<double>& rhs)  
  927.   {
  928.     long double denom = rhs.real()*rhs.real() + rhs.imag()*rhs.imag();
  929.     long double re    = (__re*rhs.real()+__im*rhs.imag())/denom;
  930.     long double im    = (rhs.real()*__im-__re*rhs.imag())/denom;
  931.     __re              = re;
  932.     __im              = im;
  933.     return *this;
  934.   }
  935.  
  936.   inline complex<long double>& 
  937.   complex<long double>::operator/= (const complex<long double>& rhs)  
  938.   {
  939.     long double denom = rhs.real()*rhs.real() + rhs.imag()*rhs.imag();
  940.     long double re    = (__re*rhs.real()+__im*rhs.imag())/denom;
  941.     long double im    = (rhs.real()*__im-__re*rhs.imag())/denom;
  942.     __re              = re;
  943.     __im              = im;
  944.     return *this;
  945.   }
  946. #endif
  947. #endif
  948.  
  949.   inline complex<float>& 
  950.   complex<float>::operator/= (float rhs)  
  951.   {
  952.     float denom = rhs*rhs;
  953.     float re    = (__re*rhs)/denom;
  954.     float im    = (rhs*__im)/denom;
  955.     __re        = re;
  956.     __im        = im;
  957.     return *this;
  958.   }
  959.  
  960.   inline complex<double>& 
  961.   complex<double>::operator/= (double rhs)  
  962.   {
  963.     double denom = rhs*rhs;
  964.     double re    = (__re*rhs)/denom;
  965.     double im    = (rhs*__im)/denom;
  966.     __re         = re;
  967.     __im         = im;
  968.     return *this;
  969.   }
  970. #ifndef _RWSTD_NO_LONGDOUBLE
  971.   inline complex<long double>& 
  972.   complex<long double>::operator/= (long double rhs)  
  973.   {
  974.     long double denom = rhs*rhs;
  975.     long double re    = (__re*rhs)/denom;
  976.     long double im    = (rhs*__im)/denom;
  977.     __re              = re;
  978.     __im              = im;
  979.     return *this;
  980.   }
  981. #endif
  982. //
  983. // complex non-member operations
  984. //
  985.  
  986.   template <class T>
  987.   inline complex<T> operator+ (const complex<T>& lhs, const complex<T>& rhs)
  988.   {
  989.     complex<T> tmp = lhs; return tmp += rhs;
  990.   }
  991.  
  992.   template <class T>
  993.   inline complex<T> operator+ (const complex<T>& lhs, const T& rhs)
  994.   {
  995.     return complex<T>(rhs+lhs.real(), lhs.imag());
  996.   }
  997.  
  998.   template <class T>
  999.   inline complex<T> operator+ (const T& lhs, const complex<T>& rhs)
  1000.   {
  1001.     return complex<T>(lhs+rhs.real(), rhs.imag());
  1002.   }
  1003.  
  1004.   template <class T>
  1005.   inline complex<T> operator- (const complex<T>& lhs, const complex<T>& rhs)
  1006.   {
  1007.     complex<T> tmp = lhs; return tmp -= rhs;
  1008.   }
  1009.  
  1010.   template <class T>
  1011.   inline complex<T> operator- (const complex<T>& lhs, const T& rhs)
  1012.   {
  1013.     return complex<T>(lhs.real()-rhs, lhs.imag());
  1014.   }
  1015.  
  1016.   template <class T>
  1017.   inline complex<T> operator- (const T& lhs, const complex<T>& rhs)
  1018.   {
  1019.     return complex<T>(lhs-rhs.real(), -rhs.imag());
  1020.   }
  1021.  
  1022.   template <class T>
  1023.   inline complex<T> operator* (const complex<T>& lhs, const complex<T>& rhs)
  1024.   {
  1025.     complex<T> tmp = lhs; return tmp *= rhs;
  1026.   }
  1027.  
  1028.   template <class T>
  1029.   inline complex<T> operator* (const complex<T>& lhs, const T& rhs)
  1030.   {
  1031.     return complex<T>(rhs*lhs.real(), rhs*lhs.imag());
  1032.   }
  1033.  
  1034.   template <class T>
  1035.   inline complex<T> operator* (const T& lhs, const complex<T>& rhs)
  1036.   {
  1037.     return complex<T>(lhs*rhs.real(), lhs*rhs.imag());
  1038.   }
  1039.  
  1040.   template <class T>
  1041.   inline complex<T> operator/ (const complex<T>& lhs, const complex<T>& rhs)
  1042.   {
  1043.     complex<T> tmp = lhs; return tmp /= rhs;
  1044.   }
  1045.  
  1046.   template <class T>
  1047.   inline complex<T> operator/ (const complex<T>& lhs, const T& rhs)
  1048.   {
  1049.     return complex<T>(lhs.real()/rhs, lhs.imag()/rhs);
  1050.   }
  1051.  
  1052.   template <class T>
  1053.   inline complex<T> operator/ (const T& lhs, const complex<T>& rhs)
  1054.   {
  1055.     register T denom = rhs.real()*rhs.real() + rhs.imag()*rhs.imag();
  1056.     return complex<T>(lhs*rhs.real()/denom,(-lhs*rhs.imag())/denom);
  1057.   }
  1058.  
  1059.   template <class T>
  1060.   inline complex<T> operator+ (const complex<T>& lhs) { return lhs; }
  1061.  
  1062.   template <class T>
  1063.   inline complex<T> operator- (const complex<T>& lhs)
  1064.   {
  1065.     return complex<T>(-lhs.real(), -lhs.imag());
  1066.   } 
  1067.  
  1068.   template <class T>
  1069.   inline bool operator== (const complex<T>& lhs, const complex<T>& rhs)
  1070.   {
  1071.     return lhs.real() == rhs.real() && lhs.imag() == rhs.imag();
  1072.   } 
  1073.  
  1074.   template <class T>
  1075.   inline bool operator== (const T& lhs, const complex<T>& rhs)
  1076.   {
  1077.     return lhs == rhs.real() && rhs.imag() == 0;
  1078.   } 
  1079.  
  1080.   template <class T>
  1081.   inline bool operator== (const complex<T>& lhs, const T& rhs)
  1082.   {
  1083.     return lhs.real() == rhs && lhs.imag() == 0;
  1084.   } 
  1085.  
  1086. #ifndef _RWSTD_NO_NAMESPACE
  1087.   template <class T>
  1088.   inline bool operator!= (const complex<T>& lhs, const complex<T>& rhs)
  1089.   {
  1090.     return lhs.real() != rhs.real() || lhs.imag() != rhs.imag();
  1091.   } 
  1092. #endif
  1093.  
  1094.   template <class T>
  1095.   inline bool operator!= (const T& lhs, const complex<T>& rhs)
  1096.   {
  1097.     return lhs != rhs.real() || rhs.imag() != 0;
  1098.   } 
  1099.  
  1100.   template <class T>
  1101.   inline bool operator!= (const complex<T>& lhs, const T& rhs)
  1102.   {
  1103.     return lhs.real() != rhs || lhs.imag() != 0;
  1104.   } 
  1105.  
  1106. //
  1107. // complex value operations
  1108. //
  1109.  
  1110. // Cope with namespace problems
  1111. #if defined(_RWSTD_NO_NEW_HEADER) && !defined(_RWSTD_NO_NAMESPACE) 
  1112. #define _RWSTD_C_SCOPE_SIN ::sin
  1113. #define _RWSTD_C_SCOPE_SINH ::sinh
  1114. #define _RWSTD_C_SCOPE_COS ::cos
  1115. #define _RWSTD_C_SCOPE_COSH ::cosh
  1116. #define _RWSTD_C_SCOPE_ATAN2 ::atan2
  1117. #define _RWSTD_C_SCOPE_ATAN ::atan
  1118. #define _RWSTD_C_SCOPE_EXP ::exp
  1119. #define _RWSTD_C_SCOPE_POW ::pow
  1120. #define _RWSTD_C_SCOPE_SQRT ::sqrt
  1121. #define _RWSTD_C_SCOPE_LOG ::log
  1122. #define _RWSTD_C_SCOPE_LOG10 ::log10
  1123. #else
  1124. #define _RWSTD_C_SCOPE_SIN sin
  1125. #define _RWSTD_C_SCOPE_SINH sinh
  1126. #define _RWSTD_C_SCOPE_COS cos
  1127. #define _RWSTD_C_SCOPE_COSH cosh
  1128. #define _RWSTD_C_SCOPE_ATAN2 atan2
  1129. #define _RWSTD_C_SCOPE_ATAN atan
  1130. #define _RWSTD_C_SCOPE_EXP exp
  1131. #define _RWSTD_C_SCOPE_POW pow
  1132. #define _RWSTD_C_SCOPE_SQRT sqrt
  1133. #define _RWSTD_C_SCOPE_LOG log
  1134. #define _RWSTD_C_SCOPE_LOG10 log10
  1135. #endif
  1136.  
  1137.   template<class T>
  1138.   inline T real (const complex<T>& a) { return a.real(); }
  1139.  
  1140.   template<class T>
  1141.   inline T imag (const complex<T>& a) { return a.imag(); }
  1142.  
  1143.   template <class T>
  1144.   inline T norm (const complex<T>& a)
  1145.   {
  1146.     return a.real()*a.real() + a.imag()*a.imag();
  1147.   }
  1148.  
  1149.   template <class T>
  1150.   inline T abs (const complex<T>& a) { return (_RWSTD_C_SCOPE_SQRT(norm(a))); }
  1151.  
  1152. //
  1153. // We guarantee that arg(complex<T>(0,0)) == 0.
  1154. //
  1155.  
  1156.   template <class T>
  1157.   inline T arg (const complex<T>& a)
  1158.   {
  1159.     return a == complex<T>(0,0) ? T(0) : _RWSTD_C_SCOPE_ATAN2(a.imag(), a.real());
  1160.   }
  1161.  
  1162.   template <class T>
  1163.   complex<T> conj (const complex<T>& a)
  1164.   {
  1165.     return complex<T>(a.real(), -a.imag());
  1166.   }
  1167.  
  1168. #if defined(_MSC_VER) &&  _MSC_VER < 901
  1169. //
  1170. // A very bizarre Microsoft problem.
  1171. //
  1172.   _RWSTD_TEMPLATE 
  1173.   inline complex<float> conj (const complex<float>& a)
  1174.   {
  1175.     return complex<float>(a.real(), -a.imag());
  1176.   }
  1177.   _RWSTD_TEMPLATE 
  1178.   inline complex<double> conj (const complex<double>& a)
  1179.   {
  1180.     return complex<double>(a.real(), -a.imag());
  1181.   }
  1182.  
  1183. #ifndef _RWSTD_NO_LONGDOUBLE
  1184.   _RWSTD_TEMPLATE 
  1185.   inline complex<long double> conj (const complex<long double>& a)
  1186.   {
  1187.     return complex<long double>(a.real(), -a.imag());
  1188.   }
  1189. #endif
  1190. #endif
  1191.  
  1192.   template <class T>
  1193. #ifndef _RWSTD_NO_INIT_CONST_TEMPLATE_REF_ARG
  1194.   inline complex<T> polar (const T& r, const T& theta = 0)
  1195. #else
  1196.   inline complex<T> polar (const T& r, const T& theta)
  1197. #endif
  1198.   {
  1199.     return complex<T>(r*_RWSTD_C_SCOPE_COS(theta), r*_RWSTD_C_SCOPE_SIN(theta));
  1200.   }
  1201.  
  1202. //
  1203. // transcendentals
  1204. //
  1205.  
  1206. //
  1207. // complex<T> cosine of complex<T> number a
  1208. //      cos (a) = cos u * cosh v - i * sin u * sinh v
  1209. //
  1210.  
  1211.   template <class T>
  1212.   inline complex<T> cos (const complex<T>& a)
  1213.   {
  1214.     return complex<T>(_RWSTD_C_SCOPE_COS(a.real())*_RWSTD_C_SCOPE_COSH(a.imag()),
  1215.                       -_RWSTD_C_SCOPE_SIN(a.real())*_RWSTD_C_SCOPE_SINH(a.imag()));
  1216.   }
  1217.  
  1218. //
  1219. // complex<T> hyperbolic cosine of complex<T> number a
  1220. //      cosh (a) = cosh u * cosv + i * sinh u * sin v
  1221. //
  1222.  
  1223.   template <class T>
  1224.   inline complex<T> cosh (const complex<T>& a)
  1225.   {
  1226.     return complex<T>(_RWSTD_C_SCOPE_COSH(a.real())*_RWSTD_C_SCOPE_COS(a.imag()),
  1227.                       _RWSTD_C_SCOPE_SINH(a.real())*_RWSTD_C_SCOPE_SIN(a.imag()));
  1228.   }
  1229.  
  1230. //
  1231. // complex<T> exponential of  complex<T> number a
  1232. //      exp (a) = exp(u) * (cos v + i * sin v)
  1233. //
  1234.  
  1235.   template <class T>
  1236.   inline complex<T> exp (const complex<T>& a)
  1237.   {
  1238.     register T e = _RWSTD_C_SCOPE_EXP(a.real());
  1239.     return complex<T>(e*_RWSTD_C_SCOPE_COS(a.imag()), e*_RWSTD_C_SCOPE_SIN(a.imag()));
  1240.   }
  1241.  
  1242. //
  1243. // complex<T> natural log of complex<T> number a
  1244. //      log(a) = log(r) + i * theta
  1245. //
  1246.  
  1247.   template <class T>
  1248.   inline complex<T> log (const complex<T>& a)
  1249.   {
  1250.     return complex<T>(_RWSTD_C_SCOPE_LOG(abs(a)), arg(a));
  1251.   }
  1252.  
  1253.   template <class T>
  1254.   complex<T> log10 (const complex<T>& a);
  1255.  
  1256. //
  1257. // For all the power functions:
  1258. //
  1259. //   0**0 == 1
  1260. //   0**x == 0 for x != 0
  1261. //
  1262.  
  1263. //
  1264. // complex<T> number a raised to an integer power n
  1265. //
  1266. // a**n = r**n * (cos(n theta) + i sin (n theta))
  1267. //
  1268.  
  1269.   template <class T>
  1270.   inline complex<T> pow (const complex<T>& a, int n)
  1271.   {
  1272.     if (a == complex<T>(0,0))
  1273.     {
  1274.       if (n == 0) 
  1275.         return complex<T>(1,0);
  1276.       else
  1277.         return complex<T>(0,0);
  1278.     }
  1279.  
  1280.     if (a.imag() == 0)
  1281.     {
  1282.       if (a.real() < 0)
  1283.         return pow(a, complex<T>(n,0));
  1284.       else
  1285. #ifndef _RWSTD_NO_OVERLOAD_C_POW
  1286.         return complex<T>(_RWSTD_C_SCOPE_POW(a.real(),T(n)), 0);
  1287. #else
  1288.       return complex<T>(_RWSTD_C_SCOPE_POW(double(a.real()),double(n)), 0);
  1289. #endif /* _RWSTD_NO_OVERLOAD_C_POW */
  1290.     }
  1291.  
  1292. #ifndef _RWSTD_NO_OVERLOAD_C_POW
  1293.     register T r  = _RWSTD_C_SCOPE_POW(T(abs(a)), T(n));
  1294. #else
  1295.     register T r  = _RWSTD_C_SCOPE_POW(double(abs(a)), double(n));
  1296. #endif
  1297.  
  1298.     register T th = T(n) * arg(a);
  1299.  
  1300.     return complex<T>(r*_RWSTD_C_SCOPE_COS(th), r*_RWSTD_C_SCOPE_SIN(th));
  1301.   }
  1302. //
  1303. // complex<T> number a raised to a real power s
  1304. //
  1305. // a**s = exp(s * log(a))
  1306. //
  1307.  
  1308.   template <class T>
  1309.   inline complex<T> pow (const complex<T>& a, const T& s)
  1310.   {
  1311.     if (a == complex<T>(0,0))
  1312.     {
  1313.       if (s == T(0))
  1314.         return complex<T>(1,0);
  1315.       else
  1316.         return complex<T>(0,0);
  1317.     }
  1318.     if (a.imag() == 0)
  1319.     {
  1320.       if (a.real() < 0)
  1321.         return pow(a, complex<T>(s,0));
  1322.       else
  1323. #ifndef _RWSTD_NO_OVERLOAD_C_POW
  1324.         return complex<T>(_RWSTD_C_SCOPE_POW(a.real(),s), 0);
  1325. #else
  1326.       return complex<T>(_RWSTD_C_SCOPE_POW(double(a.real()),double(s)), 0);
  1327. #endif /* _RWSTD_NO_OVERLOAD_C_POW */
  1328.     }
  1329.     return exp(s*log(a));
  1330.   }   
  1331. //
  1332. // real number s raised to a complex<T> power a
  1333. //
  1334. //  s**a = exp(a * log (s))
  1335. //
  1336.  
  1337.   template <class T>
  1338.   inline complex<T> pow (const T& s, const complex<T>& a)
  1339.   {
  1340.     if (s == T(0))
  1341.     {
  1342.       if (a == complex<T>(0,0)) 
  1343.         return complex<T>(1,0);
  1344.       else
  1345.         return complex<T>(0,0);
  1346.     }
  1347.     if (s < 0)
  1348.       return pow(complex<T>(s,0), a);
  1349.  
  1350.     if (a.imag() == 0)
  1351. #ifndef _RWSTD_NO_OVERLOAD_C_POW
  1352.       return complex<T>(_RWSTD_C_SCOPE_POW(s, a.real()), 0);
  1353. #else
  1354.     return complex<T>(_RWSTD_C_SCOPE_POW(double(s), double(a.real())), 0);
  1355. #endif /* _RWSTD_NO_OVERLOAD_C_POW */
  1356.  
  1357.     return complex<T>(exp(a * (T) _RWSTD_C_SCOPE_LOG(s)));
  1358.   }
  1359. //
  1360. // complex<T> number a1 raised to a complex<T> power a2
  1361. //
  1362. // a1**a2 = rho * (cos(phi) + i sin(phi))
  1363. //      rho = r1 **u2   *  exp (-v2* theta1)
  1364. //      phi = v2 * log(r1) + u2 * theta1
  1365. //
  1366.  
  1367.   template <class T>
  1368.   inline complex<T> pow (const complex<T>& a1, const complex<T>& a2)
  1369.   {
  1370.     if (a1 == complex<T>(0,0))
  1371.     {
  1372.       if (a2 == complex<T>(0,0))
  1373.         return complex<T>(1,0);
  1374.       else
  1375.         return complex<T>(0,0);
  1376.     }
  1377.  
  1378.     T r1   = abs(a1);
  1379.     T u2   = real(a2);
  1380.     T v2   = imag(a2);
  1381.     T th1  = arg(a1);
  1382. #ifndef _RWSTD_NO_OVERLOAD_C_POW
  1383.     T rho  = _RWSTD_C_SCOPE_POW(r1, u2) * _RWSTD_C_SCOPE_EXP(-v2 *th1);
  1384. #else
  1385.     T rho  = _RWSTD_C_SCOPE_POW(double(r1), double(u2)) * _RWSTD_C_SCOPE_EXP(-v2 *th1);
  1386. #endif /* _RWSTD_NO_OVERLOAD_C_POW */
  1387.     T phi  = v2 * _RWSTD_C_SCOPE_LOG(r1) + u2 * th1;
  1388.  
  1389.     return complex<T>(rho*_RWSTD_C_SCOPE_COS(phi), rho*_RWSTD_C_SCOPE_SIN(phi));
  1390.   }      
  1391. //
  1392. // complex<T> sine of complex<T> number a
  1393. //      sin (a) = sin u * cosh v + i * cos u * sinh v
  1394. //
  1395.   template <class T>
  1396.   inline complex<T> sin (const complex<T>& a)
  1397.   {
  1398.     return complex<T>(_RWSTD_C_SCOPE_SIN(a.real())*_RWSTD_C_SCOPE_COSH(a.imag()),
  1399.                       _RWSTD_C_SCOPE_COS(a.real())*_RWSTD_C_SCOPE_SINH(a.imag()));
  1400.   }
  1401.  
  1402. //
  1403. // complex<T> hyperbolic sine of complex<T> number a
  1404. //      sinh (a) = sinh u cos v + i cosh u sin v
  1405. //
  1406.   template <class T>
  1407.   inline complex<T> sinh (const complex<T>& a)
  1408.   {
  1409.     return complex<T>(_RWSTD_C_SCOPE_SINH(a.real())*_RWSTD_C_SCOPE_COS(a.imag()),
  1410.                       _RWSTD_C_SCOPE_COSH(a.real())*_RWSTD_C_SCOPE_SIN(a.imag()));
  1411.   }
  1412.  
  1413. //
  1414. // complex<T> square root of complex<T> number a
  1415. //      sqrt(a) = sqrt(r) * ( cos (theta/2) + i sin (theta/2) )
  1416. //
  1417.   template <class T>
  1418.   inline complex<T> sqrt (const complex<T>& a)
  1419.   {
  1420.     register T r  = _RWSTD_C_SCOPE_SQRT(abs(a));
  1421.     register T th = arg(a)/2.;
  1422.     return complex<T>(r*_RWSTD_C_SCOPE_COS(th), r*_RWSTD_C_SCOPE_SIN(th));
  1423.   }
  1424.  
  1425.   template <class T>
  1426.   inline complex<T> tan (const complex<T>& a) { return sin(a)/cos(a); }
  1427.  
  1428.   template <class T>
  1429.   inline complex<T> tanh (const complex<T>& a) { return sinh(a)/cosh(a);
  1430.   }
  1431. #ifdef _RW_STD_IOSTREAM
  1432.  
  1433.   template <class T,class charT, class traits>
  1434.   basic_istream<charT, traits >& _RWSTDExportTemplate 
  1435.   operator>> (basic_istream<charT, traits >& is,complex<T>& x);
  1436.   template <class T,class charT,class traits>
  1437.  
  1438.   basic_ostream<charT,traits >& _RWSTDExportTemplate 
  1439.   operator<< (basic_ostream<charT, traits >& os,const complex<T>& x);
  1440.  
  1441. #else
  1442.  
  1443.   template <class T>
  1444.   istream& _RWSTDExportTemplate operator>> (istream& is, complex<T>& x);
  1445.   template <class T>
  1446.   ostream& _RWSTDExportTemplate operator<< (ostream& os, const complex<T>& x);
  1447.  
  1448. #endif
  1449.  
  1450. #ifndef _RWSTD_NO_NAMESPACE
  1451. }
  1452. #endif
  1453.  
  1454. #if defined(_RWSTD_NO_DESTROY_BUILTIN) || defined(_RWSTD_NO_DESTROY_NONBUILTIN)
  1455.  
  1456. #ifndef _RWSTD_NO_NAMESPACE
  1457. namespace __rogue_wave_std {
  1458. #endif
  1459. //
  1460. // Specializations of STL destroy for complex.
  1461. //
  1462.   inline void __destroy (complex<float>**)         {}
  1463.   inline void __destroy (complex<float>***)        {}
  1464.   inline void __destroy (complex<float>****)       {}
  1465.   inline void __destroy (complex<double>**)        {}
  1466.   inline void __destroy (complex<double>***)       {}
  1467.   inline void __destroy (complex<double>****)      {}
  1468. #ifndef _RWSTD_NO_LONGDOUBLE
  1469.   inline void __destroy (complex<long double>**)   {}
  1470.   inline void __destroy (complex<long double>***)  {}
  1471.   inline void __destroy (complex<long double>****) {}
  1472. #endif
  1473.  
  1474. #ifndef _RWSTD_NO_NAMESPACE
  1475. }
  1476. #endif
  1477. #endif
  1478.  
  1479. #ifdef _RWSTD_NO_TEMPLATE_REPOSITORY
  1480. #include <complex.cc>
  1481. #endif
  1482. #endif /* __STD_COMPLEX */
  1483.  
  1484. #ifndef __USING_STD_NAMES__
  1485.   using namespace std;
  1486. #endif
  1487.  
  1488. #pragma option pop
  1489. #endif /* __COMPLEX_H */
  1490.