diff --git a/include/rosa/agent/DistanceMetrics.hpp b/include/rosa/agent/DistanceMetrics.hpp index 5c58198..069d48e 100644 --- a/include/rosa/agent/DistanceMetrics.hpp +++ b/include/rosa/agent/DistanceMetrics.hpp @@ -1,349 +1,345 @@ //===-- rosa/agent/DistanceMetrics.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/agent/DistanceMetrics.hpp /// /// \author Benedikt Tutzer (benedikt.tutzer@tuwien.ac.at) /// /// \date 2020 /// /// \brief Definition of *DistanceMetrics* *functionality*. /// //===----------------------------------------------------------------------===// #ifndef ROSA_AGENT_DISTANCEMETRICS_HPP #define ROSA_AGENT_DISTANCEMETRICS_HPP #include "rosa/agent/Abstraction.hpp" #include "rosa/agent/Functionality.h" #include "rosa/support/debug.hpp" #include namespace rosa { namespace agent { /// Implements \c rosa::agent::Abstraction as the absolute difference between /// two values /// /// \note This implementation is supposed to be used to represent a difference-metric /// function from an arithmetic domain to an arithmetic range. This is enforced /// statically. /// /// \tparam D type of the input values /// \tparam R type of the difference template class AbsoluteDistance : public Abstraction, R> { // Make sure the actual type arguments are matching our expectations. STATIC_ASSERT((std::is_arithmetic::value), "abstracting not arithmetic"); STATIC_ASSERT((std::is_arithmetic::value), "abstracting not to arithmetic"); public: /// Creates an instance by Initializing the underlying \c Abstraction. AbsoluteDistance(void) : Abstraction, R>(0) { } /// Destroys \p this object. ~AbsoluteDistance(void) = default; /// Checks wether the Abstraction evaluates to default at the given position /// /// \param V the value at which to check if the function falls back to it's /// default value. /// /// \return false if the value falls into a defined range and the Abstraction /// defined for that range does not fall back to it's default value. bool isDefaultAt(const std::pair &V) const noexcept override { (void)(V); return false; } /// Calculates the distance-metric for the given value. If this is the first /// value, the Default-Value is returned /// /// \param V value to abstract /// /// \return the absolute distanct R operator()(const std::pair &V) const noexcept override { // @NOTE reached >98% using 1_0.0001_0.005_1_5_absolute // inner 0.0001 // outer 0.005 return (V.first - V.second); } - R operator()(const std::pair &V, const D Norm) const noexcept { - (void)Norm; - return operator()(V); - } }; /// Implements \c rosa::agent::Abstraction as the relative difference between /// two values /// /// \note This implementation is supposed to be used to represent a difference-metric /// function from an arithmetic domain to an arithmetic range. This is enforced /// statically. /// /// \tparam D type of the input values /// \tparam R type of the difference template class RelativeDistance : public Abstraction, R> { // Make sure the actual type arguments are matching our expectations. STATIC_ASSERT((std::is_arithmetic::value), "abstracting not arithmetic"); STATIC_ASSERT((std::is_arithmetic::value), "abstracting not to arithmetic"); public: /// Creates an instance by Initializing the underlying \c Abstraction. RelativeDistance(void) : Abstraction, R>(0) { } /// Destroys \p this object. ~RelativeDistance(void) = default; /// Checks wether the Abstraction evaluates to default at the given position /// /// \param V the value at which to check if the function falls back to it's /// default value. /// /// \return false if the value falls into a defined range and the Abstraction /// defined for that range does not fall back to it's default value. bool isDefaultAt(const std::pair &V) const noexcept override { (void)(V); return false; } /// Calculates the distance-metric for the given value. If this is the first /// value, the Default-Value is returned /// /// \param V value to abstract /// /// \return the absolute distanct R operator()(const std::pair &V) const noexcept override { R Dist = ((R)V.second) - V.first; if (Dist == 0) { return 0; } else { Dist = Dist / V.first; } return Dist; } - R operator()(const std::pair &V, const D Norm) const noexcept { - (void)Norm; - return operator()(V); - } +}; + +template +class NormalizedDistanceMetric : public Abstraction, R> { + + protected: + D Norm = 1; + + NormalizedDistanceMetric() : Abstraction, R>(0) {} + ~NormalizedDistanceMetric(void) = default; + + public: + void setNorm(D _Norm) { + Norm = _Norm; + } + + R operator()(const std::pair &V, D _Norm) const noexcept { + setNorm(_Norm); + return operator()(V); + } }; /// Implements \c rosa::agent::Abstraction /// /// \note This implementation is supposed to be used to represent a difference-metric /// function from an arithmetic domain to an arithmetic range. This is enforced /// statically. /// /// \tparam D type of the input values /// \tparam R type of the difference template -class DanielsDistance1 : public Abstraction, R> { +class DanielsDistance1 : public NormalizedDistanceMetric { // Make sure the actual type arguments are matching our expectations. STATIC_ASSERT((std::is_arithmetic::value), "abstracting not arithmetic"); STATIC_ASSERT((std::is_arithmetic::value), "abstracting not to arithmetic"); public: /// Creates an instance by Initializing the underlying \c Abstraction. - DanielsDistance1(void) : Abstraction, R>(0) { } + DanielsDistance1(void) : NormalizedDistanceMetric() { } /// Destroys \p this object. ~DanielsDistance1(void) = default; /// Checks wether the Abstraction evaluates to default at the given position /// /// \param V the value at which to check if the function falls back to it's /// default value. /// /// \return false if the value falls into a defined range and the Abstraction /// defined for that range does not fall back to it's default value. bool isDefaultAt(const std::pair &V) const noexcept override { (void)(V); return false; } /// Calculates the distance-metric for the given value. If this is the first /// value, the Default-Value is returned /// /// \param V value to abstract /// /// \return the absolute distanct R operator()(const std::pair &V) const noexcept override { // Daniels 1st proposal - return (((R)V.second-V.first)*(std::abs(V.first)+1))/(std::pow(V.first,2)+1); - } - R operator()(const std::pair &V, const D Norm) const noexcept { - // Daniels 1st proposal - return (((R)V.second-V.first)*(std::abs(V.first)+Norm))/(std::pow(V.first,2)+Norm); + return (((R)V.second-V.first)*(std::abs(V.first)+this->Norm))/(std::pow(V.first,2)+this->Norm); } }; /// Implements \c rosa::agent::Abstraction /// /// \note This implementation is supposed to be used to represent a difference-metric /// function from an arithmetic domain to an arithmetic range. This is enforced /// statically. /// /// \tparam D type of the input values /// \tparam R type of the difference template -class DanielsDistance2 : public Abstraction, R> { +class DanielsDistance2 : public NormalizedDistanceMetric { // Make sure the actual type arguments are matching our expectations. STATIC_ASSERT((std::is_arithmetic::value), "abstracting not arithmetic"); STATIC_ASSERT((std::is_arithmetic::value), "abstracting not to arithmetic"); public: /// Creates an instance by Initializing the underlying \c Abstraction. - DanielsDistance2(void) : Abstraction, R>(0) { } + DanielsDistance2(void) : NormalizedDistanceMetric() { } /// Destroys \p this object. ~DanielsDistance2(void) = default; /// Checks wether the Abstraction evaluates to default at the given position /// /// \param V the value at which to check if the function falls back to it's /// default value. /// /// \return false if the value falls into a defined range and the Abstraction /// defined for that range does not fall back to it's default value. bool isDefaultAt(const std::pair &V) const noexcept override { (void)(V); return false; } /// Calculates the distance-metric for the given value. If this is the first /// value, the Default-Value is returned /// /// \param V value to abstract /// /// \return the absolute distanct R operator()(const std::pair &V) const noexcept override { // Daniels 2nd proposal - return (((R)V.first-V.second)*(std::abs(V.first-V.second)+1))/(std::pow(V.first-V.second,2)+1); - } - R operator()(const std::pair &V, const D Norm) const noexcept { - // Daniels 2nd proposal - return (((R)V.first-V.second)*(std::abs(V.first-V.second)+Norm))/(std::pow(V.first-V.second,2)+Norm); + return (((R)V.first-V.second)*(std::abs(V.first-V.second)+this->Norm))/(std::pow(V.first-V.second,2)+this->Norm); } }; /// Implements \c rosa::agent::Abstraction /// /// \note This implementation is supposed to be used to represent a difference-metric /// function from an arithmetic domain to an arithmetic range. This is enforced /// statically. /// /// \tparam D type of the input values /// \tparam R type of the difference template -class DanielsDistance3 : public Abstraction, R> { +class DanielsDistance3 : public NormalizedDistanceMetric { // Make sure the actual type arguments are matching our expectations. STATIC_ASSERT((std::is_arithmetic::value), "abstracting not arithmetic"); STATIC_ASSERT((std::is_arithmetic::value), "abstracting not to arithmetic"); public: /// Creates an instance by Initializing the underlying \c Abstraction. - DanielsDistance3(void) : Abstraction, R>(0) { } + DanielsDistance3(void) : NormalizedDistanceMetric() { } /// Destroys \p this object. ~DanielsDistance3(void) = default; /// Checks wether the Abstraction evaluates to default at the given position /// /// \param V the value at which to check if the function falls back to it's /// default value. /// /// \return false if the value falls into a defined range and the Abstraction /// defined for that range does not fall back to it's default value. bool isDefaultAt(const std::pair &V) const noexcept override { (void)(V); return false; } /// Calculates the distance-metric for the given value. If this is the first /// value, the Default-Value is returned /// /// \param V value to abstract /// /// \return the absolute distanct R operator()(const std::pair &V) const noexcept override { // Daniels 3rd proposal - return ((R)V.first-V.second)*std::abs((R)V.first-V.second)/(1+std::abs((R)V.first-V.second)); - } - R operator()(const std::pair &V, const D Norm) const noexcept { - // Daniels 3rd proposal - return ((R)V.first-V.second)*std::abs((R)V.first-V.second)/(Norm+std::abs((R)V.first-V.second)); + return ((R)V.first-V.second)*std::abs((R)V.first-V.second)/(this->Norm+std::abs((R)V.first-V.second)); } }; /// Implements \c rosa::agent::Abstraction /// /// \note This implementation is supposed to be used to represent a difference-metric /// function from an arithmetic domain to an arithmetic range. This is enforced /// statically. /// /// \tparam D type of the input values /// \tparam R type of the difference template -class MaxisDistance1 : public Abstraction, R> { +class MaxisDistance1 : public NormalizedDistanceMetric { // Make sure the actual type arguments are matching our expectations. STATIC_ASSERT((std::is_arithmetic::value), "abstracting not arithmetic"); STATIC_ASSERT((std::is_arithmetic::value), "abstracting not to arithmetic"); public: /// Creates an instance by Initializing the underlying \c Abstraction. - MaxisDistance1(void) : Abstraction, R>(0) { } + MaxisDistance1(void) : NormalizedDistanceMetric() { } /// Destroys \p this object. ~MaxisDistance1(void) = default; /// Checks wether the Abstraction evaluates to default at the given position /// /// \param V the value at which to check if the function falls back to it's /// default value. /// /// \return false if the value falls into a defined range and the Abstraction /// defined for that range does not fall back to it's default value. bool isDefaultAt(const std::pair &V) const noexcept override { (void)(V); return false; } /// Calculates the distance-metric for the given value. If this is the first /// value, the Default-Value is returned /// /// \param V value to abstract /// /// \return the absolute distanct R operator()(const std::pair &V) const noexcept override { // Maxis proposal - return ((R)V.first-V.second)/(1+std::abs(V.first-V.second)); - } - R operator()(const std::pair &V, const D Norm) const noexcept { - // Maxis proposal - return ((R)V.first-V.second)/(Norm+std::abs(V.first-V.second)); + return ((R)V.first-V.second)/(this->Norm+std::abs(V.first-V.second)); } }; } // End namespace agent } // End namespace rosa #endif // ROSA_AGENT_DISTANCEMETRICS_HPP