#ifndef COMPLEX_H #define COMPLEX_H #include #include #include class Complex { private: double re; double im; public: Complex(double r = 0., double i = 0.): re(r), im(i) {} double real() const { return re; } double imag() const { return im; } void real(double r) { re = r; } void imag(double i) { im = i; } Complex operator+=(const Complex& z) { re += z.re; im += z.im; return *this; } Complex operator-=(const Complex& z) { re -= z.re; im -= z.im; return *this; } Complex operator*=(const Complex& z) { double r = re*z.re - im*z.im; double i = re*z.im + im*z.re; re = r; im = i; return *this; } Complex inverse() const { // z * z* = re*re + im*im // 1/z = z*/(re*re + im*im) double abs2 = re*re + im*im; return Complex(re/abs2, -im/abs2); } Complex operator/=(const Complex& z) { *this *= z.inverse(); return *this; } }; inline Complex operator+( const Complex& z1, const Complex& z2 ) { Complex res = z1; res += z2; return res; } inline Complex operator-( const Complex& z1, const Complex& z2 ) { Complex res = z1; res -= z2; return res; } inline Complex operator*( const Complex& z1, const Complex& z2 ) { Complex res = z1; res *= z2; return res; } inline Complex operator/( const Complex& z1, const Complex& z2 ) { Complex res = z1; res /= z2; return res; } // std::cout << z; inline std::ostream& operator<<( std::ostream& s, const Complex& z ) { s << z.real() << " + " << z.imag() << "*i"; return s; } // std::cin >> z; inline std::istream& operator>>( std::istream& s, Complex& z ) { double r = 0., i = 0.; s >> r >> i; z.real(r); z.imag(i); return s; } inline double arg(const Complex& z) { return atan2(z.imag(), z.real()); } inline double abs(const Complex& z) { return sqrt(z.real()*z.real() + z.imag()*z.imag()); } inline Complex rootN(const Complex& z, int n) { assert(n > 0); double angle = arg(z)/double(n); double length = pow(abs(z), 1./double(n)); return Complex(length*cos(angle), length*sin(angle)); } Complex unitRoot(int n); #endif