home *** CD-ROM | disk | FTP | other *** search
- /*
- Copyright (C) 1988 Free Software Foundation
- written by Doug Lea (dl@rocky.oswego.edu)
-
- This file is part of GNU CC.
-
- GNU CC is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY. No author or distributor
- accepts responsibility to anyone for the consequences of using it
- or for whether it serves any particular purpose or works at all,
- unless he says so in writing. Refer to the GNU CC General Public
- License for full details.
-
- Everyone is granted permission to copy, modify and redistribute
- GNU CC, but only under the conditions described in the
- GNU CC General Public License. A copy of this license is
- supposed to have been given to you along with GNU CC so you
- can know your rights and responsibilities. It should be in a
- file named COPYING. Among other things, the copyright notice
- and this notice must be preserved on all copies.
- */
-
- #include <Complex.h>
- #include <std.h>
-
- // error handling
-
- void default_Complex_error_handler(char* msg)
- {
- cerr << "Fatal Complex arithmetic error. " << msg << "\n";
- exit(1);
- }
-
- one_arg_error_handler_t Complex_error_handler = default_Complex_error_handler;
-
- one_arg_error_handler_t set_Complex_error_handler(one_arg_error_handler_t f)
- {
- one_arg_error_handler_t old = Complex_error_handler;
- Complex_error_handler = f;
- return old;
- }
-
- void Complex::error(char* msg)
- {
- (*Complex_error_handler)(msg);
- }
-
- Complex operator / (Complex& x, Complex& y)
- {
- double den = norm(y);
- if (den == 0.0) x.error ("Attempted division by zero.");
- return Complex((x.re * y.re + x.im * y.im) / den,
- (x.im * y.re - x.re * y.im) / den);
- }
-
- Complex operator / (double x, Complex& y)
- {
- double den = norm(y);
- if (den == 0.0) y.error ("Attempted division by zero.");
- return Complex((x * y.re) / den, -(x * y.im) / den);
- }
-
- Complex operator / (Complex& x, double y)
- {
- if (y == 0.0) x.error ("Attempted division by zero.");
- return Complex(x.re / y, x.im / y);
- }
-
- Complex& Complex::operator /= (Complex& y)
- {
- double den = norm(y);
- if (den == 0.0) error ("Attempted division by zero.");
- double r = (re * y.re + im * y.im) / den;
- im = (im * y.re - re * y.im) / den;
- re = r;
- return *this;
- }
-
- Complex& Complex::operator /= (double y)
- {
- if (y == 0.0) error ("Attempted division by zero.");
- re /= y;
- im /= y;
- return *this;
- }
-
- Complex polar(double r, double t = 0.0)
- {
- return Complex(r * cos(t), r * sin(t));
- }
-
- Complex exp(Complex& x)
- {
- double r = exp(x.re);
- return Complex(r * cos(x.im), r * sin(x.im));
- }
-
- Complex cosh(Complex& x)
- {
- return Complex(cos(x.im) * cosh(x.re), sin(x.im) * sinh(x.re));
- }
-
- Complex sinh(Complex& x)
- {
- return Complex(cos(x.im) * sinh(x.re), sin(x.im) * cosh(x.re));
- }
-
- Complex cos(Complex& x)
- {
- return Complex(cos(x.re) * cosh(x.im), -sin(x.re) * sinh(x.im));
- }
-
- Complex sin(Complex& x)
- {
- return Complex(sin(x.re) * cosh(x.im), cos(x.re) * sinh(x.im));
- }
-
- Complex log(Complex& x)
- {
- double h = hypot(x.re, x.im);
- if (h <= 0.0) x.error("attempted log of zero magnitude number.");
- return Complex(log(h), atan2(x.im, x.re));
- }
-
- Complex pow(Complex& x, Complex& p)
- {
- Complex res;
- if (p.re == 0.0 && p.im == 0.0)
- {
- res.re = 1.0; res.im = 0.0;
- }
- else if (x.re == 0.0 && x.im == 0.0)
- {
- res.re = 0.0; res.im = 0.0;
- }
- else
- {
- double h = hypot(x.re, x.im);
- if (h <= 0.0) x.error("attempted power of zero magnitude number.");
- double lr = exp(log(h) * p.re);
- double li = atan2(x.im, x.re) * p.im;
- res.re = lr * cos(li);
- res.im = lr * sin(li);
- }
- return res;
- }
-
- Complex sqrt(Complex& x)
- {
- double r, i;
- if (x.re == 0.0 && x.im == 0.0)
- r = i = 0.0;
- else
- {
- double s = sqrt((abs(x.re) + hypot(x.re, x.im)) * 0.5);
- double d = (x.im / s) * 0.5;
- if (x.re > 0.0)
- {
- r = s;
- i = d;
- }
- else if (x.im >= 0.0)
- {
- r = d;
- i = s;
- }
- else
- {
- r = -d;
- i = -s;
- }
- }
- return Complex(r, i);
- }
-
-
- Complex pow(Complex& x, long p)
- {
- Complex res;
- if (p == 0)
- {
- res.re = 1.0; res.im = 0.0;
- }
- else if (x == 0.0)
- {
- res.re = 0.0; res.im = 0.0;
- }
- else
- {
- res.re = 1.0; res.im = 0.0;
- Complex b = x;
- if (p < 0)
- {
- p = -p;
- b = 1.0 / b;
- }
- for(;;)
- {
- if (p & 1)
- res *= b;
- if ((p >>= 1) == 0)
- break;
- else
- b *= b;
- }
- }
- return res;
- }
-
- ostream& operator << (ostream& s, Complex& x)
- {
- return s << "(" << x.re << ", " << x.im << ")" ;
- }
-
- istream& operator >> (istream& s, Complex& x)
- {
- char ch;
- s >> WS;
- s.get(ch);
- if (ch == '(')
- {
- s >> x.re;
- s >> WS;
- s.get(ch);
- if (ch == ',')
- {
- s >> x.im;
- s >> WS;
- s .get(ch);
- }
- else
- x.im = 0;
- if (ch != ')')
- s.clear(_bad);
- }
- else
- {
- s.unget(ch);
- s >> x.re;
- x.im = 0;
- }
- return s;
- }
-
-