diff --git a/include/rosa/agent/DistanceMetrics.hpp b/include/rosa/agent/DistanceMetrics.hpp index e5956be..2c02eb0 100644 --- a/include/rosa/agent/DistanceMetrics.hpp +++ b/include/rosa/agent/DistanceMetrics.hpp @@ -1,158 +1,325 @@ //===-- 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); } }; /// 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 { - // first = sample - // second = history - + R Dist = ((R)V.second) - V.first; + if (Dist == 0) { + return 0; + } else { + Dist = Dist / V.first; + } + return Dist; + } +}; +/// 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> { + // 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) { } + + /// 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 D Norm = 1) const noexcept override { // Daniels 1st proposal - //return (((R)V.second-V.first)*(std::abs(V.first)+1))/(std::pow(V.first,2)+1); + return (((R)V.second-V.first)*(std::abs(V.first)+Norm))/(std::pow(V.first,2)+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> { + // 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) { } + + /// 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 D Norm = 1) 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); + return (((R)V.first-V.second)*(std::abs(V.first-V.second)+Norm))/(std::pow(V.first-V.second,2)+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> { + // 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) { } + + /// 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 D Norm = 1) 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)); - + return ((R)V.first-V.second)*std::abs((R)V.first-V.second)/(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> { + // 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) { } + + /// 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 D Norm = 1) const noexcept override { // Maxis proposal - return ((R)V.first-V.second)/(1+std::abs(V.first-V.second)); - /* - R Norm = ((R)100) - V.first; - R Dist = ((R)V.second) - V.first; - if (Dist == 0) { - return 0; - } else { - Dist = Dist / (V.first+Norm); - } - return Dist;*/ + return ((R)V.first-V.second)/(Norm+std::abs(V.first-V.second)); } }; } // End namespace agent } // End namespace rosa #endif // ROSA_AGENT_DISTANCEMETRICS_HPP