diff --git a/README.md b/README.md index 9916b82..4d926c5 100644 --- a/README.md +++ b/README.md @@ -58,3 +58,7 @@ assert(!crc(uint32_t(~0x1C291CA3))); Implemented [Simple linear regression](https://en.wikipedia.org/wiki/Simple_linear_regression) for [Regression analysis](https://en.wikipedia.org/wiki/Regression_analysis) of data. +### [complex.hh](complex.hh) + +Faster alternative (no Inf/NaN handling) to the std::complex implementation. + diff --git a/complex.hh b/complex.hh new file mode 100644 index 0000000..81a9ca5 --- /dev/null +++ b/complex.hh @@ -0,0 +1,128 @@ +/* +Fast complex math + +Copyright 2018 Ahmet Inan +*/ + +#ifndef COMPLEX_HH +#define COMPLEX_HH + +template +class Complex +{ + T re, im; +public: + typedef T value_type; + Complex() : re(0), im(0) {} + Complex(T r) : re(r), im(0) {} + Complex(T r, T i) : re(r), im(i) {} + inline T real() const { return re; } + inline T imag() const { return im; } + inline void real(T r) { re = r; } + inline void imag(T i) { im = i; } + inline Complex operator = (T a) + { + real() = a; + imag() = 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 inline Complex operator + (Complex a, Complex b) +{ + return Complex(a.real() + b.real(), a.imag() + b.imag()); +} + +template +static inline Complex operator + (Complex a) +{ + return a; +} + +template +static inline Complex operator - (Complex a, Complex b) +{ + return Complex(a.real() - b.real(), a.imag() - b.imag()); +} + +template +static inline Complex operator - (Complex a) +{ + return Complex(-a.real(), -a.imag()); +} + +template +static inline Complex operator * (T a, Complex b) +{ + return Complex(a * b.real(), a * b.imag()); +} + +template +static inline Complex operator / (Complex a, T b) +{ + return Complex(a.real() / b, a.imag() / b); +} + +template +static inline 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 inline 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 inline Complex exp(Complex a) +{ + return Complex(exp(a.real()) * cos(a.imag()), exp(a.real()) * sin(a.imag())); +} + +template +static inline T abs(Complex a) +{ + return hypot(a.real(), a.imag()); +} + +template +static inline T arg(Complex a) +{ + return atan2(a.imag(), a.real()); +} + +template +static inline T norm(Complex a) +{ + return a.real() * a.real() + a.imag() * a.imag(); +} + +#endif