| template <typename Type>
|
| class Complex {
| |
| Type re, im;
| |
| public:
| |
| Complex() : re(0),im(0) {} | // Constructors
|
| Complex(const Complex& c) : re(c.re),im(c.im) {}
| |
| Complex(const Type r) : re(r),im(0) {}
| |
| Complex(const Type r, const Type i) : re(r),im(i) {}
| |
| Complex operator=(const Complex& c) { | // Operators
|
| re = c.re;
| |
| im = c.im;
| |
| return *this;
| |
| }
| |
| Complex operator-() {
| |
| return Complex(-re, -im);
| |
| }
| |
| Complex operator+=(const Complex& c) {
| |
| re += c.re;
| |
| im += c.im;
| |
| return *this;
| |
| }
| |
| Complex operator+(const Complex& c) {
| |
| return Complex(re + c.re, im + c.im);
| |
| }
| |
| Complex operator-=(const Complex& c) {
| |
| re -= c.re;
| |
| im -= c.im;
| |
| return *this;
| |
| }
| |
| Complex operator-(const Complex& c) {
| |
| return Complex(re - c.re, im - c.im);
| |
| }
| |
| Complex operator*=(const double d) {
| |
| re = Type(re*d);
| |
| im = Type(im*d);
| |
| return *this;
| |
| }
| |
| Complex operator*=(const Complex& c) {
| |
| Complex cn(re*c.re - im*c.im, re*c.im + im*c.re);
| |
| *this = cn;
| |
| return *this;
| |
| }
| |
| Complex operator*(const double d) {
| |
| return Complex(re*d, im*d);
| |
| }
| |
| Complex operator*(const Complex& c) {
| |
| return Complex(re*c.re - im*c.im, re*c.im + im*c.re);
| |
| }
| |
| Complex operator/=(const double d) {
| |
| re = Type(re/d);
| |
| im = Type(im/d);
| |
| return *this;
| |
| }
| |
| Complex operator/=(const Complex& c) {
| |
| Complex cc(c);
| |
| Type d = (double)c.re*c.re + (double)c.im*c.im;
| |
| cc.im = -cc.im;
| |
| *this = (*this * cc)/d;
| |
| return *this;
| |
| }
| |
| Complex operator/(const double d) {
| |
| return Complex(re/d, im/d);
| |
| }
| |
| Complex operator/(const Complex& c) {
| |
| Complex cc(c);
| |
| double d = (double)c.re*c.re + (double)c.im*c.im;
| |
| cc.im = -cc.im;
| |
| return (*this * cc)/d;
| |
| }
| |
| Type& operator[](const int i) { return (i==0)? re: im; }
| |
| template operator Complex() const {
| |
| return Complex(re, im);
| |
| }
| |
| Type real() { return re; }
| |
| Type imag() { return im; }
| |
| double power() { return (double)re*re + (double)im*im; }
| |
| double amp() { return sqrt((double)re*re + (double)im*im); }
| |
| double phi() { return atan2((double)im, (double)re); }
| |
| Complex conj() { return Complex(re, -im); }
| |
| void set(const double a, const double p) { re = a*cos(p); im = a*sin(p); }
| |
| void real(const Type d) { re = d; }
| |
| void imag(const Type d) { im = d; }
| |
| void amp(const double d) { Type r = d/amp(); re *= r; im *= r; }
| |
| void phi(const double d) { Type a = amp(); re = a*cos(d); im = a*sin(d); }
| |
| void shift_phi(const double d) { Complex c((Type)cos(d), (Type)sin(d)); *this *= c; }
| |
| Complex unpack_first(Complex c) {
| |
| return (*this + c.conj()) * 0.5;
| |
| }
| |
| Complex unpack_second(Complex c) {
| |
| return Complex(0.5*(c.imag() + imag()), 0.5*(c.real() - real()));
| |
| }
| |
| };
| |