diff --git a/src/Math/Complex.h b/src/Math/Complex.h index 71710f371..72fed26e3 100644 --- a/src/Math/Complex.h +++ b/src/Math/Complex.h @@ -37,6 +37,18 @@ template class Complex { public: typedef T Type; /**< @brief Underlying data type */ + /** + * @brief Dot product + * + * @f[ + * c_0 \cdot c_1 = c_0 \overline{c_1} = (a_0 a_1 + b_0 b_1) + i(a_1 b_0 - a_0 b_1) + * @f] + * @see dot() const + */ + inline static Complex dot(const Complex& a, const Complex& b) { + return a*b.conjugated(); + } + /** * @brief Default constructor * @@ -183,6 +195,36 @@ template class Complex { _imaginary*other._real + _real*other._imaginary}; } + /** + * @brief Dot product of the complex number + * + * Should be used instead of length() for comparing complex number length + * with other values, because it doesn't compute the square root. @f[ + * c \cdot c = c \overline c = a^2 + b^2 + * @f] + * @see dot(const Complex&, const Complex&) + */ + inline T dot() const { + return _real*_real + _imaginary*_imaginary; + } + + /** + * @brief %Complex number length + * + * See also dot() const which is faster for comparing length with other + * values. @f[ + * |c| = \sqrt{c \overline c} = \sqrt{a^2 + b^2} + * @f] + */ + inline T length() const { + return std::hypot(_real, _imaginary); + } + + /** @brief Normalized complex number (of unit length) */ + inline Complex normalized() const { + return (*this)/length(); + } + private: T _real, _imaginary; }; diff --git a/src/Math/Test/ComplexTest.cpp b/src/Math/Test/ComplexTest.cpp index 8c06bcf2f..9916ed582 100644 --- a/src/Math/Test/ComplexTest.cpp +++ b/src/Math/Test/ComplexTest.cpp @@ -35,6 +35,11 @@ class ComplexTest: public Corrade::TestSuite::Tester { void multiplyDivideScalar(); void multiply(); + void dot(); + void dotSelf(); + void length(); + void normalized(); + void debug(); }; @@ -50,6 +55,11 @@ ComplexTest::ComplexTest() { &ComplexTest::multiplyDivideScalar, &ComplexTest::multiply, + &ComplexTest::dot, + &ComplexTest::dotSelf, + &ComplexTest::length, + &ComplexTest::normalized, + &ComplexTest::debug); } @@ -128,6 +138,29 @@ void ComplexTest::multiply() { CORRADE_COMPARE(b*a, c); } +void ComplexTest::dot() { + Complex a(5.0f, 3.0f); + Complex b(6.0f, -7.0f); + + CORRADE_COMPARE(Complex::dot(a, b), Complex(9.0f, 53.0f)); +} + +void ComplexTest::dotSelf() { + CORRADE_COMPARE(Complex(-4.0f, 3.0f).dot(), 25.0f); +} + +void ComplexTest::length() { + CORRADE_COMPARE(Complex(-4.0f, 3.0f).length(), 5.0f); +} + +void ComplexTest::normalized() { + Complex a(-3.0f, 4.0f); + Complex b(-0.6f, 0.8f); + + CORRADE_COMPARE(a.normalized(), b); + CORRADE_COMPARE(a.normalized().length(), 1.0f); +} + void ComplexTest::debug() { std::ostringstream o;