diff --git a/src/Math/Algorithms/Test/SvdTest.cpp b/src/Math/Algorithms/Test/SvdTest.cpp index 3397f92f3..c46448fc4 100644 --- a/src/Math/Algorithms/Test/SvdTest.cpp +++ b/src/Math/Algorithms/Test/SvdTest.cpp @@ -107,14 +107,14 @@ void SvdTest::testFloat() { /* Test composition (single precision is not enough, test for similarity) */ Matrix8f u2(u[0], u[1], u[2], u[3], u[4], Vector8f(), Vector8f(), Vector8f()); Matrix5x8f w2 = Matrix5x8f::fromDiagonal(w); - CORRADE_VERIFY((u2*w2*v.transposed()-af).maxAbs() < 1.0e-5f); + CORRADE_VERIFY(Math::abs((u2*w2*v.transposed()-af).toVector()).max() < 1.0e-5f); /* Test that V is unitary */ CORRADE_COMPARE(v*v.transposed(), Matrix5f(Matrix5f::Identity)); CORRADE_COMPARE(v.transposed()*v, Matrix5f(Matrix5f::Identity)); /* Test W (single precision is not enough, test for similarity) */ - CORRADE_VERIFY((w-expectedf).maxAbs() < 1.0e-5f); + CORRADE_VERIFY(Math::abs(w-expectedf).max() < 1.0e-5f); } }}}} diff --git a/src/Math/Functions.h b/src/Math/Functions.h index f5af1e56a..fb4bafd1b 100644 --- a/src/Math/Functions.h +++ b/src/Math/Functions.h @@ -126,7 +126,7 @@ perform the operations component-wise. /** @brief Minimum -@see min(), clamp() +@see min(), clamp(), Vector::min() */ #ifdef DOXYGEN_GENERATING_OUTPUT template inline T min(T a, T b); @@ -145,7 +145,7 @@ template inline Vector min(const Vector inline T max(const T& a, const T& b); diff --git a/src/Math/RectangularMatrix.h b/src/Math/RectangularMatrix.h index fb869992d..48b86a3f8 100644 --- a/src/Math/RectangularMatrix.h +++ b/src/Math/RectangularMatrix.h @@ -96,6 +96,17 @@ template class RectangularMatrix { return out; } + /** + * @brief Construct matrix from vector + * + * Rolls the vector into matrix, i.e. first `rows` elements of the + * vector will make first column of resulting matrix. + * @see toVector() + */ + inline static RectangularMatrix fromVector(const Vector& vector) { + return *reinterpret_cast*>(vector.data()); + } + /** @brief Construct zero-filled matrix */ inline constexpr /*implicit*/ RectangularMatrix() {} @@ -381,64 +392,17 @@ template class RectangularMatrix { return out; } - /** @brief Sum of values in the matrix */ - T sum() const { - T out(_data[0].sum()); - - for(std::size_t i = 1; i != cols; ++i) - out += _data[i].sum(); - - return out; - } - - /** @brief Product of values in the matrix */ - T product() const { - T out(_data[0].product()); - - for(std::size_t i = 1; i != cols; ++i) - out *= _data[i].product(); - - return out; - } - - /** @brief Minimal value in the matrix */ - T min() const { - T out(_data[0].min()); - - for(std::size_t i = 1; i != cols; ++i) - out = std::min(out, _data[i].min()); - - return out; - } - - /** @brief Minimal absolute value in the matrix */ - T minAbs() const { - T out(_data[0].minAbs()); - - for(std::size_t i = 1; i != cols; ++i) - out = std::min(out, _data[i].minAbs()); - - return out; - } - - /** @brief Maximal value in the matrix */ - T max() const { - T out(_data[0].max()); - - for(std::size_t i = 1; i != cols; ++i) - out = std::max(out, _data[i].max()); - - return out; - } - - /** @brief Maximal absolute value in the matrix */ - T maxAbs() const { - T out(_data[0].maxAbs()); - - for(std::size_t i = 1; i != cols; ++i) - out = std::max(out, _data[i].maxAbs()); - - return out; + /** + * @brief Convert matrix to vector + * + * Returns the matrix unrolled into one large vector, i.e. first column + * of the matrix will make first `rows` elements of resulting vector. + * Useful for performing vector operations with the matrix (e.g. + * summing the elements etc.). + * @see fromVector() + */ + inline Vector toVector() const { + return *reinterpret_cast*>(data()); } private: diff --git a/src/Math/Test/RectangularMatrixTest.cpp b/src/Math/Test/RectangularMatrixTest.cpp index 9ce624889..ab25a608c 100644 --- a/src/Math/Test/RectangularMatrixTest.cpp +++ b/src/Math/Test/RectangularMatrixTest.cpp @@ -54,12 +54,7 @@ class RectangularMatrixTest: public Corrade::TestSuite::Tester { void transposed(); void diagonal(); - void sum(); - void product(); - void min(); - void minAbs(); - void max(); - void maxAbs(); + void vector(); void debug(); void configuration(); @@ -95,12 +90,7 @@ RectangularMatrixTest::RectangularMatrixTest() { &RectangularMatrixTest::transposed, &RectangularMatrixTest::diagonal, - &RectangularMatrixTest::sum, - &RectangularMatrixTest::product, - &RectangularMatrixTest::min, - &RectangularMatrixTest::minAbs, - &RectangularMatrixTest::max, - &RectangularMatrixTest::maxAbs, + &RectangularMatrixTest::vector, &RectangularMatrixTest::debug, &RectangularMatrixTest::configuration}); @@ -338,50 +328,20 @@ void RectangularMatrixTest::diagonal() { CORRADE_COMPARE(b.diagonal(), diagonal); } -void RectangularMatrixTest::sum() { - Matrix2 matrix(Vector2(1.0f, 2.0f), - Vector2(3.0f, 4.0f)); - CORRADE_COMPARE(matrix.sum(), 10.0f); -} - -void RectangularMatrixTest::product() { - Matrix2 matrix(Vector2(1.0f, 2.0f), - Vector2(3.0f, 4.0f)); - CORRADE_COMPARE(matrix.product(), 24.0f); -} - -void RectangularMatrixTest::min() { - /* Check also that initial value isn't initialized to 0 */ - Matrix2 matrix(Vector2(-2.0f, 1.0f), - Vector2(3.0f, 4.0f)); - CORRADE_COMPARE(matrix.min(), -2.0f); -} +void RectangularMatrixTest::vector() { + typedef Vector<3, Int> Vector3i; + typedef RectangularMatrix<4, 3, Int> Matrix4x3i; + typedef Vector<12, Int> Vector12i; -void RectangularMatrixTest::minAbs() { - /* Check that initial value is absolute and also all others */ - Matrix2 a(Vector2(-2.0f, 1.0f), - Vector2(3.0f, 4.0f)); - Matrix2 b(Vector2(3.0f, 4.0f), - Vector2(-2.0f, 1.0f)); - CORRADE_COMPARE(a.minAbs(), 1.0f); - CORRADE_COMPARE(a.minAbs(), 1.0f); -} + Matrix4x3i a(Vector3i(0, 1, 2), + Vector3i(3, 4, 5), + Vector3i(6, 7, 8), + Vector3i(9, 10, 11)); -void RectangularMatrixTest::max() { - /* Check also that initial value isn't initialized to 0 */ - Matrix2 matrix(Vector2(-2.0f, -1.0f), - Vector2(-3.0f, -4.0f)); - CORRADE_COMPARE(matrix.max(), -1.0f); -} + Vector12i b(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11); -void RectangularMatrixTest::maxAbs() { - /* Check that initial value is absolute and also all others */ - Matrix2 a(Vector2(2.0f, 1.0f), - Vector2(3.0f, -4.0f)); - Matrix2 b(Vector2(3.0f, -4.0f), - Vector2(2.0f, 1.0f)); - CORRADE_COMPARE(a.maxAbs(), 4.0f); - CORRADE_COMPARE(b.maxAbs(), 4.0f); + CORRADE_COMPARE(a.toVector(), b); + CORRADE_COMPARE(Matrix4x3i::fromVector(b), a); } void RectangularMatrixTest::debug() { diff --git a/src/Math/Test/VectorTest.cpp b/src/Math/Test/VectorTest.cpp index 7c93976b6..583df6b19 100644 --- a/src/Math/Test/VectorTest.cpp +++ b/src/Math/Test/VectorTest.cpp @@ -83,9 +83,7 @@ class VectorTest: public Corrade::TestSuite::Tester { void sum(); void product(); void min(); - void minAbs(); void max(); - void maxAbs(); void projected(); void projectedOntoNormalized(); @@ -130,9 +128,7 @@ VectorTest::VectorTest() { &VectorTest::sum, &VectorTest::product, &VectorTest::min, - &VectorTest::minAbs, &VectorTest::max, - &VectorTest::maxAbs, &VectorTest::projected, &VectorTest::projectedOntoNormalized, @@ -331,23 +327,11 @@ void VectorTest::min() { CORRADE_COMPARE(Vector3(1.0f, -2.0f, 3.0f).min(), -2.0f); } -void VectorTest::minAbs() { - /* Check that initial value is absolute and also all others */ - CORRADE_COMPARE(Vector3(-2.0f, 1.0f, 3.0f).minAbs(), 1.0f); - CORRADE_COMPARE(Vector3(1.0f, -2.0f, 3.0f).minAbs(), 1.0f); -} - void VectorTest::max() { /* Check also that initial value isn't initialized to 0 */ CORRADE_COMPARE(Vector3(-1.0f, -2.0f, -3.0f).max(), -1.0f); } -void VectorTest::maxAbs() { - /* Check that initial value is absolute and also all others */ - CORRADE_COMPARE(Vector3(-5.0f, 1.0f, 3.0f).maxAbs(), 5.0f); - CORRADE_COMPARE(Vector3(1.0f, -5.0f, 3.0f).maxAbs(), 5.0f); -} - void VectorTest::projected() { Vector3 line(1.0f, -1.0f, 0.5f); Vector3 projected = Vector3(1.0f, 2.0f, 3.0f).projected(line); diff --git a/src/Math/Vector.h b/src/Math/Vector.h index e49f1700b..ad4ea4314 100644 --- a/src/Math/Vector.h +++ b/src/Math/Vector.h @@ -300,7 +300,7 @@ template class Vector { /** * @brief Add vector * - * @see operator+=() + * @see operator+=(), sum() */ inline Vector operator+(const Vector& other) const { return Vector(*this) += other; @@ -408,7 +408,7 @@ template class Vector { /** * @brief Multiply vector component-wise * - * @see operator*=(const Vector&) + * @see operator*=(const Vector&), product() */ template inline Vector operator*(const Vector& other) const { return Vector(*this) *= other; @@ -499,7 +499,11 @@ template class Vector { return line*dot(*this, line); } - /** @brief Sum of values in the vector */ + /** + * @brief Sum of values in the vector + * + * @see operator+() + */ T sum() const { T out(_data[0]); @@ -509,7 +513,11 @@ template class Vector { return out; } - /** @brief Product of values in the vector */ + /** + * @brief Product of values in the vector + * + * @see operator*(const Vector&) + */ T product() const { T out(_data[0]); @@ -519,7 +527,11 @@ template class Vector { return out; } - /** @brief Minimal value in the vector */ + /** + * @brief Minimal value in the vector + * + * @see Math::min() + */ T min() const { T out(_data[0]); @@ -529,17 +541,11 @@ template class Vector { return out; } - /** @brief Minimal absolute value in the vector */ - T minAbs() const { - T out(std::abs(_data[0])); - - for(std::size_t i = 1; i != size; ++i) - out = std::min(out, std::abs(_data[i])); - - return out; - } - - /** @brief Maximal value in the vector */ + /** + * @brief Maximal value in the vector + * + * @see Math::max() + */ T max() const { T out(_data[0]); @@ -549,16 +555,6 @@ template class Vector { return out; } - /** @brief Maximal absolute value in the vector */ - T maxAbs() const { - T out(std::abs(_data[0])); - - for(std::size_t i = 1; i != size; ++i) - out = std::max(out, std::abs(_data[i])); - - return out; - } - private: /* Implementation for Vector::Vector(const Vector&) */ template inline constexpr explicit Vector(Implementation::Sequence, const Vector& vector): _data{T(vector._data[sequence])...} {}