Mercurial > hg > x
comparison xcomplex.h @ 1:6422640a802f
first upload
author | Wen X <xue.wen@elec.qmul.ac.uk> |
---|---|
date | Tue, 05 Oct 2010 10:45:57 +0100 |
parents | |
children | 5f3c32dc6e17 |
comparison
equal
deleted
inserted
replaced
0:9b9f21935f24 | 1:6422640a802f |
---|---|
1 #ifndef XCOMPLEX | |
2 #define XCOMPLEX | |
3 | |
4 | |
5 /* | |
6 xcomplex.h - Xue's complex number class. | |
7 | |
8 This classes is modelled after standard c++ complex class, with a few additional methods. Unused | |
9 standard member and non-member functions/operators may not have been implemented. | |
10 */ | |
11 | |
12 #include <math.h> | |
13 | |
14 //* | |
15 template <class T> class cmplx | |
16 { | |
17 public: | |
18 //standard members | |
19 T x; | |
20 T y; | |
21 cmplx(){} | |
22 cmplx(const T& c, const T& d) {x=c; y=d;} | |
23 cmplx(const T& c) {x=c; y=0;} | |
24 template<class X> cmplx(const cmplx<X>& c){x=c.x, y=c.y;} | |
25 | |
26 T real(){return x;} | |
27 T imag(){return y;} | |
28 | |
29 cmplx<T>& operator=(const T& c){x=c; y=0; return *this;} | |
30 template<class X> cmplx<T>& operator+=(const X& c){x+=c; y=0; return *this;} | |
31 template<class X> cmplx<T>& operator-=(const X& c){x-=c; y=0; return *this;} | |
32 template<class X> cmplx<T>& operator*=(const X& c){x*=c; y*=c; return *this;} | |
33 template<class X> cmplx<T>& operator/=(const X& c){x/=c; y/=c; return *this;} | |
34 template<class X> cmplx<T>& operator=(const cmplx<X>& c){x=c.x; y=c.y; return* this;} | |
35 | |
36 template<class X> cmplx<T>& operator+=(const cmplx<X>& c){x+=c.x; y+=c.y; return *this;} | |
37 template<class X> cmplx<T>& operator-=(const cmplx<X>& c){x-=c.x; y-=c.y; return *this;} | |
38 template<class X> cmplx<T>& operator*=(const cmplx<X>& c){T tmpx=x*c.x-y*c.y; y=x*c.y+y*c.x; x=tmpx; return *this;} | |
39 template<class X> cmplx<T>& operator/=(const cmplx<X>& c){if (c.y==0){x/=c.x; y/=c.x;} else if (c.x==0){T tmpx=y/c.y; y=-x/c.y; x=tmpx;} else {T xm=c.x*c.x+c.y*c.y; T tmpx=(c.x*x+c.y*y)/xm; y=(y*c.x-x*c.y)/xm; x=tmpx;} return *this;} | |
40 | |
41 //non-standard members | |
42 //operator~: square of absolute value | |
43 T operator~() {return x*x+y*y;} | |
44 //operator*: complex conjugate | |
45 cmplx<T> operator*(){cmplx<T> result; result.x=x; result.y=-y; return result;} | |
46 //operator^: multiplicaiton with the complex conjugate of the argument | |
47 cmplx<T> operator^(const cmplx &b){cmplx<T> result; result.x=x*b.x+y*b.y; result.y=y*b.x-x*b.y; return result;} | |
48 //cinv: complex reciprocal | |
49 cmplx<T> cinv(){cmplx<T> result; if (y==0) result.x=1/x, result.y=0; else if (x==0) result.y=-1/y, result.x=0; else{T xm=x*x+y*y; result.x=x/xm; result.y=-y/xm;} return result;} | |
50 //rotate: rotate by an angle | |
51 cmplx<T>& rotate(const T ph) {double s=sin(ph), c=cos(ph), tmpx; tmpx=x*c-y*s; y=x*s+y*c; x=tmpx; return *this;} | |
52 }; //*/ | |
53 //standard Non-member Operators | |
54 template<class Ta, class Tb> cmplx<Ta> operator+(const cmplx<Ta>& a, const cmplx<Tb>& b){cmplx<Ta> result=a; result+=b; return result;} | |
55 template<class Ta, class Tb> cmplx<Ta> operator+(const cmplx<Ta>& a, Tb& b){cmplx<Ta> result=a; result+=b; return result;} | |
56 template<class T> cmplx<T> operator+(T a, const cmplx<T>& b){cmplx<T> result=a; result+=b; return result;} | |
57 template<class Ta, class Tb> cmplx<Ta> operator-(const cmplx<Ta>& a, const cmplx<Tb>& b){cmplx<Ta> result=a; result-=b; return result;} | |
58 template<class Ta, class Tb> cmplx<Ta> operator-(const cmplx<Ta>& a, Tb& b){cmplx<Ta> result=a; result-=b; return result;} | |
59 template<class T> cmplx<T> operator-(T a, const cmplx<T>& b){cmplx<T> result=a; result-=b; return result;} | |
60 template<class Ta, class Tb> cmplx<Ta> operator*(const cmplx<Ta>& a, const cmplx<Tb>& b){cmplx<Ta> result=a; result*=b; return result;} | |
61 template<class Ta, class Tb> cmplx<Ta> operator*(const cmplx<Ta>& a, Tb& b){cmplx<Ta> result=a; result*=b; return result;} | |
62 template<class T> cmplx<T> operator*(T& a, const cmplx<T>& b){cmplx<T> result=b; result*=a; return result;} | |
63 template<class Ta, class Tb> cmplx<Ta> operator/(const cmplx<Ta>& a, const cmplx<Tb>& b){cmplx<Ta> result=a; result/=b; return result;} | |
64 template<class Ta, class Tb> cmplx<Ta> operator/(const cmplx<Ta>& a, Tb& b){cmplx<Ta> result=a; result/=b; return result;} | |
65 template<class T> cmplx<T> operator/(T a, const cmplx<T>& b){cmplx<T> result=a; result/=b; return result;} | |
66 template<class T> cmplx<T> operator+(const cmplx<T>& a){return a;} | |
67 template<class T> cmplx<T> operator-(const cmplx<T>& a){cmplx<T> result; result.x=-a.x; result.y=-a.y; return result;} | |
68 template<class Ta, class Tb> bool operator==(const cmplx<Ta>& a, const cmplx<Tb>& b){return (a.x==b.x && a.y==b.y);} | |
69 template<class Ta, class Tb> bool operator==(const cmplx<Ta>& a, Tb b){return (a.x==b && a.y==0);} | |
70 template<class Ta, class Tb> bool operator==(Ta a, const cmplx<Tb>& b){return (a==b.x && 0==b.y);} | |
71 template<class Ta, class Tb> bool operator!=(const cmplx<Ta>& a, const cmplx<Tb>& b){return (a.x!=b.x || a.y!=b.y);} | |
72 template<class Ta, class Tb> bool operator!=(const cmplx<Ta>& a, Tb b){return (a.x!=b || a.y!=0);} | |
73 template<class Ta, class Tb> bool operator!=(Ta a, const cmplx<Tb>& b){return (a!=b.x || 0!=b.y);} | |
74 /* | |
75 template <class T, class charT, class traits> basic_istream<charT, traits>& operator>>(istream&, complex<T>&); | |
76 template <class T, class charT, class traits> basic_ostream<charT, traits>& operator<<(ostream&, const complex<T>&); | |
77 */ | |
78 //Values | |
79 template<class T> T real(const cmplx<T>& a){return a.x;} | |
80 template<class T> T imag(const cmplx<T>& a){return a.y;} | |
81 template<class T> T abs(const cmplx<T>& a){return sqrt(a.x*a.x+a.y*a.y);} | |
82 template<class T> T fabs(const cmplx<T>& a){return sqrt(a.x*a.x+a.y*a.y);} | |
83 template<class T> T arg(const cmplx<T>& a){return (a.x==0 && a.y==0)?0:atan2(a.y, a.x);} | |
84 template<class T> T norm(const cmplx<T>& a){return a.x*a.x+a.y*a.y;} | |
85 template<class T> cmplx<T> conj(const cmplx<T>& a){cmplx<T> result; result.x=a.x; result.y=-a.y; return result;} | |
86 template<class T> cmplx<T> polar(const T& r, const T& theta){cmplx<T> result; result.x=r*cos(theta); result.y=r*sin(theta); return result;} | |
87 //Transcendentals | |
88 /* | |
89 template<class T> cmplx<T> cos (const cmplx<T>&); | |
90 template<class T> cmplx<T> cosh (const cmplx<T>&); | |
91 */ | |
92 template<class T> cmplx<T> exp(const cmplx<T>& a){return polar(exp(a.x), a.y);} | |
93 template<class T> cmplx<T> log(const cmplx<T>& a){cmplx<T> result; result.x=0.5*log(norm(a)); result.y=arg(a); return result;} | |
94 /* | |
95 template<class T> cmplx<T> log10 (const cmplx<T>&); | |
96 template<class T> cmplx<T> pow (const cmplx<T>&, int); | |
97 */ | |
98 template<class T> cmplx<T> pow(const cmplx<T>& a, T& e){cmplx<T> result; T rad=abs(a); T angle=arg(a); return polar(rad, angle*e);} | |
99 /* | |
100 template<class T> cmplx<T> pow (const cmplx<T>&, const cmplx<T>&); | |
101 template<class T> cmplx<T> pow (const T&, const cmplx<T>&); | |
102 template<class T> cmplx<T> sin (const cmplx<T>&); | |
103 template<class T> cmplx<T> sinh (const cmplx<T>&); | |
104 */ | |
105 template<class T> cmplx<T> sqrt(const cmplx<T>& a){cmplx<T> result; if (a.y==0) {if (a.x>=0){result.x=sqrt(a.x); result.y=0;} else{result.y=sqrt(-a.x); result.x=0;}} else {result.y=sqrt((sqrt(a.x*a.x+a.y*a.y)-a.x)*0.5); result.x=0.5*a.y/result.y;} return result;} | |
106 /* | |
107 template<class T> cmplx<T> tan (const cmplx<T>&); | |
108 template<class T> cmplx<T> tanh (const cmplx<T>&); | |
109 */ | |
110 | |
111 //non-standard non-member functions | |
112 //template operator^: multiplying one complex number with the complex conjugate of another | |
113 template<class T> cmplx<T> operator^(const cmplx<T>& a, const cmplx<T>& b){cmplx<T> result=a; result^=b; return result;} | |
114 | |
115 typedef cmplx<double> cdouble; | |
116 typedef cmplx<float> cfloat; | |
117 | |
118 #endif |