Path: utzoo!utgpu!jarvis.csri.toronto.edu!rutgers!apple!agate!ucbvax!hplabs!hp-pcd!hplsla!jima From: jima@hplsla.HP.COM (Jim Adcock) Newsgroups: comp.lang.c++ Subject: A PD complex number capability Message-ID: <6590209@hplsla.HP.COM> Date: 19 Jul 89 20:20:28 GMT Organization: HP Lake Stevens, WA Lines: 175 /***** A PD complex number "work-similar" class. Copyright 1989 James L. Adcock. This work is placed in the public domain, for use without restriction, for the common good of the people. Please do not add usage restrictions to simple derivations of this work. Defined to be able to either give a double precision or single precision capability. If you have an archaic compiler you may have to remove or modify the const keywords in this file. ****/ #ifndef DCMPX_H #define DCMPX_H #define dblepreccomplex #undef snglpreccomplex #define USING_STREAMS #ifdef USING_STREAMS #ifndef STREAM_H #define STREAM_H #include #endif #endif #ifndef MATH_H #define MATH_H #include #endif #ifdef dblepreccomplex #define complex cmpx #define cmpx dcmpx #define basis double #endif #ifdef snglpreccomplex #define fcmpx cmpx #define cmpx scmpx #define basis float #endif #define ZERO (basis(0.0)) /***** In the following, features not found frequently in C++ complex number packages are marked "not common." I have not included definitions for advanced functions since I believe these are more frequently a nuisance than a help. Define them if you like. I have made the real and imag parts "public" as distributed to make this easily possible. You should find this implementation generally faster than other implementations. Error trapping or recovery not attempted. Please let me know if you find any bugs *****/ class cmpx { public: basis r; basis i; public: cmpx(){} /*other packages may initialize to zero*/ cmpx(basis real) {r = real; i = ZERO;} cmpx(basis real, basis imag) {r = real; i = imag;} cmpx(const cmpx& c) {r=c.r; i=c.i;} cmpx& operator=(const cmpx& c) {r=c.r; i=c.i; return *this;} cmpx& operator=(basis b) {r=b; return *this;} basis real() const {return r;} /*not common*/ friend basis real(const cmpx& c) {return c.r;} friend basis imag(const cmpx& c) {return c.i;} basis imag() const {return i;} /*not common*/ basis mag() const {return (basis)sqrt(double(r*r + i*i));} /*not common*/ friend basis mag(const cmpx& c){return c.mag();} /*not common*/ basis abs() const {return (basis)sqrt(double(r*r + i*i));} /*not common*/ friend basis abs(const cmpx& c){return c.mag();} basis magsq() const {return r*r + i*i;} /*not common*/ basis norm() const {return r*r + i*i;} /*not common*/ basis norm(const cmpx& c) {return c.r*c.r + c.i*c.i;} friend basis magsq(const cmpx& c) {return c.r*c.r+c.i*c.i;} basis phase() const {return (basis)atan2(i,r);} /*not common*/ friend basis phase(const cmpx& c) {return atan2(c.i,c.r);} /*not common*/ basis arg() const {return (basis)atan2(i,r);} friend basis arg(const cmpx& c) {return (basis)atan2(c.i,c.r);}/*not common*/ friend cmpx conj(const cmpx& c) {return cmpx(c.r,-c.i);} /*caution -- the following is defined "in place"*/ cmpx& conj() {i = -i; return *this;} /*not common*/ friend ostream& operator<<(ostream& s, const cmpx& c); friend istream& operator>>(istream& s, cmpx& c); friend cmpx polar(basis m, basis p) {return cmpx(m*cos(p), m*sin(p));} friend cmpx polar(basis m) {return cmpx(m);} cmpx operator+(const cmpx& c) const {return cmpx(r+c.r, i+c.i);} cmpx operator+(basis b) const {return cmpx(r+b, i);} friend cmpx operator+(basis b, const cmpx& c) {return cmpx(b+c.r, c.i);} cmpx operator-(const cmpx& c) const {return cmpx(r-c.r, i-c.i);} friend cmpx operator-(basis b, const cmpx& c) {return cmpx(b-c.r, c.i);} cmpx operator-(basis b) const {return cmpx(r-b, i);} cmpx operator*(const cmpx& c) const {return cmpx(r*c.r-i*c.i, r*c.i+i*c.r);} cmpx operator*(basis b) const {return cmpx(r*b, i*b);} friend cmpx operator*(basis b, const cmpx& c) {return cmpx(b*c.r, b*c.i);} friend cmpx operator/(const cmpx& a, const cmpx& b) {basis d=b.r*b.r+b.i*b.i; return cmpx((a.r*b.r+a.i*b.i)/d,(a.i*b.r-a.r*b.i)/d);} cmpx operator/(basis b) const {return cmpx(r/b, i/b);} cmpx operator+() const {return *this;} cmpx operator-() const {return cmpx(-r,-i);} cmpx& operator+=(const cmpx& c) {r += c.r; i += c.i; return *this;} cmpx& operator+=(basis b) {r += b; return *this;} cmpx& operator-=(const cmpx& c) {r -= c.r; i -= c.i; return *this;} cmpx& operator-=(basis b) {r -= b; return *this;} cmpx& operator*=(const cmpx& c) {basis re=r; r = re*c.r-i*c.i; i = re*c.i+i*c.r; return *this;} cmpx& operator*=(basis b) {r *= b; i *= b; return *this;} cmpx& operator/=(const cmpx& c) {basis re; basis d=c.r*c.r+c.i*c.i; re = (r*c.r+i*c.i)/d; i = (i*c.r-r*c.i)/d; r = re; return *this;} cmpx& operator/=(basis b) {r/=b; i/=b; return *this;} int operator!() const {return (r == ZERO) && (i == ZERO);} /*not common*/ friend int operator&&(const cmpx& a, const cmpx& b) /*not common*/ {return ((a.r!=ZERO) || (a.i!=ZERO)) && ((b.r!=ZERO) || (b.i!=ZERO));} friend int operator||(const cmpx& a, const cmpx& b) /*not common*/ { return (a.r!=ZERO) || (a.i!=ZERO) || (b.r!=ZERO) || (b.i!=ZERO);} }; #endif /***************************/ /*the following two should be in a .c file*/ #define USING_STREAMS #ifdef USING_STREAMS /*older C++ compilers may require strings instead of chars below*/ ostream& operator<<(ostream& s, const cmpx& c) { return s << '(' << c.r << '+' << c.i << ')';} istream& operator>>(istream& s, cmpx& c) { s >> c.r >> c.i; return s;} #endif /***************************/ /*a little test program follows*/ main() { complex a, b; while(1) { cout << "\n? ? ? ?\n"; cin >> a >> b; cout << "\na = " << a ; cout << "\nb = " << b ; cout << "\na+b = " << a+b; cout << "\na-b = " << a-b; cout << "\na*b = " << a*b; cout << "\na/b = " << a/b; cout << "\na.mag() = " << a.mag(); cout << "\na.magsq() = " << a.magsq(); cout << "\na.phase() = " << a.phase(); cout << "\na.real() = " << a.real(); cout << "\na.imag() = " << a.imag(); cout << "\n!a = " << (!a); cout << "\na&&b = " << (a&&b); cout << "\na||b = " << (a||b); cout << "\n\n"; } }