#ifndef AJLIB_COMPLEX_H #define AJLIB_COMPLEX_H #define _USE_MATH_DEFINES #include #include "vectors.h" template class Complex { public: Complex(Real re, Real im) : x(re), y(im) { } Complex(Real re) : x(re), y(0) { } Complex() { } Complex(const Complex& other) : x(other.x), y(other.y) { } explicit Complex(const Vector2& vector) : x(vector.x), y(vector.y) { } Real modulus() const { return sqrt(modulus2()); } Real modulus2() const { return x*x + y*y; } Real argument() const { return atan2(y, x); } Complex conjugate() const { return Complex(x, -y); } const Complex& operator+=(const Complex& other) { x += other.x; y += other.y; return *this; } const Complex& operator-=(const Complex& other) { x -= other.x; y -= other.y; return *this; } const Complex& operator*=(const Complex& other) { Real xx = x*other.x; Real yy = y*other.y; y = (x+y)*(other.x+other.y)-xx-yy; x = xx-yy; return *this; } const Complex& operator/=(const Complex& other) { Real q = other.modulus2(); *this *= other.conjugate(); *this /= q; return *this; } const Complex& operator+=(const Real& other) { x += other; return *this; } const Complex& operator-=(const Real& other) { x -= other; return *this; } const Complex& operator*=(const Real& other) { x *= other; y *= other; return *this; } const Complex& operator/=(const Real& other) { x /= other; y /= other; return *this; } Complex operator+(const Complex& other) const { Complex t(*this); t += other; return t; } Complex operator-(const Complex& other) const { Complex t(*this); t -= other; return t; } Complex operator*(const Complex& other) const { Complex t(*this); t *= other; return t; } Complex operator/(const Complex& other) const { Complex t(*this); t /= other; return t; } Complex operator+(const Real& other) const { Complex t(*this); t += other; return t; } Complex operator-(const Real& other) const { Complex t(*this); t -= other; return t; } Complex operator*(const Real& other) const { Complex t(*this); t *= other; return t; } Complex operator/(const Real& other) const { Complex t(*this); t /= other; return t; } Complex operator-() const { return Complex(-x, -y); } const Complex& operator=(const Real& re) { x = re; y = 0; return *this; } const Complex& operator=(const Complex& other) { x = other.x; y = other.y; return *this; } bool operator==(const Complex& other) { return x==other.x && y==other.y; } Real x, y; }; template Complex operator*(const Real& x, const Complex& c) { return c*x; } template Complex operator/(const Real& x, const Complex& c) { return Complex(x)/c; } template Complex operator-(const Real& x, const Complex& c) { return Complex(x)-c; } template Complex operator+(const Real& x, const Complex& c) { return c+x; } template Complex exp(const Complex& z) { Real magnitude = exp(z.x); return Complex(magnitude*cos(z.y), magnitude*sin(z.y)); } template Complex log(const Complex& z) { return Complex(log(z.modulus()), z.argument()); } template Complex log(const Complex& z, Real theta) { Real n = floor(((theta - z.argument())/static_cast(M_PI)+1)/2); return Complex(log(z.modulus()), z.argument() + 2*static_cast(M_PI)*n); } template Complex sqrt(const Complex& z) { Real r = z.modulus(); Real x = z.x; if (z.y > 0) return Complex(sqrt((r+x)/2), sqrt((r-x)/2)); return Complex(sqrt((r+x)/2), -sqrt((r-x)/2)); } template Complex pow(const Complex& a,const Complex& b) { return exp(b*log(a)); } template Complex pow(const Complex& a,const Complex& b, Real theta) { return exp(b*log(a, theta)); } template Complex sin(const Complex& z) { return Complex(sin(z.x)*cosh(z.y), cos(z.x)*sinh(z.y)); } template Complex cos(const Complex& z) { return Complex(cos(z.x)*cosh(z.y), -sin(z.x)*sinh(z.y)); } template Complex tan(const Complex& z) { return sin(z)/cos(z); } template Complex atan(const Complex& z) { return Complex(0, -1)*(log(Complex(1+z.y, z.x))-log(Complex(1-z.y, z.x)))/2; } template Complex sinh(const Complex& z) { return Complex(sinh(z.x)*cos(z.y), cosh(z.x)*sin(z.y)); } template Complex cosh(const Complex& z) { return Complex(cosh(z.x)*cos(z.y), sinh(z.x)*sin(z.y)); } template Complex tanh(const Complex& z) { return sinh(z)/cosh(z); } template Complex atanh(const Complex& z) { return log(1+z)-log(1-z)/2; } #endif // AJLIB_COMPLEX_H