home *** CD-ROM | disk | FTP | other *** search
/ CD Actual 14 / CDACTUAL.iso / cdactual / demobin / share / program / c / ZPP120.ZIP / COMPLEX.CPP next >
Encoding:
C/C++ Source or Header  |  1993-02-16  |  5.4 KB  |  247 lines

  1. /* -------------------------------------------------------------------- */
  2. /* Z++ Version 1.20                               Last revised 02/15/93 */
  3. /*                                                                      */
  4. /* Complex number class for Turbo C++/Borland C++.                      */
  5. /* Copyright 1992, 1993 by Carl W. Moreland                             */
  6. /*                                                                      */
  7. /* complex.cpp                                                          */
  8. /* -------------------------------------------------------------------- */
  9.  
  10. #include "complex.h"
  11.  
  12. unsigned char complex::zArgMode   = Z_RADIANS;
  13. unsigned char complex::zPrintMode = Z_COMMA;
  14. unsigned char complex::zLetter    = 'i';
  15.  
  16. /* -------------------------------------------------------------------- */
  17.  
  18. double arg(const complex& z)        // argument (angle)
  19. {
  20.   if(z.re == 0 && z.im == 0)        // this is actually a domain error
  21.     return 0;
  22.   if(complex::zArgMode == Z_RADIANS)
  23.     return atan2(z.im, z.re);
  24.   return atan2(z.im, z.re)/M_PI*180;
  25. }
  26.  
  27. complex ptor(double mag, double angle)  // polar-to-rectangular
  28. {
  29.   if(complex::zArgMode == Z_RADIANS)
  30.     return complex(mag*cos(angle), mag*sin(angle));
  31.   return complex(mag*cos(angle/180*M_PI), mag*sin(angle/180*M_PI));
  32. }
  33.  
  34. complex rtop(double x, double y)    // rectangular-to-polar
  35. {
  36.   if(x == 0 && y == 0)            // this is actually a domain error
  37.     return Z0;
  38.   if(complex::zArgMode == Z_RADIANS)
  39.     return complex(sqrt(x*x + y*y), atan2(y, x));
  40.   return complex(sqrt(x*x + y*y), atan2(y, x)*180/M_PI);
  41. }
  42.  
  43. complex& complex::topolar(void)
  44. {
  45.   double re_tmp = re;
  46.  
  47.   if(re != 0 || im != 0)        // z = (0,0) is a domain error
  48.   {
  49.     re = sqrt(re*re + im*im);
  50.     im = atan2(im, re_tmp);
  51.   }
  52.  
  53.   if(complex::zArgMode == Z_DEGREES)
  54.     im *= (180/M_PI);
  55.  
  56.   return *this;
  57. }
  58.  
  59. complex& complex::torect(void)
  60. {
  61.   double re_tmp = re;
  62.  
  63.   re = re_tmp*cos(im);
  64.   im = re_tmp*sin(im);
  65.  
  66.   return *this;
  67. }
  68.  
  69. /* ----- Operators ---------------------------------------------------- */
  70.  
  71. complex operator/(const complex& z1, const complex& z2)
  72. {
  73.   if(z2 == Z0)
  74.     return complex(Zinf);        // z2 = Z0 is an error!
  75.  
  76.   double denom = z2.re*z2.re + z2.im*z2.im;
  77.   double re = (z1.re*z2.re + z1.im*z2.im)/denom;
  78.   double im = (z2.re*z1.im - z2.im*z1.re)/denom;
  79.   return complex(re, im);
  80. }
  81.  
  82. complex operator/(const double x, const complex& z)
  83. {
  84.   if(z == Z0)
  85.     return complex(Zinf);        // z = Z0 is an error!
  86.  
  87.   double denom = z.re*z.re + z.im*z.im;
  88.   return complex(x*z.re/denom, -z.im*x/denom);
  89. }
  90.  
  91. /* ----- Math functions ----------------------------------------------- */
  92.  
  93. double abs(const complex& z)
  94. {
  95.   return sqrt(z.re*z.re + z.im*z.im);
  96. }
  97.  
  98. complex sqrt(const complex& z)
  99. {
  100.   return ptor(sqrt(abs(z)), arg(z)/2);
  101. }
  102.  
  103. complex pow(const complex& base, const double exponent)
  104. {
  105.   if(base != Z0 && exponent == 0.0)
  106.     return complex(1,0);
  107.  
  108.   if (base == Z0 && exponent > 0)
  109.     return Z0;
  110.  
  111.   // base == Z0 && exponent == 0 is undefined!
  112.  
  113.   return ptor(pow(abs(base), exponent), exponent*arg(base));
  114. }
  115.  
  116. complex pow(const double base, const complex& exponent)
  117. {
  118.   if(base != 0.0 && exponent == Z0)
  119.     return complex(1,0);
  120.  
  121.   if (base == 0 && re(exponent) > 0)
  122.     return complex(0,0);
  123.  
  124.   // base == 0 && re(exponent) == 0 is undefined!
  125.  
  126.   if(base > 0.0)
  127.     return exp(exponent * log(fabs(base)));
  128.  
  129.   return exp(exponent * complex(log(fabs(base)), M_PI));
  130. }
  131.  
  132. complex pow(const complex& base, const complex& exponent)
  133. {
  134.   if(base != Z0 && exponent == Z0)
  135.     return complex(1,0);
  136.  
  137.   if(base == Z0 && re(exponent) > 0)
  138.     return complex(0,0);
  139.  
  140.   // base == Z0 && re(exponent) == 0 is undefined!
  141.  
  142.   return exp(exponent * log(base));
  143. }
  144.  
  145. /* ----- Trig functions ----------------------------------------------- */
  146.  
  147. complex exp(const complex& z)
  148. {
  149.   double mag = exp(z.re);
  150.   return complex(mag*cos(z.im), mag*sin(z.im));
  151. }
  152.  
  153. complex log(const complex& z)
  154. {
  155.   return complex(log(mag(z)), atan2(z.im, z.re));
  156. }
  157.  
  158. complex log10(const complex& z)
  159. {
  160.   return log(z) * M_LOG10E;
  161. }
  162.  
  163. complex sin(const complex& z)
  164. {
  165.   return (exp(Zi*z) - exp(-Zi*z))/(2*Zi);
  166. }
  167.  
  168. complex cos(const complex& z)
  169. {
  170.   return (exp(Zi*z) + exp(-Zi*z))/2;
  171. }
  172.  
  173. complex tan(const complex& z)
  174. {
  175.   return sin(z)/cos(z);
  176. }
  177.  
  178. complex asin(const complex& z)
  179. {
  180.   return -Zi*log(Zi*z+sqrt(1-z*z));
  181. }
  182.  
  183. complex acos(const complex& z)
  184. {
  185.   return -Zi*log(z+Zi*sqrt(1-z*z));
  186. }
  187.  
  188. complex atan(const complex& z)
  189. {
  190.   return -0.5*Zi * log((1+Zi*z)/(1-Zi*z));
  191. }
  192.  
  193. complex sinh(const complex& z)
  194. {
  195.   return (exp(z) - exp(-z))/2;
  196. }
  197.  
  198. complex cosh(const complex& z)
  199. {
  200.   return (exp(z) + exp(-z))/2;
  201. }
  202.  
  203. complex tanh(const complex& z)
  204. {
  205.   return sinh(z)/cosh(z);
  206. }
  207.  
  208. /* ----- Stream I/O --------------------------------------------------- */
  209.  
  210. ostream& operator<<(ostream& s, const complex& z)
  211. {
  212.   char sign[] = "   ";
  213.  
  214.   if(complex::zPrintMode == Z_COMMA)
  215.     return s << "(" << z.re << ", " << z.im << ")";
  216.  
  217.   if(z.im == 0 || z.im/fabs(z.im) == 1)
  218.     sign[1] = '+';
  219.   else
  220.     sign[1] = '-';
  221.   return s << z.re << sign << complex::zLetter << fabs(z.im);
  222.  
  223. }
  224.  
  225. istream& operator>>(istream& s, complex& z)
  226. {
  227.   char ch;
  228.  
  229.   s >> ch;
  230.   if(ch == '(')
  231.   {
  232.     s >> z.re >> ch;
  233.     if(ch == ',')
  234.       s >> z.im >> ch;
  235.     if(ch != ')')
  236.       s.clear(ios::badbit | s.rdstate());
  237.   }
  238.   else
  239.   {
  240.     s.putback(ch);
  241.     s >> z.re;
  242.   }
  243.  
  244.   return s;
  245. }
  246.  
  247.