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