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