From a11f6d40cf65805f3450cff6c2dd4f706d23d533 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20M=C3=BCller?= <felix.mueller2@mailbox.tu-dresden.de> Date: Wed, 14 Mar 2018 16:27:49 +0100 Subject: [PATCH] fixed min/max bug in FieldMatVec --- src/amdis/common/FieldMatVec.hpp | 47 ++++++++++++++++---------------- test/CMakeLists.txt | 6 ++++ test/FieldMatVecTest.cpp | 12 ++++++++ 3 files changed, 41 insertions(+), 24 deletions(-) diff --git a/src/amdis/common/FieldMatVec.hpp b/src/amdis/common/FieldMatVec.hpp index 90baf9d0..3a62f524 100644 --- a/src/amdis/common/FieldMatVec.hpp +++ b/src/amdis/common/FieldMatVec.hpp @@ -1,6 +1,7 @@ #pragma once #include <algorithm> +#include <limits> #include <dune/common/diagonalmatrix.hh> #include <dune/common/fmatrix.hh> @@ -96,21 +97,19 @@ namespace AMDiS namespace Impl { template <class T, int N, class Operation> - T accumulate(FieldVector<T, N> const& x, Operation op) + T accumulate(FieldVector<T, N> const& x, T init, Operation op) { - T result = 0; for (int i = 0; i < N; ++i) - result = op(result, x[i]); - return result; + init = op(init, x[i]); + return init; } template <class T, int N, class Operation> - T accumulate(FieldMatrix<T, 1, N> const& x, Operation op) + T accumulate(FieldMatrix<T, 1, N> const& x, T init, Operation op) { - T result = 0; for (int i = 0; i < N; ++i) - result = op(result, x[0][i]); - return result; + init = op(init, x[0][i]); + return init; } } // end namespace Impl @@ -119,13 +118,13 @@ namespace AMDiS template <class T, int N> T sum(FieldVector<T, N> const& x) { - return Impl::accumulate(x, Operation::Plus{}); + return Impl::accumulate(x, T(0), Operation::Plus{}); } template <class T, int N> T sum(FieldMatrix<T, 1, N> const& x) { - return Impl::accumulate(x, Operation::Plus{}); + return Impl::accumulate(x, T(0), Operation::Plus{}); } @@ -134,66 +133,66 @@ namespace AMDiS auto unary_dot(FieldVector<T, N> const& x) { auto op = [](auto const& a, auto const& b) { return a + Math::sqr(std::abs(b)); }; - return Impl::accumulate(x, op); + return Impl::accumulate(x, T(0), op); } template <class T, int N> auto unary_dot(FieldMatrix<T, 1, N> const& x) { auto op = [](auto const& a, auto const& b) { return a + Math::sqr(std::abs(b)); }; - return Impl::accumulate(x, op); + return Impl::accumulate(x, T(0), op); } /// Maximum over all vector entries template <class T, int N> auto max(FieldVector<T, N> const& x) { - return Impl::accumulate(x, Operation::Max{}); + return Impl::accumulate(x, std::numeric_limits<T>::lowest(), Operation::Max{}); } template <class T, int N> auto max(FieldMatrix<T, 1, N> const& x) { - return Impl::accumulate(x, Operation::Max{}); + return Impl::accumulate(x, std::numeric_limits<T>::lowest(), Operation::Max{}); } /// Minimum over all vector entries template <class T, int N> auto min(FieldVector<T, N> const& x) { - return Impl::accumulate(x, Operation::Min{}); + return Impl::accumulate(x, std::numeric_limits<T>::max(), Operation::Min{}); } template <class T, int N> auto min(FieldMatrix<T, 1, N> const& x) { - return Impl::accumulate(x, Operation::Min{}); + return Impl::accumulate(x, std::numeric_limits<T>::max(), Operation::Min{}); } /// Maximum of the absolute values of vector entries template <class T, int N> auto abs_max(FieldVector<T, N> const& x) { - return Impl::accumulate(x, Operation::AbsMax{}); + return Impl::accumulate(x, T(0), Operation::AbsMax{}); } template <class T, int N> auto abs_max(FieldMatrix<T, 1, N> const& x) { - return Impl::accumulate(x, Operation::AbsMax{}); + return Impl::accumulate(x, T(0), Operation::AbsMax{}); } /// Minimum of the absolute values of vector entries template <class T, int N> auto abs_min(FieldVector<T, N> const& x) { - return Impl::accumulate(x, Operation::AbsMin{}); + return Impl::accumulate(x, std::numeric_limits<T>::max(), Operation::AbsMin{}); } template <class T, int N> auto abs_min(FieldMatrix<T, 1, N> const& x) { - return Impl::accumulate(x, Operation::AbsMin{}); + return Impl::accumulate(x, std::numeric_limits<T>::max(), Operation::AbsMin{}); } // ---------------------------------------------------------------------------- @@ -205,14 +204,14 @@ namespace AMDiS auto one_norm(FieldVector<T, N> const& x) { auto op = [](auto const& a, auto const& b) { return a + std::abs(b); }; - return Impl::accumulate(x, op); + return Impl::accumulate(x, T(0), op); } template <class T, int N> auto one_norm(FieldMatrix<T, 1, N> const& x) { auto op = [](auto const& a, auto const& b) { return a + std::abs(b); }; - return Impl::accumulate(x, op); + return Impl::accumulate(x, T(0), op); } /** \ingroup vector_norms @@ -237,14 +236,14 @@ namespace AMDiS auto p_norm(FieldVector<T, N> const& x) { auto op = [](auto const& a, auto const& b) { return a + Math::pow<p>(std::abs(b)); }; - return std::pow( Impl::accumulate(x, op), 1.0/p ); + return std::pow( Impl::accumulate(x, T(0), op), 1.0/p ); } template <int p, class T, int N> auto p_norm(FieldMatrix<T, 1, N> const& x) { auto op = [](auto const& a, auto const& b) { return a + Math::pow<p>(std::abs(b)); }; - return std::pow( Impl::accumulate(x, op), 1.0/p ); + return std::pow( Impl::accumulate(x, T(0), op), 1.0/p ); } /** \ingroup vector_norms diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index b4996001..bd94e104 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -1,4 +1,7 @@ +dune_add_test(SOURCES ClonablePtrTest.cpp + LINK_LIBRARIES amdis) + dune_add_test(SOURCES ConceptsTest.cpp LINK_LIBRARIES amdis) @@ -29,3 +32,6 @@ dune_add_test(SOURCES StringTest.cpp dune_add_test(SOURCES TreeDataTest.cpp LINK_LIBRARIES amdis) + +dune_add_test(SOURCES TupleUtilityTest.cpp + LINK_LIBRARIES amdis) diff --git a/test/FieldMatVecTest.cpp b/test/FieldMatVecTest.cpp index 46fc9300..d494f12c 100644 --- a/test/FieldMatVecTest.cpp +++ b/test/FieldMatVecTest.cpp @@ -53,6 +53,18 @@ void test1() AMDIS_TEST_EQ( max(d), -1.0 ); AMDIS_TEST_EQ( abs_min(c), 3.0 ); AMDIS_TEST_EQ( abs_max(c), 5.0 ); + + using V3 = FieldVector<int, 3>; + V3 f{2, 3, 4}; + V3 g{3, -5, 4}; + V3 h{-1, -2, -3}; + AMDIS_TEST_EQ( sum(g), 2 ); + AMDIS_TEST_EQ( min(f), 2 ); + AMDIS_TEST_EQ( min(g), -5 ); + AMDIS_TEST_EQ( max(g), 4 ); + AMDIS_TEST_EQ( max(h), -1 ); + AMDIS_TEST_EQ( abs_min(g), 3 ); + AMDIS_TEST_EQ( abs_max(g), 5 ); } // ----------------------------------------------------------------------------- -- GitLab