home *** CD-ROM | disk | FTP | other *** search
/ CD Actual 9 / CDACTUAL9.iso / progs / CB / DATA.Z / COMPLEX.H < prev    next >
Encoding:
C/C++ Source or Header  |  1996-10-11  |  48.8 KB  |  1,727 lines

  1. /* complex.h
  2.  
  3.     Complex Number Library - Include File
  4.     class complex:  declarations for complex numbers.
  5.  
  6. All function names, member names, and operators have been borrowed
  7. from AT&T C++, except for the addition of:
  8.  
  9.     friend complex _RTLENTRY acos(complex _FAR &);
  10.     friend complex _RTLENTRY asin(complex _FAR &);
  11.     friend complex _RTLENTRY atan(complex _FAR &);
  12.     friend complex _RTLENTRY log10(complex _FAR &);
  13.     friend complex _RTLENTRY tan(complex _FAR &);
  14.     friend complex _RTLENTRY tanh(complex _FAR &);
  15.     complex _RTLENTRY operator+();
  16.     complex _RTLENTRY operator-();
  17. */
  18.  
  19. /* $Copyright: 1990$ */
  20. /* $Revision:   8.2  $ */
  21.  
  22. #ifndef __cplusplus
  23. #error Must use C++ for the type complex.
  24. #endif
  25.  
  26. #if !defined(__USING_STD_NAMES__)
  27.  
  28. #if !defined(__COMPLEX_H)
  29. #define __COMPLEX_H
  30.  
  31.  
  32. #if !defined(___DEFS_H)
  33. #include <_defs.h>
  34. #endif
  35.  
  36. #if !defined(__MATH_H)
  37. #include <math.h>
  38. #endif
  39.  
  40. #if !defined(__IOSTREAM_H)
  41. #include <iostream.h>
  42. #endif
  43.  
  44.  
  45. #if !defined(RC_INVOKED)
  46.  
  47. #if defined(__BCOPT__)
  48. #if !defined(_RTL_ALLOW_po) && !defined(__FLAT__)
  49. #pragma option -po-     // disable Object data calling convention
  50. #endif
  51. #endif
  52.  
  53. #pragma option -Vo-
  54.  
  55. #if defined(__STDC__)
  56. #pragma warn -nak
  57. #endif
  58.  
  59. #endif  /* !RC_INVOKED */
  60.  
  61.  
  62. class _EXPCLASS complex {
  63.  
  64. public:
  65.     // constructors
  66.     _RTLENTRY complex(double __re_val, double __im_val=0);
  67.     _RTLENTRY complex();
  68.  
  69.     // complex manipulations
  70.     friend double  _RTLENTRY _EXPFUNC real(const complex _FAR &);   // the real part
  71.     friend double  _RTLENTRY _EXPFUNC imag(const complex _FAR &);   // the imaginary part
  72.     friend complex _RTLENTRY _EXPFUNC conj(const complex _FAR &);   // the complex conjugate
  73.     friend double  _RTLENTRY _EXPFUNC norm(const complex _FAR &);   // the square of the magnitude
  74.     friend double  _RTLENTRY _EXPFUNC arg(const complex _FAR &);    // the angle in the plane
  75.  
  76.     // Create a complex object given polar coordinates
  77.     friend complex _RTLENTRY _EXPFUNC polar(double __mag, double __angle=0);
  78.  
  79.     // Overloaded ANSI C math functions
  80.     friend double  _RTLENTRY _EXPFUNC abs(const complex _FAR &);
  81.     friend complex _RTLENTRY _EXPFUNC acos(const complex _FAR &);
  82.     friend complex _RTLENTRY _EXPFUNC asin(const complex _FAR &);
  83.     friend complex _RTLENTRY _EXPFUNC atan(const complex _FAR &);
  84.     friend complex _RTLENTRY _EXPFUNC cos(const complex _FAR &);
  85.     friend complex _RTLENTRY _EXPFUNC cosh(const complex _FAR &);
  86.     friend complex _RTLENTRY _EXPFUNC exp(const complex _FAR &);
  87.     friend complex _RTLENTRY _EXPFUNC log(const complex _FAR &);
  88.     friend complex _RTLENTRY _EXPFUNC log10(const complex _FAR &);
  89.     friend complex _RTLENTRY _EXPFUNC pow(const complex _FAR & __base, double __expon);
  90.     friend complex _RTLENTRY _EXPFUNC pow(double __base, const complex _FAR & __expon);
  91.     friend complex _RTLENTRY _EXPFUNC pow(const complex _FAR & __base, const complex _FAR & __expon);
  92.     friend complex _RTLENTRY _EXPFUNC sin(const complex _FAR &);
  93.     friend complex _RTLENTRY _EXPFUNC sinh(const complex _FAR &);
  94.     friend complex _RTLENTRY _EXPFUNC sqrt(const complex _FAR &);
  95.     friend complex _RTLENTRY _EXPFUNC tan(const complex _FAR &);
  96.     friend complex _RTLENTRY _EXPFUNC tanh(const complex _FAR &);
  97.  
  98.     // Binary Operator Functions
  99.     friend complex _RTLENTRY _EXPFUNC operator+(const complex _FAR &, const complex _FAR &);
  100.     friend complex _RTLENTRY _EXPFUNC operator+(double, const complex _FAR &);
  101.     friend complex _RTLENTRY _EXPFUNC operator+(const complex _FAR &, double);
  102.     friend complex _RTLENTRY _EXPFUNC operator-(const complex _FAR &, const complex _FAR &);
  103.     friend complex _RTLENTRY _EXPFUNC operator-(double, const complex _FAR &);
  104.     friend complex _RTLENTRY _EXPFUNC operator-(const complex _FAR &, double);
  105.     friend complex _RTLENTRY _EXPFUNC operator*(const complex _FAR &, const complex _FAR &);
  106.     friend complex _RTLENTRY _EXPFUNC operator*(const complex _FAR &, double);
  107.     friend complex _RTLENTRY _EXPFUNC operator*(double, const complex _FAR &);
  108.     friend complex _RTLENTRY _EXPFUNC operator/(const complex _FAR &, const complex _FAR &);
  109.     friend complex _RTLENTRY _EXPFUNC operator/(const complex _FAR &, double);
  110.     friend complex _RTLENTRY _EXPFUNC operator/(double, const complex _FAR &);
  111.     friend int _RTLENTRY _EXPFUNC operator==(const complex _FAR &, const complex _FAR &);
  112.     friend int _RTLENTRY _EXPFUNC operator!=(const complex _FAR &, const complex _FAR &);
  113.     complex _FAR & _RTLENTRY operator+=(const complex _FAR &);
  114.     complex _FAR & _RTLENTRY operator+=(double);
  115.     complex _FAR & _RTLENTRY operator-=(const complex _FAR &);
  116.     complex _FAR & _RTLENTRY operator-=(double);
  117.     complex _FAR & _RTLENTRY operator*=(const complex _FAR &);
  118.     complex _FAR & _RTLENTRY operator*=(double);
  119.     complex _FAR & _RTLENTRY operator/=(const complex _FAR &);
  120.     complex _FAR & _RTLENTRY operator/=(double);
  121.     complex _RTLENTRY operator+();
  122.     complex _RTLENTRY operator-();
  123.  
  124. // Implementation
  125. private:
  126.         double re, im;
  127. };
  128.  
  129.  
  130. // Inline complex functions
  131.  
  132. inline _RTLENTRY complex::complex(double __re_val, double __im_val)
  133. {
  134.     re = __re_val;
  135.     im = __im_val;
  136. }
  137.  
  138. inline _RTLENTRY complex::complex()
  139. {
  140. /* if you want your complex numbers initialized ...
  141.     re = im = 0;
  142. */
  143. }
  144.  
  145. inline complex _RTLENTRY complex::operator+()
  146. {
  147.     return *this;
  148. }
  149.  
  150. inline complex _RTLENTRY complex::operator-()
  151. {
  152.     return complex(-re, -im);
  153. }
  154.  
  155.  
  156. // Definitions of compound-assignment operator member functions
  157.  
  158. inline complex _FAR & _RTLENTRY complex::operator+=(const complex _FAR & __z2)
  159. {
  160.     re += __z2.re;
  161.     im += __z2.im;
  162.     return *this;
  163. }
  164.  
  165. inline complex _FAR & _RTLENTRY complex::operator+=(double __re_val2)
  166. {
  167.     re += __re_val2;
  168.     return *this;
  169. }
  170.  
  171. inline complex _FAR & _RTLENTRY complex::operator-=(const complex _FAR & __z2)
  172. {
  173.     re -= __z2.re;
  174.     im -= __z2.im;
  175.     return *this;
  176. }
  177.  
  178. inline complex _FAR & _RTLENTRY complex::operator-=(double __re_val2)
  179. {
  180.     re -= __re_val2;
  181.     return *this;
  182. }
  183.  
  184. inline complex _FAR & _RTLENTRY complex::operator*=(double __re_val2)
  185. {
  186.     re *= __re_val2;
  187.     im *= __re_val2;
  188.     return *this;
  189. }
  190.  
  191. inline complex _FAR & _RTLENTRY complex::operator/=(double __re_val2)
  192. {
  193.     re /= __re_val2;
  194.     im /= __re_val2;
  195.     return *this;
  196. }
  197.  
  198.  
  199. // Definitions of non-member complex functions
  200.  
  201. inline double _RTLENTRY real(const complex _FAR & __z)
  202. {
  203.     return __z.re;
  204. }
  205.  
  206. inline double _RTLENTRY imag(const complex _FAR & __z)
  207. {
  208.     return __z.im;
  209. }
  210.  
  211. inline complex _RTLENTRY conj(const complex _FAR & __z)
  212. {
  213.     return complex(__z.re, -__z.im);
  214. }
  215.  
  216. inline complex _RTLENTRY polar(double __mag, double __angle)
  217. {
  218.     return complex(__mag*cos(__angle), __mag*sin(__angle));
  219. }
  220.  
  221.  
  222. // Definitions of non-member binary operator functions
  223.  
  224. inline complex _RTLENTRY operator+(const complex _FAR & __z1, const complex _FAR & __z2)
  225. {
  226.     return complex(__z1.re + __z2.re, __z1.im + __z2.im);
  227. }
  228.  
  229. inline complex _RTLENTRY operator+(double __re_val1, const complex _FAR & __z2)
  230. {
  231.     return complex(__re_val1 + __z2.re, __z2.im);
  232. }
  233.  
  234. inline complex _RTLENTRY operator+(const complex _FAR & __z1, double __re_val2)
  235. {
  236.     return complex(__z1.re + __re_val2, __z1.im);
  237. }
  238.  
  239. inline complex _RTLENTRY operator-(const complex _FAR & __z1, const complex _FAR & __z2)
  240. {
  241.     return complex(__z1.re - __z2.re, __z1.im - __z2.im);
  242. }
  243.  
  244. inline complex _RTLENTRY operator-(double __re_val1, const complex _FAR & __z2)
  245. {
  246.     return complex(__re_val1 - __z2.re, -__z2.im);
  247. }
  248.  
  249. inline complex _RTLENTRY operator-(const complex _FAR & __z1, double __re_val2)
  250. {
  251.     return complex(__z1.re - __re_val2, __z1.im);
  252. }
  253.  
  254. inline complex _RTLENTRY operator*(const complex _FAR & __z1, double __re_val2)
  255. {
  256.     return complex(__z1.re*__re_val2, __z1.im*__re_val2);
  257. }
  258.  
  259. inline complex _RTLENTRY operator*(double __re_val1, const complex _FAR & __z2)
  260. {
  261.     return complex(__z2.re*__re_val1, __z2.im*__re_val1);
  262. }
  263.  
  264. inline complex _RTLENTRY operator/(const complex _FAR & __z1, double __re_val2)
  265. {
  266.     return complex(__z1.re/__re_val2, __z1.im/__re_val2);
  267. }
  268.  
  269. inline int _RTLENTRY operator==(const complex _FAR & __z1, const complex _FAR & __z2)
  270. {
  271.     return __z1.re == __z2.re && __z1.im == __z2.im;
  272. }
  273.  
  274. inline int _RTLENTRY operator!=(const complex _FAR & __z1, const complex _FAR & __z2)
  275. {
  276.     return __z1.re != __z2.re || __z1.im != __z2.im;
  277. }
  278.  
  279.  
  280. // Complex stream I/O
  281.  
  282. ostream _FAR & _RTLENTRY _EXPFUNC operator<<(ostream _FAR &, const complex _FAR &);
  283. istream _FAR & _RTLENTRY _EXPFUNC operator>>(istream _FAR &, complex _FAR &);
  284.  
  285.  
  286. #if !defined(RC_INVOKED)
  287.  
  288. #if defined(__STDC__)
  289. #pragma warn .nak
  290. #endif
  291.  
  292. #pragma option -Vo.
  293.  
  294. #if defined(__BCOPT__)
  295. #if !defined(_RTL_ALLOW_po) && !defined(__FLAT__)
  296. #pragma option -po.     // restore Object data calling convention
  297. #endif
  298. #endif
  299.  
  300. #endif  /* !RC_INVOKED */
  301.  
  302.  
  303. #endif  // __COMPLEX_H
  304.  
  305. #else   // __USING_STD_NAMES__
  306.  
  307. #ifndef __STD_COMPLEX
  308. #define __STD_COMPLEX
  309.  
  310. /***************************************************************************
  311.  *
  312.  * complex - Declaration for the Standard Library complex class
  313.  *
  314.  * $Id: complex,v 1.58 1995/10/04 00:40:32 hart Exp $
  315.  *
  316.  ***************************************************************************
  317.  *
  318.  * (c) Copyright 1994, 1995 Rogue Wave Software, Inc.
  319.  * ALL RIGHTS RESERVED
  320.  *
  321.  * The software and information contained herein are proprietary to, and
  322.  * comprise valuable trade secrets of, Rogue Wave Software, Inc., which
  323.  * intends to preserve as trade secrets such software and information.
  324.  * This software is furnished pursuant to a written license agreement and
  325.  * may be used, copied, transmitted, and stored only in accordance with
  326.  * the terms of such license and with the inclusion of the above copyright
  327.  * notice.  This software and information or any other copies thereof may
  328.  * not be provided or otherwise made available to any other person.
  329.  *
  330.  * Notwithstanding any other lease or license that may pertain to, or
  331.  * accompany the delivery of, this computer software and information, the
  332.  * rights of the Government regarding its use, reproduction and disclosure
  333.  * are as set forth in Section 52.227-19 of the FARS Computer
  334.  * Software-Restricted Rights clause.
  335.  *
  336.  * Use, duplication, or disclosure by the Government is subject to
  337.  * restrictions as set forth in subparagraph (c)(1)(ii) of the Rights in
  338.  * Technical Data and Computer Software clause at DFARS 252.227-7013.
  339.  * Contractor/Manufacturer is Rogue Wave Software, Inc.,
  340.  * P.O. Box 2328, Corvallis, Oregon 97339.
  341.  *
  342.  * This computer software and information is distributed with "restricted
  343.  * rights."  Use, duplication or disclosure is subject to restrictions as
  344.  * set forth in NASA FAR SUP 18-52.227-79 (April 1985) "Commercial
  345.  * Computer Software-Restricted Rights (April 1985)."  If the Clause at
  346.  * 18-52.227-74 "Rights in Data General" is specified in the contract,
  347.  * then the "Alternate III" clause applies.
  348.  *
  349.  **************************************************************************/
  350.  
  351. #include <stdcomp.h>
  352. #include <stddefs.h>
  353.  
  354. //
  355. // Hack to get around extraneous exception specification bug in math stuff.
  356. //
  357. #ifdef exception
  358. #undef exception
  359. #else
  360. #define exception math_exception
  361. #endif
  362.  
  363. #ifndef RWSTD_NO_NEW_HEADER
  364. #include <cmath>
  365. #else
  366. #include <math.h>
  367. #endif
  368.  
  369. //
  370. // Undo hack.
  371. //
  372. #ifdef exception
  373. #undef exception
  374. #endif
  375.  
  376. //
  377. // MSVC provides it's own complex
  378. //
  379. #ifdef _MSC_VER
  380. #ifdef complex
  381. #undef complex
  382. #endif
  383. #endif
  384.  
  385. #include <utility>
  386.  
  387. #ifdef RW_STD_IOSTREAM
  388. #include <iostream>
  389. #else
  390. #include <iostream.h>
  391. #endif
  392.  
  393. #ifndef RWSTD_NO_NAMESPACE
  394. namespace std {
  395. #endif
  396.  
  397. #ifndef RWSTD_NO_FORWARD_SPECIALIZATIONS
  398. template <class T>
  399. class complex
  400. {
  401.   public:
  402.     complex (const T& re_arg=0, const T& imag_arg=0) { re_=re_arg; im_=imag_arg; }
  403.  
  404.     T imag () const { return im_; }
  405.     T real () const { return re_; }
  406.  
  407. #ifndef RWSTD_NO_MEMBER_TEMPLATES
  408.     template <class X> complex (const complex<X>& rhs) {re_=rhs.real(); im_=rhs.imag();}
  409.  
  410.     template <class X> complex<T>& operator=  (const complex<X>& rhs) {re_=rhs.real(); im_=rhs.imag(); return *this;}
  411.     template <class X> complex<T>& operator+= (const complex<X>& rhs) {re_+=rhs.real(); im_+=rhs.imag(); return *this;}
  412.     template <class X> complex<T>& operator-= (const complex<X>& rhs) {re_-=rhs.real(); im_-=rhs.imag(); return *this;}
  413.     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;}
  414.     template <class X> complex<T>& operator/= (const complex<X>&);
  415. #endif
  416.  
  417.   private:
  418.     T re_, im_;
  419. };
  420.  
  421.  
  422. #else
  423.  
  424. //
  425. // The complex template definition must be placed after specializations to
  426. // satisfy several compilers' rather bizarre preference.
  427. //
  428. template <class T>
  429. class complex;
  430. #endif
  431.  
  432. class RWSTDExport complex<float>;
  433. class RWSTDExport complex<double>;
  434. class RWSTDExport complex<long double>;
  435.  
  436. #ifdef RWSTD_NO_UNDECLARED_FRIEND
  437. istream& RWSTDExport operator>> (istream&,       complex<float>&);
  438. ostream& RWSTDExport operator<< (ostream&, const complex<float>&);
  439. istream& RWSTDExport operator>> (istream&,       complex<double>&);
  440. ostream& RWSTDExport operator<< (ostream&, const complex<double>&);
  441. istream& RWSTDExport operator>> (istream&,       complex<long double>&);
  442. ostream& RWSTDExport operator<< (ostream&, const complex<long double>&);
  443. #endif
  444.  
  445. class complex<float>
  446. {
  447.   public:
  448.     complex (const float& re_arg=0.0f, const float& imag_arg=0.0f) { re_=re_arg; im_=imag_arg; }
  449.     complex (const complex<float>&);
  450.     explicit complex (const complex<double>&);
  451.     explicit complex (const complex<long double>&);
  452.  
  453.     float imag () const { return im_; }
  454.     float real () const { return re_; }
  455.  
  456. #ifndef RWSTD_NO_MEMBER_TEMPLATES
  457.     template <class X> complex<float>& operator=  (const complex<X>& rhs) {re_=rhs.real(); im_=rhs.imag(); return *this;}
  458.     template <class X> complex<float>& operator+= (const complex<X>& rhs) {re_+=rhs.real(); im_+=rhs.imag(); return *this;}
  459.     template <class X> complex<float>& operator-= (const complex<X>& rhs) {re_-=rhs.real(); im_-=rhs.imag(); return *this;}
  460.     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;}
  461.     template <class X> complex<float>& operator/= (const complex<X>&);
  462. #else /* Have to specialize each one :-( */
  463.  
  464.     complex<float>& operator=  (const complex<float>&);
  465.     complex<float>& operator+= (const complex<float>&);
  466.     complex<float>& operator-= (const complex<float>&);
  467.     complex<float>& operator*= (const complex<float>&);
  468.     complex<float>& operator/= (const complex<float>&);
  469.  
  470.     complex<float>& operator=  (const complex<double>&);
  471.     complex<float>& operator+= (const complex<double>&);
  472.     complex<float>& operator-= (const complex<double>&);
  473.     complex<float>& operator*= (const complex<double>&);
  474.     complex<float>& operator/= (const complex<double>&);
  475.  
  476.     complex<float>& operator=  (const complex<long double>&);
  477.     complex<float>& operator+= (const complex<long double>&);
  478.     complex<float>& operator-= (const complex<long double>&);
  479.     complex<float>& operator*= (const complex<long double>&);
  480.     complex<float>& operator/= (const complex<long double>&);
  481. #endif
  482.  
  483.     friend istream& operator>> (istream&,       complex<float>&);
  484.     friend ostream& operator<< (ostream&, const complex<float>&);
  485.  
  486.   private:
  487.     float re_, im_;
  488. };
  489.  
  490. class  complex<double>
  491. {
  492.   public:
  493.     complex (const double& re_arg=0.0, const double& imag_arg=0.0) { re_=re_arg; im_=imag_arg; }
  494.     complex (const complex<float>&);
  495.     complex (const complex<double>&);
  496.     explicit complex (const complex<long double>&);
  497.  
  498.     double imag () const { return im_; }
  499.     double real () const { return re_; }
  500.  
  501. #ifndef RWSTD_NO_MEMBER_TEMPLATES
  502.     template <class X> complex<double>& operator=  (const complex<X>& rhs) {re_=rhs.real(); im_=rhs.imag(); return *this;}
  503.     template <class X> complex<double>& operator+= (const complex<X>& rhs) {re_+=rhs.real(); im_+=rhs.imag(); return *this;}
  504.     template <class X> complex<double>& operator-= (const complex<X>& rhs) {re_-=rhs.real(); im_-=rhs.imag(); return *this;}
  505.     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;}
  506.     template <class X> complex<double>& operator/= (const complex<X>&);
  507.  
  508. #else /* Have to specialize each one :-( */
  509.  
  510.     complex<double>& operator=  (const complex<float>&);
  511.     complex<double>& operator+= (const complex<float>&);
  512.     complex<double>& operator-= (const complex<float>&);
  513.     complex<double>& operator*= (const complex<float>& rhs);
  514.     complex<double>& operator/= (const complex<float>&);
  515.  
  516.     complex<double>& operator=  (const complex<double>& rhs);
  517.     complex<double>& operator+= (const complex<double>& rhs);
  518.     complex<double>& operator-= (const complex<double>& rhs);
  519.     complex<double>& operator*= (const complex<double>& rhs);
  520.     complex<double>& operator/= (const complex<double>&);
  521.  
  522.     complex<double>& operator=  (const complex<long double>&);
  523.     complex<double>& operator+= (const complex<long double>&);
  524.     complex<double>& operator-= (const complex<long double>&);
  525.     complex<double>& operator*= (const complex<long double>&);
  526.     complex<double>& operator/= (const complex<long double>&);
  527. #endif
  528.  
  529.     friend istream& operator>> (istream&,       complex<double>&);
  530.     friend ostream& operator<< (ostream&, const complex<double>&);
  531.  
  532.   private:
  533.     double re_, im_;
  534. };
  535.  
  536. class complex<long double>
  537. {
  538.   public:
  539.     complex (const long double& re_arg=0.0L, const long double& imag_arg=0.0L) { re_=re_arg; im_=imag_arg; }
  540.     complex (const complex<float>&);
  541.     complex (const complex<double>&);
  542.     complex (const complex<long double>&);
  543.  
  544.     long double imag () const { return im_; }
  545.     long double real () const { return re_; }
  546.  
  547. #ifndef RWSTD_NO_MEMBER_TEMPLATES
  548.     template <class X> complex<long double>& operator=  (const complex<X>& rhs) {re_=rhs.real(); im_=rhs.imag(); return *this;}
  549.     template <class X> complex<long double>& operator+= (const complex<X>& rhs) {re_+=rhs.real(); im_+=rhs.imag(); return *this;}
  550.     template <class X> complex<long double>& operator-= (const complex<X>& rhs) {re_-=rhs.real(); im_-=rhs.imag(); return *this;}
  551.     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;}
  552.     template <class X> complex<long double>& operator/= (const complex<X>&);
  553.  
  554. #else /* Have to specialize each one :-( */
  555.  
  556.     complex<long double>& operator=  (const complex<float>&);
  557.     complex<long double>& operator+= (const complex<float>&);
  558.     complex<long double>& operator-= (const complex<float>&);
  559.     complex<long double>& operator*= (const complex<float>&);
  560.     complex<long double>& operator/= (const complex<float>&);
  561.  
  562.     complex<long double>& operator=  (const complex<double>&);
  563.     complex<long double>& operator+= (const complex<double>&);
  564.     complex<long double>& operator-= (const complex<double>&);
  565.     complex<long double>& operator*= (const complex<double>&);
  566.     complex<long double>& operator/= (const complex<double>&);
  567.  
  568.     complex<long double>& operator=  (const complex<long double>&);
  569.     complex<long double>& operator+= (const complex<long double>&);
  570.     complex<long double>& operator-= (const complex<long double>&);
  571.     complex<long double>& operator*= (const complex<long double>&);
  572.     complex<long double>& operator/= (const complex<long double>&);
  573. #endif
  574.  
  575.     friend istream& operator>> (istream&,       complex<long double>&);
  576.     friend ostream& operator<< (ostream&, const complex<long double>&);
  577.  
  578.   private:
  579.     long double re_, im_;
  580. };
  581.  
  582. #ifdef RWSTD_NO_FORWARD_SPECIALIZATIONS
  583. template <class T>
  584. class complex
  585. {
  586.   public:
  587.     complex (const T& re_arg=0, const T& imag_arg=0) { re_=re_arg; im_=imag_arg; }
  588.  
  589.     T imag () const { return im_; }
  590.     T real () const { return re_; }
  591.  
  592. #ifndef RWSTD_NO_MEMBER_TEMPLATES
  593.     template <class X> complex (const complex<X>& rhs) {re_=rhs.real(); im_=rhs.imag();}
  594.  
  595.     template <class X> complex<T>& operator=  (const complex<X>& rhs) {re_=rhs.real(); im_=rhs.imag(); return *this;}
  596.     template <class X> complex<T>& operator+= (const complex<X>& rhs) {re_+=rhs.real(); im_+=rhs.imag(); return *this;}
  597.     template <class X> complex<T>& operator-= (const complex<X>& rhs) {re_-=rhs.real(); im_-=rhs.imag(); return *this;}
  598.     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;}
  599.     template <class X> complex<T>& operator/= (const complex<X>&);
  600. #endif
  601.  
  602.   private:
  603.     T re_, im_;
  604. };
  605.  
  606.  
  607. #endif
  608.  
  609. //
  610. // complex<float> specializations.
  611. //
  612. inline
  613. complex<float>::complex (const complex<float>& cf)
  614. {
  615.     re_ = cf.real(); im_ = cf.imag();
  616. }
  617.  
  618. inline
  619. complex<float>::complex (const complex<double>& cd)
  620. {
  621.     re_ = cd.real(); im_ = cd.imag();
  622. }
  623.  
  624. inline
  625. complex<float>::complex (const complex<long double>& cld)
  626. {
  627.     re_ = cld.real(); im_ = cld.imag();
  628. }
  629.  
  630. inline complex<float>&
  631. complex<float>::operator= (const complex<float>& rhs)
  632. {
  633.     re_ = rhs.real(); im_ = rhs.imag(); return *this;
  634. }
  635.  
  636. inline complex<float>&
  637. complex<float>::operator+= (const complex<float>& rhs)
  638. {
  639.     re_ += rhs.real(); im_ += rhs.imag(); return *this;
  640. }
  641.  
  642. inline complex<float>&
  643. complex<float>::operator-= (const complex<float>& rhs)
  644. {
  645.     re_ -= rhs.real(); im_ -= rhs.imag(); return *this;
  646. }
  647.  
  648. inline complex<float>&
  649. complex<float>::operator*= (const complex<float>& rhs)
  650. {
  651.     float tmp = re_*rhs.real()-im_*rhs.imag();
  652.     im_       = im_*rhs.real()+re_*rhs.imag();
  653.     re_       = tmp;
  654.     return *this;
  655. }
  656.  
  657. inline complex<float>&
  658. complex<float>::operator= (const complex<double>& rhs)
  659. {
  660.     re_ = rhs.real(); im_ = rhs.imag(); return *this;
  661. }
  662.  
  663. inline complex<float>&
  664. complex<float>::operator+= (const complex<double>& rhs)
  665. {
  666.     re_ += rhs.real(); im_ += rhs.imag(); return *this;
  667. }
  668.  
  669. inline complex<float>&
  670. complex<float>::operator-= (const complex<double>& rhs)
  671. {
  672.     re_ -= rhs.real(); im_ -= rhs.imag(); return *this;
  673. }
  674.  
  675. inline complex<float>&
  676. complex<float>::operator*= (const complex<double>& rhs)
  677. {
  678.     float tmp = re_*rhs.real()-im_*rhs.imag();
  679.     im_       = im_*rhs.real()+re_*rhs.imag();
  680.     re_       = tmp;
  681.     return *this;
  682. }
  683.  
  684. inline complex<float>&
  685. complex<float>::operator= (const complex<long double>& rhs)
  686. {
  687.     re_ = rhs.real(); im_ = rhs.imag(); return *this;
  688. }
  689.  
  690. inline complex<float>&
  691. complex<float>::operator+= (const complex<long double>& rhs)
  692. {
  693.     re_ += rhs.real(); im_ += rhs.imag(); return *this;
  694. }
  695.  
  696. inline complex<float>&
  697. complex<float>::operator-= (const complex<long double>& rhs)
  698. {
  699.     re_ -= rhs.real(); im_ -= rhs.imag(); return *this;
  700. }
  701.  
  702. inline complex<float>&
  703. complex<float>::operator*= (const complex<long double>& rhs)
  704. {
  705.     float tmp = re_*rhs.real()-im_*rhs.imag();
  706.     im_       = im_*rhs.real()+re_*rhs.imag();
  707.     re_       = tmp;
  708.     return *this;
  709. }
  710.  
  711. //
  712. // complex<double> specializations.
  713. //
  714.  
  715. inline
  716. complex<double>::complex (const complex<float>& cf)
  717.     : re_(cf.real()), im_(cf.imag()) {}
  718.  
  719. inline
  720. complex<double>::complex (const complex<double>& cd)
  721.     : re_(cd.real()), im_(cd.imag()) {}
  722.  
  723. inline
  724. complex<double>::complex (const complex<long double>& cld)
  725.     : re_(cld.real()), im_(cld.imag()) {}
  726.  
  727. inline complex<double>&
  728. complex<double>::operator= (const complex<float>& rhs)
  729. {
  730.     re_ = rhs.real(); im_ = rhs.imag(); return *this;
  731. }
  732.  
  733. inline complex<double>&
  734. complex<double>::operator+= (const complex<float>& rhs)
  735. {
  736.     re_ += rhs.real(); im_ += rhs.imag(); return *this;
  737. }
  738.  
  739. inline complex<double>&
  740. complex<double>::operator-= (const complex<float>& rhs)
  741. {
  742.     re_ -= rhs.real(); im_ -= rhs.imag(); return *this;
  743. }
  744.  
  745. inline complex<double>&
  746. complex<double>::operator*= (const complex<float>& rhs)
  747. {
  748.     double tmp = re_*rhs.real()-im_*rhs.imag();
  749.     im_        = im_*rhs.real()+re_*rhs.imag();
  750.     re_        = tmp;
  751.     return *this;
  752. }
  753.  
  754. inline complex<double>&
  755. complex<double>::operator= (const complex<double>& rhs)
  756. {
  757.     re_ = rhs.real(); im_ = rhs.imag(); return *this;
  758. }
  759.  
  760. inline complex<double>&
  761. complex<double>::operator+= (const complex<double>& rhs)
  762. {
  763.     re_ += rhs.real(); im_ += rhs.imag(); return *this;
  764. }
  765.  
  766. inline complex<double>&
  767. complex<double>::operator-= (const complex<double>& rhs)
  768. {
  769.     re_ -= rhs.real(); im_ -= rhs.imag(); return *this;
  770. }
  771.  
  772. inline complex<double>&
  773. complex<double>::operator*= (const complex<double>& rhs)
  774. {
  775.     double tmp = re_*rhs.real()-im_*rhs.imag();
  776.     im_        = im_*rhs.real()+re_*rhs.imag();
  777.     re_        = tmp;
  778.     return *this;
  779. }
  780.  
  781. inline complex<double>&
  782. complex<double>::operator= (const complex<long double>& rhs)
  783. {
  784.     re_ = rhs.real(); im_ = rhs.imag(); return *this;
  785. }
  786.  
  787. inline complex<double>&
  788. complex<double>::operator+= (const complex<long double>& rhs)
  789. {
  790.     re_ += rhs.real(); im_ += rhs.imag(); return *this;
  791. }
  792.  
  793. inline complex<double>&
  794. complex<double>::operator-= (const complex<long double>& rhs)
  795. {
  796.     re_ -= rhs.real(); im_ -= rhs.imag(); return *this;
  797. }
  798.  
  799. inline complex<double>&
  800. complex<double>::operator*= (const complex<long double>& rhs)
  801. {
  802.     double tmp = re_*rhs.real()-im_*rhs.imag();
  803.     im_        = im_*rhs.real()+re_*rhs.imag();
  804.     re_        = tmp;
  805.     return *this;
  806. }
  807.  
  808. //
  809. // complex<long double> specializations.
  810. //
  811.  
  812. inline
  813. complex<long double>::complex (const complex<float>& cf)
  814.     : re_(cf.real()), im_(cf.imag()) {}
  815.  
  816. inline
  817. complex<long double>::complex (const complex<double>& cd)
  818.     : re_(cd.real()), im_(cd.imag()) {}
  819.  
  820. inline
  821. complex<long double>::complex (const complex<long double>& cld)
  822.     : re_(cld.real()), im_(cld.imag()) {}
  823.  
  824. inline complex<long double>&
  825. complex<long double>::operator= (const complex<float>& rhs)
  826. {
  827.     re_ = rhs.real(); im_ = rhs.imag(); return *this;
  828. }
  829.  
  830. inline complex<long double>&
  831. complex<long double>::operator+= (const complex<float>& rhs)
  832. {
  833.     re_ += rhs.real(); im_ += rhs.imag(); return *this;
  834. }
  835.  
  836. inline complex<long double>&
  837. complex<long double>::operator-= (const complex<float>& rhs)
  838. {
  839.     re_ -= rhs.real(); im_ -= rhs.imag(); return *this;
  840. }
  841.  
  842. inline complex<long double>&
  843. complex<long double>::operator*= (const complex<float>& rhs)
  844. {
  845.     long double tmp = re_*rhs.real()-im_*rhs.imag();
  846.     im_             = im_*rhs.real()+re_*rhs.imag();
  847.     re_             = tmp;
  848.     return *this;
  849. }
  850.  
  851. inline complex<long double>&
  852. complex<long double>::operator= (const complex<double>& rhs)
  853. {
  854.     re_ = rhs.real(); im_ = rhs.imag(); return *this;
  855. }
  856.  
  857. inline complex<long double>&
  858. complex<long double>::operator+= (const complex<double>& rhs)
  859. {
  860.     re_ += rhs.real(); im_ += rhs.imag(); return *this;
  861. }
  862.  
  863. inline complex<long double>&
  864. complex<long double>::operator-= (const complex<double>& rhs)
  865. {
  866.     re_ -= rhs.real(); im_ -= rhs.imag(); return *this;
  867. }
  868.  
  869. inline complex<long double>&
  870. complex<long double>::operator*= (const complex<double>& rhs)
  871. {
  872.     long double tmp = re_*rhs.real()-im_*rhs.imag();
  873.     im_             = im_*rhs.real()+re_*rhs.imag();
  874.     re_             = tmp;
  875.     return *this;
  876. }
  877.  
  878. inline complex<long double>&
  879. complex<long double>::operator= (const complex<long double>& rhs)
  880. {
  881.     re_ = rhs.real(); im_ = rhs.imag(); return *this;
  882. }
  883.  
  884. inline complex<long double>&
  885. complex<long double>::operator+= (const complex<long double>& rhs)
  886. {
  887.     re_ += rhs.real(); im_ += rhs.imag(); return *this;
  888. }
  889.  
  890. inline complex<long double>&
  891. complex<long double>::operator-= (const complex<long double>& rhs)
  892. {
  893.     re_ -= rhs.real(); im_ -= rhs.imag(); return *this;
  894. }
  895.  
  896. inline complex<long double>&
  897. complex<long double>::operator*= (const complex<long double>& rhs)
  898. {
  899.     long double tmp = re_*rhs.real()-im_*rhs.imag();
  900.     im_             = im_*rhs.real()+re_*rhs.imag();
  901.     re_             = tmp;
  902.     return *this;
  903. }
  904.  
  905. #ifndef RWSTD_NO_MEMBER_TEMPLATES
  906. template <class T>
  907. template <class X>
  908. complex<T>&
  909. complex<T>::operator/= (const complex<X>& rhs)
  910. {
  911.     T denom = rhs.real()*rhs.real() + rhs.imag()*rhs.imag();
  912.     T re    = (re_*rhs.real()+im_*rhs.imag())/denom;
  913.     T im    = (rhs.real()*im_-re_*rhs.imag())/denom;
  914.     re_     = re;
  915.     im_     = im;
  916.     return *this;
  917. }
  918.  
  919. template <class X>
  920. complex<float>&
  921. complex<float>::operator/= (const complex<X>& rhs)
  922. {
  923.     float denom = rhs.real()*rhs.real() + rhs.imag()*rhs.imag();
  924.     float re    = (re_*rhs.real()+im_*rhs.imag())/denom;
  925.     float im    = (rhs.real()*im_-re_*rhs.imag())/denom;
  926.     re_         = re;
  927.     im_         = im;
  928.     return *this;
  929. }
  930.  
  931. template <class X>
  932. complex<double>&
  933. complex<double>::operator/= (const complex<X>& rhs)
  934. {
  935.     double denom = rhs.real()*rhs.real() + rhs.imag()*rhs.imag();
  936.     double re    = (re_*rhs.real()+im_*rhs.imag())/denom;
  937.     double im    = (rhs.real()*im_-re_*rhs.imag())/denom;
  938.     re_          = re;
  939.     im_          = im;
  940.     return *this;
  941. }
  942.  
  943. template <class X>
  944. complex<long double>&
  945. complex<long double>::operator/= (const complex<X>& rhs)
  946. {
  947.     long double denom = rhs.real()*rhs.real() + rhs.imag()*rhs.imag();
  948.     long double re    = (re_*rhs.real()+im_*rhs.imag())/denom;
  949.     long double im    = (rhs.real()*im_-re_*rhs.imag())/denom;
  950.     re_               = re;
  951.     im_               = im;
  952.     return *this;
  953. }
  954.  
  955. #else /* No member function templates, have to specialize :-( */
  956.  
  957. inline complex<float>&
  958. complex<float>::operator/= (const complex<float>& rhs)
  959. {
  960.     float denom = rhs.real()*rhs.real() + rhs.imag()*rhs.imag();
  961.     float re    = (re_*rhs.real()+im_*rhs.imag())/denom;
  962.     float im    = (rhs.real()*im_-re_*rhs.imag())/denom;
  963.     re_         = re;
  964.     im_         = im;
  965.     return *this;
  966. }
  967.  
  968. inline complex<float>&
  969. complex<float>::operator/= (const complex<double>& rhs)
  970. {
  971.     float denom = rhs.real()*rhs.real() + rhs.imag()*rhs.imag();
  972.     float re    = (re_*rhs.real()+im_*rhs.imag())/denom;
  973.     float im    = (rhs.real()*im_-re_*rhs.imag())/denom;
  974.     re_         = re;
  975.     im_         = im;
  976.     return *this;
  977. }
  978.  
  979. inline complex<float>&
  980. complex<float>::operator/= (const complex<long double>& rhs)
  981. {
  982.     float denom = rhs.real()*rhs.real() + rhs.imag()*rhs.imag();
  983.     float re    = (re_*rhs.real()+im_*rhs.imag())/denom;
  984.     float im    = (rhs.real()*im_-re_*rhs.imag())/denom;
  985.     re_         = re;
  986.     im_         = im;
  987.     return *this;
  988. }
  989.  
  990. inline complex<double>&
  991. complex<double>::operator/= (const complex<float>& rhs)
  992. {
  993.     double denom = rhs.real()*rhs.real() + rhs.imag()*rhs.imag();
  994.     double re    = (re_*rhs.real()+im_*rhs.imag())/denom;
  995.     double im    = (rhs.real()*im_-re_*rhs.imag())/denom;
  996.     re_          = re;
  997.     im_          = im;
  998.     return *this;
  999. }
  1000.  
  1001. inline complex<double>&
  1002. complex<double>::operator/= (const complex<double>& rhs)
  1003. {
  1004.     double denom = rhs.real()*rhs.real() + rhs.imag()*rhs.imag();
  1005.     double re    = (re_*rhs.real()+im_*rhs.imag())/denom;
  1006.     double im    = (rhs.real()*im_-re_*rhs.imag())/denom;
  1007.     re_          = re;
  1008.     im_          = im;
  1009.     return *this;
  1010. }
  1011.  
  1012. inline complex<double>&
  1013. complex<double>::operator/= (const complex<long double>& rhs)
  1014. {
  1015.     double denom = rhs.real()*rhs.real() + rhs.imag()*rhs.imag();
  1016.     double re    = (re_*rhs.real()+im_*rhs.imag())/denom;
  1017.     double im    = (rhs.real()*im_-re_*rhs.imag())/denom;
  1018.     re_          = re;
  1019.     im_          = im;
  1020.     return *this;
  1021. }
  1022.  
  1023. inline complex<long double>&
  1024. complex<long double>::operator/= (const complex<float>& rhs)
  1025. {
  1026.     long double denom = rhs.real()*rhs.real() + rhs.imag()*rhs.imag();
  1027.     long double re    = (re_*rhs.real()+im_*rhs.imag())/denom;
  1028.     long double im    = (rhs.real()*im_-re_*rhs.imag())/denom;
  1029.     re_               = re;
  1030.     im_               = im;
  1031.     return *this;
  1032. }
  1033.  
  1034. inline complex<long double>&
  1035. complex<long double>::operator/= (const complex<double>& rhs)
  1036. {
  1037.     long double denom = rhs.real()*rhs.real() + rhs.imag()*rhs.imag();
  1038.     long double re    = (re_*rhs.real()+im_*rhs.imag())/denom;
  1039.     long double im    = (rhs.real()*im_-re_*rhs.imag())/denom;
  1040.     re_               = re;
  1041.     im_               = im;
  1042.     return *this;
  1043. }
  1044.  
  1045. inline complex<long double>&
  1046. complex<long double>::operator/= (const complex<long double>& rhs)
  1047. {
  1048.     long double denom = rhs.real()*rhs.real() + rhs.imag()*rhs.imag();
  1049.     long double re    = (re_*rhs.real()+im_*rhs.imag())/denom;
  1050.     long double im    = (rhs.real()*im_-re_*rhs.imag())/denom;
  1051.     re_               = re;
  1052.     im_               = im;
  1053.     return *this;
  1054. }
  1055. #endif
  1056.  
  1057. //
  1058. // complex non-member operations
  1059. //
  1060.  
  1061. template <class T>
  1062. inline complex<T> operator+ (const complex<T>& lhs, const complex<T>& rhs)
  1063. {
  1064.     complex<T> tmp = lhs; return tmp += rhs;
  1065. }
  1066.  
  1067. template <class T>
  1068. inline complex<T> operator+ (const complex<T>& lhs, const T& rhs)
  1069. {
  1070.     return complex<T>(rhs+lhs.real(), lhs.imag());
  1071. }
  1072.  
  1073. template <class T>
  1074. inline complex<T> operator+ (const T& lhs, const complex<T>& rhs)
  1075. {
  1076.     return complex<T>(lhs+rhs.real(), rhs.imag());
  1077. }
  1078.  
  1079. template <class T>
  1080. inline complex<T> operator- (const complex<T>& lhs, const complex<T>& rhs)
  1081. {
  1082.     complex<T> tmp = lhs; return tmp -= rhs;
  1083. }
  1084.  
  1085. template <class T>
  1086. inline complex<T> operator- (const complex<T>& lhs, const T& rhs)
  1087. {
  1088.     return complex<T>(lhs.real()-rhs, lhs.imag());
  1089. }
  1090.  
  1091. template <class T>
  1092. inline complex<T> operator- (const T& lhs, const complex<T>& rhs)
  1093. {
  1094.     return complex<T>(lhs-rhs.real(), -rhs.imag());
  1095. }
  1096.  
  1097. template <class T>
  1098. inline complex<T> operator* (const complex<T>& lhs, const complex<T>& rhs)
  1099. {
  1100.     complex<T> tmp = lhs; return tmp *= rhs;
  1101. }
  1102.  
  1103. template <class T>
  1104. inline complex<T> operator* (const complex<T>& lhs, const T& rhs)
  1105. {
  1106.     return complex<T>(rhs*lhs.real(), rhs*lhs.imag());
  1107. }
  1108.  
  1109. template <class T>
  1110. inline complex<T> operator* (const T& lhs, const complex<T>& rhs)
  1111. {
  1112.     return complex<T>(lhs*rhs.real(), lhs*rhs.imag());
  1113. }
  1114.  
  1115. template <class T>
  1116. inline complex<T> operator/ (const complex<T>& lhs, const complex<T>& rhs)
  1117. {
  1118.     complex<T> tmp = lhs; return tmp /= rhs;
  1119. }
  1120.  
  1121. template <class T>
  1122. inline complex<T> operator/ (const complex<T>& lhs, const T& rhs)
  1123. {
  1124.     return complex<T>(lhs.real()/rhs, lhs.imag()/rhs);
  1125. }
  1126.  
  1127. template <class T>
  1128. inline complex<T> operator/ (const T& lhs, const complex<T>& rhs)
  1129. {
  1130.     register T denom = rhs.real()*rhs.real() + rhs.imag()*rhs.imag();
  1131.     return complex<T>(lhs*rhs.real()/denom,(-lhs*rhs.imag())/denom);
  1132. }
  1133.  
  1134. template <class T>
  1135. inline complex<T> operator+ (const complex<T>& lhs) { return lhs; }
  1136.  
  1137. template <class T>
  1138. inline complex<T> operator- (const complex<T>& lhs)
  1139. {
  1140.     return complex<T>(-lhs.real(), -lhs.imag());
  1141. }
  1142.  
  1143. template <class T>
  1144. inline bool operator== (const complex<T>& lhs, const complex<T>& rhs)
  1145. {
  1146.     return lhs.real() == rhs.real() && lhs.imag() == rhs.imag();
  1147. }
  1148.  
  1149. template <class T>
  1150. inline bool operator== (const T& lhs, const complex<T>& rhs)
  1151. {
  1152.     return lhs == rhs.real() && rhs.imag() == 0;
  1153. }
  1154.  
  1155. template <class T>
  1156. inline bool operator== (const complex<T>& lhs, const T& rhs)
  1157. {
  1158.     return lhs.real() == rhs && lhs.imag() == 0;
  1159. }
  1160.  
  1161. #ifndef RWSTD_NO_PART_SPEC_OVERLOAD
  1162. template <class T>
  1163. inline bool operator!= (const complex<T>& lhs, const complex<T>& rhs)
  1164. {
  1165.     return lhs.real() != rhs.real() || lhs.imag() != rhs.imag();
  1166. }
  1167. #endif
  1168.  
  1169. template <class T>
  1170. inline bool operator!= (const T& lhs, const complex<T>& rhs)
  1171. {
  1172.     return lhs != rhs.real() || rhs.imag() != 0;
  1173. }
  1174.  
  1175. template <class T>
  1176. inline bool operator!= (const complex<T>& lhs, const T& rhs)
  1177. {
  1178.     return lhs.real() != rhs || lhs.imag() != 0;
  1179. }
  1180.  
  1181. //
  1182. // complex value operations
  1183. //
  1184.  
  1185. template<class T>
  1186. inline T real (const complex<T>& a) { return a.real(); }
  1187.  
  1188. template<class T>
  1189. inline T imag (const complex<T>& a) { return a.imag(); }
  1190.  
  1191. template <class T>
  1192. inline T norm (const complex<T>& a)
  1193. {
  1194.     return a.real()*a.real() + a.imag()*a.imag();
  1195. }
  1196.  
  1197. template <class T>
  1198. inline T abs (const complex<T>& a) { return ::sqrt(norm(a)); }
  1199.  
  1200. //
  1201. // We guarantee that arg(complex<T>(0,0)) == 0.
  1202. //
  1203.  
  1204. template <class T>
  1205. inline T arg (const complex<T>& a)
  1206. {
  1207.     return a == complex<T>(0,0) ? T(0) : ::atan2 (a.imag(), a.real());
  1208. }
  1209.  
  1210. template <class T>
  1211. complex<T> conj (const complex<T>& a)
  1212. {
  1213.     return complex<T>(a.real(), -a.imag());
  1214. }
  1215.  
  1216. #if _MSC_VER < 901
  1217. //
  1218. // A very bizarre Microsoft problem.
  1219. //
  1220. inline complex<float> conj (const complex<float>& a)
  1221. {
  1222.     return complex<float>(a.real(), -a.imag());
  1223. }
  1224. inline complex<double> conj (const complex<double>& a)
  1225. {
  1226.     return complex<double>(a.real(), -a.imag());
  1227. }
  1228. inline complex<long double> conj (const complex<long double>& a)
  1229. {
  1230.     return complex<long double>(a.real(), -a.imag());
  1231. }
  1232. #endif
  1233.  
  1234. template <class T>
  1235. inline complex<T> polar (T r, T theta)
  1236. {
  1237.     return complex<T>(r*::cos(theta), r*::sin(theta));
  1238. }
  1239.  
  1240. //
  1241. // transcendentals
  1242. //
  1243.  
  1244. template <class T>
  1245. inline complex<T> acos (const complex<T>& a)
  1246. {
  1247.     const complex<T> i(0,1);
  1248.     return -i * log(a + i*sqrt(complex<T>(1,0) - a*a));
  1249. }
  1250.  
  1251. template <class T>
  1252. inline complex<T> asin (const complex<T>& a)
  1253. {
  1254.     const complex<T> i(0,1);
  1255.     return i * log(i*a + sqrt(complex<T>(1,0) - a*a));
  1256. }
  1257.  
  1258. template <class T>
  1259. inline complex<T> atan (const complex<T>& a)
  1260. {
  1261.     const complex<T> i(0,1);
  1262.     return i/T(2) * log((i+a)/(i-a));
  1263. }
  1264. template <class T>
  1265. inline complex<T> atan2 (const complex<T>& lhs, const complex<T>& rhs)
  1266. {
  1267.     return atan(lhs/rhs);
  1268. }
  1269.  
  1270. template <class T>
  1271. inline complex<T> atan2 (const complex<T>& lhs, T rhs)
  1272. {
  1273.     return atan(lhs/rhs);
  1274. }
  1275.  
  1276. template <class T>
  1277. inline complex<T> atan2 (T lhs, const complex<T>& rhs)
  1278. {
  1279.     return atan(lhs/rhs);
  1280. }
  1281.  
  1282. //
  1283. // complex<T> cosine of complex<T> number a
  1284. //      cos (a) = cos u * cosh v - i * sin u * sinh v
  1285. //
  1286.  
  1287. template <class T>
  1288. inline complex<T> cos (const complex<T>& a)
  1289. {
  1290.     return complex<T>(::cos(a.real())*::cosh(a.imag()),
  1291.                       -::sin(a.real())*::sinh(a.imag()));
  1292. }
  1293.  
  1294. //
  1295. // complex<T> hyperbolic cosine of complex<T> number a
  1296. //      cosh (a) = cosh u * cosv + i * sinh u * sin v
  1297. //
  1298.  
  1299. template <class T>
  1300. inline complex<T> cosh (const complex<T>& a)
  1301. {
  1302.     return complex<T>(::cosh(a.real())*::cos(a.imag()),
  1303.                       ::sinh(a.real())*::sin(a.imag()));
  1304. }
  1305.  
  1306. //
  1307. // complex<T> exponential of  complex<T> number a
  1308. //      exp (a) = exp(u) * (cos v + i * sin v)
  1309. //
  1310.  
  1311. template <class T>
  1312. inline complex<T> exp (const complex<T>& a)
  1313. {
  1314.     register T e = ::exp(a.real());
  1315.     return complex<T>(e*::cos(a.imag()), e*::sin(a.imag()));
  1316. }
  1317.  
  1318. //
  1319. // complex<T> natural log of complex<T> number a
  1320. //      log(a) = log(r) + i * theta
  1321. //
  1322.  
  1323. template <class T>
  1324. inline complex<T> log (const complex<T>& a)
  1325. {
  1326.     return complex<T>(::log(abs(a)), arg(a));
  1327. }
  1328.  
  1329. template <class T>
  1330. complex<T> log10 (const complex<T>& a)
  1331. {
  1332.     static const T log10e = ::log10(::exp(T(1)));
  1333.     return log10e * log(a);
  1334. }
  1335.  
  1336. //
  1337. // For all the power functions:
  1338. //
  1339. //   0**0 == 1
  1340. //   0**x == 0 for x != 0
  1341. //
  1342.  
  1343. //
  1344. // complex<T> number a raised to an integer power n
  1345. //
  1346. // a**n = r**n * (cos(n theta) + i sin (n theta))
  1347. //
  1348.  
  1349. template <class T>
  1350. complex<T> pow (const complex<T>& a, int n)
  1351. {
  1352.     if (a == complex<T>(0,0))
  1353.         return n == 0 ? complex<T>(1,0) : complex<T>(0,0);
  1354.  
  1355.     if (a.imag() == 0)
  1356.         return a.real() < 0
  1357.             ? pow(a, complex<T>(n,0)) : complex<T>(::pow(a.real(),T(n)), 0);
  1358.  
  1359.     register T r  = ::pow(T(abs(a)), T(n));
  1360.     register T th = T(n) * arg(a);
  1361.  
  1362.     return complex<T>(r*::cos(th), r*::sin(th));
  1363. }
  1364.  
  1365.  
  1366. //
  1367. // complex<T> number a raised to a real power s
  1368. //
  1369. // a**s = exp(s * log(a))
  1370. //
  1371.  
  1372. template <class T>
  1373. complex<T> pow (const complex<T>& a, T s)
  1374. {
  1375.     if (a == complex<T>(0,0))
  1376.         return s == T(0) ? complex<T>(1,0) : complex<T>(0,0);
  1377.  
  1378.     if (a.imag() == 0)
  1379.         return a.real() < 0
  1380.             ? pow(a, complex<T>(s,0)) : complex<T>(::pow(a.real(),s), 0);
  1381.  
  1382.     return exp(s*log(a));
  1383. }
  1384.  
  1385.  
  1386. //
  1387. // real number s raised to a complex<T> power a
  1388. //
  1389. //  s**a = exp(a * log (s))
  1390. //
  1391.  
  1392. template <class T>
  1393. complex<T> pow (T s, const complex<T>& a)
  1394. {
  1395.     if (s == T(0))
  1396.         return a == complex<T>(0,0) ? complex<T>(1,0) : complex<T>(0,0);
  1397.  
  1398.     if (s < 0)
  1399.         return pow(complex<T>(s,0), a);
  1400.  
  1401.     if (a.imag() == 0)
  1402.         return complex<T>(::pow(s, a.real()), 0);
  1403.     return complex<T>(exp(a * (T) ::log(s)));
  1404. }
  1405.  
  1406.  
  1407. //
  1408. // complex<T> number a1 raised to a complex<T> power a2
  1409. //
  1410. // a1**a2 = rho * (cos(phi) + i sin(phi))
  1411. //      rho = r1 **u2   *  exp (-v2* theta1)
  1412. //      phi = v2 * log(r1) + u2 * theta1
  1413. //
  1414.  
  1415. template <class T>
  1416. complex<T> pow (const complex<T>& a1, const complex<T>& a2)
  1417. {
  1418.     if (a1 == complex<T>(0,0))
  1419.         return a2 == complex<T>(0,0) ? complex<T>(1,0) : complex<T>(0,0);
  1420.  
  1421.     T r1   = abs(a1);
  1422.     T u2   = real(a2);
  1423.     T v2   = imag(a2);
  1424.     T th1  = arg(a1);
  1425.     T rho  = ::pow(r1, u2) * ::exp(-v2 * th1);
  1426.     T phi  = v2 * ::log(r1) + u2 * th1;
  1427.  
  1428.     return complex<T>(rho*::cos(phi), rho*::sin(phi));
  1429. }
  1430.  
  1431.  
  1432. //
  1433. // complex<T> sine of complex<T> number a
  1434. //      sin (a) = sin u * cosh v + i * cos u * sinh v
  1435. //
  1436. template <class T>
  1437. inline complex<T> sin (const complex<T>& a)
  1438. {
  1439.     return complex<T>(::sin(a.real())*::cosh(a.imag()),
  1440.                       ::cos(a.real())*::sinh(a.imag()));
  1441. }
  1442.  
  1443. //
  1444. // complex<T> hyperbolic sine of complex<T> number a
  1445. //      sinh (a) = sinh u cos v + i cosh u sin v
  1446. //
  1447. template <class T>
  1448. inline complex<T> sinh (const complex<T>& a)
  1449. {
  1450.     return complex<T>(::sinh(a.real())*::cos(a.imag()),
  1451.                       ::cosh(a.real())*::sin(a.imag()));
  1452. }
  1453.  
  1454. //
  1455. // complex<T> square root of complex<T> number a
  1456. //      sqrt(a) = sqrt(r) * ( cos (theta/2) + i sin (theta/2) )
  1457. //
  1458. template <class T>
  1459. inline complex<T> sqrt (const complex<T>& a)
  1460. {
  1461.     register T r  = ::sqrt(abs(a));
  1462.     register T th = arg(a)/2.;
  1463.     return complex<T>(r*::cos(th), r*::sin(th));
  1464. }
  1465.  
  1466. template <class T>
  1467. inline complex<T> tan (const complex<T>& a) { return sin(a)/cos(a); }
  1468.  
  1469. template <class T>
  1470. inline complex<T> tanh (const complex<T>& a) { return sinh(a)/cosh(a); }
  1471.  
  1472. #ifdef RW_STD_IOSTREAM
  1473. template <class T,class charT, class traits>
  1474. basic_istream<charT, traits >&  operator>> (basic_istream<charT, traits >& is,complex<T>& x)
  1475. #else
  1476. template <class T>
  1477. istream& operator>> (istream& is, complex<T>& x)
  1478. #endif
  1479. {
  1480.     //
  1481.     // operator >> reads a complex number x in the form
  1482.     // u
  1483.     // (u)
  1484.     // (u, v)
  1485.     //
  1486.     T u = 0, v = 0;
  1487.     char c;
  1488.  
  1489.     is >> c;
  1490.     if (c == '(')
  1491.     {
  1492.         is >> u >> c;
  1493.         if (c == ',') { is >> v  >> c;}
  1494.         if (c != ')' )
  1495.         {
  1496. #ifdef RW_STD_IOSTREAM
  1497.             is.setstate(ios::failbit);
  1498. #else
  1499.             is.clear(ios::failbit);
  1500. #endif
  1501.         }
  1502.     }
  1503.     else
  1504.     {
  1505.         is.putback(c);
  1506.         is >> u;
  1507.     }
  1508.  
  1509.     if (is)
  1510.         x = complex<T>(u,v);
  1511.  
  1512.     return is;
  1513. }
  1514.  
  1515. #ifdef RW_STD_IOSTREAM
  1516. template <class T,class charT, class traits>
  1517. basic_istream<charT, traits >&  operator>> (basic_istream<charT, traits >& is,complex<float>& x)
  1518. #else
  1519. istream&  operator>> (istream& is, complex<float>& x)
  1520. #endif
  1521. {
  1522.     //
  1523.     // operator >> reads a complex number x in the form
  1524.     // u
  1525.     // (u)
  1526.     // (u, v)
  1527.     //
  1528.     float u = 0, v = 0;
  1529.     char c;
  1530.  
  1531.     is >> c;
  1532.     if (c == '(')
  1533.     {
  1534.         is >> u >> c;
  1535.         if (c == ',') { is >> v  >> c;}
  1536.         if (c != ')' )
  1537.         {
  1538. #ifdef RW_STD_IOSTREAM
  1539.             is.setstate(ios::failbit);
  1540. #else
  1541.             is.clear(ios::failbit);
  1542. #endif
  1543.         }
  1544.     }
  1545.     else
  1546.     {
  1547.         is.putback(c);
  1548.         is >> u;
  1549.     }
  1550.  
  1551.     if (is)
  1552.         x = complex<float>(u,v);
  1553.  
  1554.     return is;
  1555. }
  1556.  
  1557. #ifdef RW_STD_IOSTREAM
  1558. template <class T,class charT, class traits>
  1559. basic_istream<charT, traits >&  operator>> (basic_istream<charT, traits >& is,complex<double>& x)
  1560. #else
  1561. istream&  operator>> (istream& is, complex<double>& x)
  1562. #endif
  1563. {
  1564.     //
  1565.     // operator >> reads a complex number x in the form
  1566.     // u
  1567.     // (u)
  1568.     // (u, v)
  1569.     //
  1570.     double u = 0, v = 0;
  1571.     char c;
  1572.  
  1573.     is >> c;
  1574.     if (c == '(')
  1575.     {
  1576.         is >> u >> c;
  1577.         if (c == ',') { is >> v  >> c;}
  1578.         if (c != ')' )
  1579.         {
  1580. #ifdef RW_STD_IOSTREAM
  1581.             is.setstate(ios::failbit);
  1582. #else
  1583.             is.clear(ios::failbit);
  1584. #endif
  1585.         }
  1586.     }
  1587.     else
  1588.     {
  1589.         is.putback(c);
  1590.         is >> u;
  1591.     }
  1592.  
  1593.     if (is)
  1594.         x = complex<double>(u,v);
  1595.  
  1596.     return is;
  1597. }
  1598.  
  1599. #ifndef RWSTD_NO_STREAM_LONG_DOUBLE
  1600. #ifdef RW_STD_IOSTREAM
  1601. template <class T,class charT, class traits>
  1602. basic_istream<charT, traits >&  operator>> (basic_istream<charT, traits >& is,complex<long double>& x)
  1603. #else
  1604. istream&  operator>> (istream& is, complex<long double>& x)
  1605. #endif
  1606. {
  1607.     //
  1608.     // operator >> reads a complex number x in the form
  1609.     // u
  1610.     // (u)
  1611.     // (u, v)
  1612.     //
  1613.     long double u = 0, v = 0;
  1614.     char c;
  1615.  
  1616.     is >> c;
  1617.     if (c == '(')
  1618.     {
  1619.         is >> u >> c;
  1620.         if (c == ',') { is >> v  >> c;}
  1621.         if (c != ')' )
  1622.         {
  1623. #ifdef RW_STD_IOSTREAM
  1624.             is.setstate(ios::failbit);
  1625. #else
  1626.             is.clear(ios::failbit);
  1627. #endif
  1628.         }
  1629.     }
  1630.     else
  1631.     {
  1632.         is.putback(c);
  1633.         is >> u;
  1634.     }
  1635.  
  1636.     if (is)
  1637.         x = complex<long double>(u,v);
  1638.  
  1639.     return is;
  1640. }
  1641. #endif /*RWSTD_NO_STREAM_LONG_DOUBLE*/
  1642.  
  1643. #ifdef RW_STD_IOSTREAM
  1644. template <class T,class charT,class traits>
  1645. basic_ostream<charT,traits > >&  operator<< (basic_ostream<charT, traits >& os,const complex<T>& x)
  1646. #else
  1647. template <class T>
  1648. ostream&  operator<< (ostream& os, const complex<T>& x)
  1649. #endif
  1650. {
  1651.     return os << "(" << x.real() << "," << x.imag() << ")";
  1652. }
  1653.  
  1654. #ifdef RW_STD_IOSTREAM
  1655. template <class T,class charT,class traits>
  1656. basic_ostream<charT,traits > >&  operator<< (basic_ostream<charT, traits >& os,const complex<float>& x)
  1657. #else
  1658. ostream&  operator<< (ostream& os, const complex<float>& x)
  1659. #endif
  1660. {
  1661.     return os << "(" << x.real() << "," << x.imag() << ")";
  1662. }
  1663.  
  1664. #ifdef RW_STD_IOSTREAM
  1665. template <class T,class charT,class traits>
  1666. basic_ostream<charT,traits > >&  operator<< (basic_ostream<charT, traits >& os,const complex<double>& x)
  1667. #else
  1668. ostream&  operator<< (ostream& os, const complex<double>& x)
  1669. #endif
  1670. {
  1671.     return os << "(" << x.real() << "," << x.imag() << ")";
  1672. }
  1673.  
  1674. #ifndef RWSTD_NO_STREAM_LONG_DOUBLE
  1675. #ifdef RW_STD_IOSTREAM
  1676. template <class T,class charT,class traits>
  1677. basic_ostream<charT,traits > >&  operator<< (basic_ostream<charT, traits >& os,const complex<long double>& x)
  1678. #else
  1679. ostream&  operator<< (ostream& os, const complex<long double>& x)
  1680. #endif
  1681. {
  1682.     return os << "(" << x.real() << "," << x.imag() << ")";
  1683. }
  1684. #endif /*RWSTD_NO_STREAM_LONG_DOUBLE*/
  1685.  
  1686. #if defined(RWSTD_NO_DESTROY_BUILTIN) || defined(RWSTD_NO_DESTROY_NONBUILTIN)
  1687. //
  1688. // Specializations of STL destroy for complex.
  1689. //
  1690. inline void destroy (complex<float>**)         {}
  1691. inline void destroy (complex<float>***)        {}
  1692. inline void destroy (complex<float>****)       {}
  1693. inline void destroy (complex<double>**)        {}
  1694. inline void destroy (complex<double>***)       {}
  1695. inline void destroy (complex<double>****)      {}
  1696. inline void destroy (complex<long double>**)   {}
  1697. inline void destroy (complex<long double>***)  {}
  1698. inline void destroy (complex<long double>****) {}
  1699. #endif
  1700.  
  1701.  // Export functions
  1702.  
  1703. /* template complex<float> RWSTDExportTemplate pow (const complex<float>& a, int n);
  1704.  template complex<double> RWSTDExportTemplate pow (const complex<double>& a, int n);
  1705.  template complex<long double> RWSTDExportTemplate pow (const complex<long double>& a, int n);
  1706.  template complex<float>  RWSTDExportTemplate pow (const complex<float>& a, float s);
  1707.  template complex<double>  RWSTDExportTemplate pow (const complex<double>& a, double s);
  1708.  template complex<long double>  RWSTDExportTemplate pow (const complex<long double>& a, long double s);
  1709.  template complex<float> RWSTDExportTemplate pow (float s, const complex<float>& a);
  1710.  template complex<double> RWSTDExporttemplate pow (double s, const complex<double>& a);
  1711.  template complex<long double> RWSTDExporttemplate pow (long double s, const complex<long double>& a);
  1712.  template complex<float> RWSTDExportTemplate pow (const complex<float>& a1, const complex<float>& a2);
  1713.  template complex<double> RWSTDExportTemplate pow (const complex<double>& a1, const complex<double>& a2);
  1714.  template complex<long double> RWSTDExportTemplate pow (const complex<long double>& a1, const complex<long double>& a2);
  1715.  template complex<float> RWSTDExportTemplate log10 (const complex<float>& a);
  1716.  template complex<double> RWSTDExportTemplate log10 (const complex<double>& a);
  1717.  template complex<long double> RWSTDExportTemplate log10 (const complex<long double>& a);       */
  1718.  
  1719.  
  1720. #ifndef RWSTD_NO_NAMESPACE
  1721. }
  1722. #endif
  1723.  
  1724. #endif /* __STD_COMPLEX */
  1725.  
  1726. #endif // __USING_STD_NAMES__
  1727.