/* Fast complex math Copyright 2018 Ahmet Inan */ #pragma once namespace DSP { template class Complex { T re, im; public: typedef T value_type; constexpr Complex() : re(0), im(0) {} constexpr Complex(T r) : re(r), im(0) {} constexpr Complex(T r, T i) : re(r), im(i) {} constexpr T real() const { return re; } constexpr T imag() const { return im; } inline void real(T r) { re = r; } inline void imag(T i) { im = i; } inline Complex operator = (T a) { re = a; im = 0; return *this; } inline Complex operator += (Complex a) { return *this = a + *this; } inline Complex operator -= (Complex a) { return *this = *this - a; } inline Complex operator *= (Complex a) { return *this = a * *this; } inline Complex operator *= (T a) { return *this = a * *this; } inline Complex operator /= (T a) { return *this = *this / a; } inline Complex operator /= (Complex a) { return *this = *this / a; } }; template static constexpr Complex operator + (Complex a, Complex b) { return Complex(a.real() + b.real(), a.imag() + b.imag()); } template static constexpr Complex operator + (Complex a) { return a; } template static constexpr Complex operator - (Complex a, Complex b) { return Complex(a.real() - b.real(), a.imag() - b.imag()); } template static constexpr Complex operator - (Complex a) { return Complex(-a.real(), -a.imag()); } template static constexpr Complex operator * (T a, Complex b) { return Complex(a * b.real(), a * b.imag()); } template static constexpr Complex operator / (Complex a, T b) { return Complex(a.real() / b, a.imag() / b); } template static constexpr Complex operator * (Complex a, Complex b) { return Complex(a.real() * b.real() - a.imag() * b.imag(), a.real() * b.imag() + a.imag() * b.real()); } template static constexpr Complex operator / (Complex a, Complex b) { return Complex((a.real() * b.real() + a.imag() * b.imag()) / (b.real() * b.real() + b.imag() * b.imag()), (a.imag() * b.real() - a.real() * b.imag()) / (b.real() * b.real() + b.imag() * b.imag())); } template static constexpr Complex conj(Complex a) { return Complex(a.real(), -a.imag()); } template static constexpr T norm(Complex a) { return a.real() * a.real() + a.imag() * a.imag(); } template static constexpr T abs(Complex a) { return sqrt(norm(a)); } template static constexpr T arg(Complex a) { return atan2(a.imag(), a.real()); } template static constexpr Complex polar(T a, T b) { return Complex(a * cos(b), a * sin(b)); } }