diff --git a/include/rosa/agent/DistanceMetrics.hpp b/include/rosa/agent/DistanceMetrics.hpp index 2c02eb0..5c58198 100644 --- a/include/rosa/agent/DistanceMetrics.hpp +++ b/include/rosa/agent/DistanceMetrics.hpp @@ -1,325 +1,349 @@ //===-- 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); + } }; /// 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 { + 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); } }; /// 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 { + 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); } }; /// 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 { + 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)); } }; /// 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 { + 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)); } }; } // End namespace agent } // End namespace rosa #endif // ROSA_AGENT_DISTANCEMETRICS_HPP