diff --git a/include/rosa/support/math.hpp b/include/rosa/support/math.hpp index a4e6b86..90928b0 100644 --- a/include/rosa/support/math.hpp +++ b/include/rosa/support/math.hpp @@ -1,159 +1,159 @@ //===-- rosa/support/math.hpp -----------------------------------*- C++ -*-===// // // The RoSA Framework // // Distributed under the terms and conditions of the Boost Software License 1.0. // See accompanying file LICENSE. // // If you did not receive a copy of the license file, see // http://www.boost.org/LICENSE_1_0.txt. // //===----------------------------------------------------------------------===// /// /// \file rosa/support/math.hpp /// /// \author David Juhasz (david.juhasz@tuwien.ac.at) /// /// \date 2017 /// /// \brief Math helpers. /// //===----------------------------------------------------------------------===// // !!!!!! Please check lines 60 - 180 forward !!!!!!!!!!!!!! #ifndef ROSA_SUPPORT_MATH_HPP #define ROSA_SUPPORT_MATH_HPP #include "debug.hpp" #include #include #include #include #include #include #include namespace rosa { /// Computes log base 2 of a number. /// /// \param N the number to compute log base 2 for /// /// \return log base 2 of \p N constexpr size_t log2(const size_t N) { return ((N < 2) ? 1 : 1 + log2(N / 2)); } /// Tells the next representable floating point value. /// /// \tparam T type to operate on /// /// \note The second type argument enforces \p T being a floating point type, /// always use the default value! /// /// \param V value to which find the next representable one /// /// \return the next representable value of type \p T after value \p V /// /// \pre Type \p T must be a floating point type, which is enforced by /// `std::enable_if` in the second type argument. template ::value>> T nextRepresentableFloatingPoint(const T V) { return std::nextafter(V, std::numeric_limits::infinity()); } /// Conjuncts two or more values with each other. /// /// \param Data an array of the data /// /// \return the conjunction of the values given as parameter. template CONFDATATYPE fuzzyAND(const std::array & Data) noexcept { STATIC_ASSERT(std::is_arithmetic::value, "Type of FuzzyAnd is not arithmetic"); STATIC_ASSERT(size > 1, "Number of Arguments is to little"); for (auto tmp : Data) ASSERT(tmp <= 1 && tmp >= 0); return *std::min_element(Data.begin(), Data.end()); } /// Conjuncts two or more values with each other. It's a wrapper for \c fuzzyAND() [array] /// /// \param Data first data to get the type explicitly /// /// \param Datan a package of data /// /// \note the types of Datan must be the same type as Data /// /// \return the conjunction of the values given as parameter. template std::enable_if_t< std::conjunction_v...>, CONFDATATYPE> fuzzyAND(const CONFDATATYPE Data, const _CONFDATATYPE... Datan) noexcept { return fuzzyAND( - std::array{Data, Datan...}); + std::array{{Data, Datan...}}); } /// Disjuncts two or more values with each other. /// /// \param Data an array with the data. /// /// \return the disjunction of the values given as parameter. template CONFDATATYPE fuzzyOR(const std::array & Data) noexcept { STATIC_ASSERT(std::is_arithmetic::value, "Type of FuzzyAnd is not arithmetic"); STATIC_ASSERT(size > 1, "Number of Arguments is to little"); ASSERT(std::all_of(Data.begin(), Data.end(), [](const auto &v) { return v <= 1 && v >= 0; })); return *std::max_element(Data.begin(), Data.end()); } /// Disjuncts two or more values with each other. It's a wrapper for \c fuzzyOR() [array] /// /// \param Data first data to get the type explicitly /// /// \param Datan a package of data /// /// \note the types of Datan must be the same type as Data /// /// \return the disjunction of the values given as parameter. template std::enable_if_t< std::conjunction_v...>, CONFDATATYPE> fuzzyOR(const CONFDATATYPE Data, const _CONFDATATYPE... Datan) noexcept { return fuzzyOR( - std::array{Data, Datan...}); + std::array{{Data, Datan...}}); } template PROCDATATYPE relativeDistance(INDATATYPE NewValue, INDATATYPE HistoryValue) noexcept { PROCDATATYPE Dist = HistoryValue - NewValue; if (Dist == 0) { return 0; } else { Dist = Dist / NewValue; if (Dist < 0) { // TODO: I guess this multiplication here should not be done because // it could be that the distance fuzzy functions are not symetrical //(negative and positive side) Dist = Dist * (-1); } return (Dist); } } } // End namespace rosa #endif // ROSA_SUPPORT_MATH_HPP