//Complex class definition (copyright 1993, Information Disciplines, Inc.) // All functions are in-line. There's no separate implementation code file. // For polar coordinates, this class will use the Angle class if the user // includes it prior to this file. #ifndef COMPLEX /* Multiple definition guard */ #define COMPLEX const Complex /* Conventional notation for constants */ #include /* For sqrt (in abs) and atan (in theta) */ #include "global.hpp" class Complex { double rl, im; // Real & imaginary parts // Constructors and destructor // --------------------------- public: Complex(DOUBLE x = 0, DOUBLE y = 0) : rl(x), im(y) {} // Real & imaginary #ifdef ANGLE Complex(DOUBLE r, ANGLE t) : rl(r*t.cos()), // Rho & theta im(r*t.sin()) {} #endif // The compiler will generate by default an appropriate destructor, // copy constructor, and assignment operator. // Accessors // --------- double realPart() const {return rl;} double imagPart() const {return im;} double rho() const // Magnitude of vector {return sqrt(realPart() * realPart() // from origin of + imagPart() * imagPart());} // complex plane #ifdef ANGLE Angle #else double #endif theta() const // Angle between vector {return atan2(imagPart(),realPart());} // & real-axis // Member operators // ---------------- Complex operator-() const // Unary minus operator {return Complex(-rl, -im);} operator double () const // Conversion to real {assert(im == 0); return rl;} // (Provided that value is real) }; // ************ End of class definition // Non-member operators and functions // ---------------------------------- // These functions are neither member nor friend functions, since they // can gain access to the component data through the accessors. inline double abs (COMPLEX x) // Magnitude or absolute value {return x.rho();} inline ostream& operator<< (ostream& ls, // External representation is COMPLEX rs) // ordered pair in parens. {ls << '(' << rs.realPart() << ", " << rs.imagPart() << ')'; return ls;} // Arithmetic operations // --------------------- inline Complex operator+ (COMPLEX ls, COMPLEX rs) {return Complex(ls.realPart() + rs.realPart(), ls.imagPart() + rs.imagPart());} inline Complex operator- (COMPLEX ls, COMPLEX rs) {return ls + (-rs);} inline Complex operator* (COMPLEX ls, COMPLEX rs) {return Complex (ls.realPart() * rs.realPart() - ls.imagPart() * rs.imagPart(), ls.realPart() * rs.imagPart() + ls.imagPart() * rs.realPart());} inline Complex operator/ (COMPLEX ls, COMPLEX rs) {DOUBLE denom = rs.realPart() * rs.realPart() + rs.imagPart() * rs.imagPart(); return Complex ((ls.realPart() * rs.realPart() + ls.imagPart() * rs.imagPart()) / denom, (rs.realPart() * ls.imagPart() - rs.imagPart() * ls.realPart()) / denom);} inline Complex& operator+= (Complex& ls, COMPLEX rs) {return ls = ls + rs;} inline Complex& operator-= (Complex& ls, COMPLEX rs) {return ls = ls - rs;} inline Complex& operator*= (Complex& ls, COMPLEX rs) {return ls = ls * rs;} inline Complex& operator/= (Complex& ls, COMPLEX rs) {return ls = ls / rs;} // Relational operator // ---------- inline bool operator== (COMPLEX ls, COMPLEX rs) {return ls.realPart() == rs.realPart() && ls.imagPart() == rs.imagPart();} #endif