diff --git a/include/rosa/agent/FunctionAbstractions.hpp b/include/rosa/agent/FunctionAbstractions.hpp index 51801f0..a8aed1e 100644 --- a/include/rosa/agent/FunctionAbstractions.hpp +++ b/include/rosa/agent/FunctionAbstractions.hpp @@ -1,194 +1,223 @@ //===-- rosa/agent/FunctionAbstractions.hpp ---------------------*- C++ -*-===// // // The RoSA Framework // //===----------------------------------------------------------------------===// /// /// \file rosa/agent/FunctionAbstractions.hpp /// /// \author Benedikt Tutzer (benedikt.tutzer@tuwien.ac.at) /// /// \date 2019 /// /// \brief Definition of *FunctionAbstractions* *functionality*. /// //===----------------------------------------------------------------------===// #ifndef ROSA_AGENT_FUNCTIONABSTRACTIONS_HPP #define ROSA_AGENT_FUNCTIONABSTRACTIONS_HPP #include "rosa/agent/Functionality.h" #include "rosa/agent/Abstraction.hpp" #include "rosa/support/debug.hpp" #include #include #include #include namespace rosa { namespace agent { -/// Evaluates a linear function at a given value. +/// Implements \c rosa::agent::Abstraction as a linear function, +/// y = Coefficient * X + Intercept. +/// +/// \note This implementation is supposed to be used to represent a linear +/// function from an arithmetic domain to an arithmetic range. This is enforced +/// statically. /// /// \tparam D type of the functions domain /// \tparam R type of the functions range template class LinearFunction : public Abstraction{ // Make sure the actual type arguments are matching our expectations. STATIC_ASSERT((std::is_arithmetic::value), "LinearFunction not arithmetic T"); STATIC_ASSERT((std::is_arithmetic::value), "LinearFunction not to arithmetic"); protected: + /// The Intercept of the linear function const D Intercept; + /// The Coefficient of the linear function const D Coefficient; public: /// Creates an instance. /// /// \param Intercept the intercept of the linear function /// \param Coefficient the coefficient of the linear function - /// domain LinearFunction(D Intercept, D Coefficient) noexcept : Abstraction(Intercept), Intercept(Intercept), Coefficient(Coefficient) {} /// Destroys \p this object. ~LinearFunction(void) = default; /// Checks wether the Abstraction evaluates to default at the given position /// As LinearFunctions can be evaluated everythwere, this is always false + /// + /// \param V the value at which to check if the function falls back to it's + /// default value. + /// + /// \return false bool isDefaultAt(const D &V) const{ (void)V; return false; } /// Evaluates the linear function /// /// \param X the value at which to evaluate the function - /// \return the result + /// + /// \return Coefficient*X + Intercept virtual R operator()(const D &X) const noexcept override { return Intercept + X*Coefficient; } }; -/// Evaluates a sine function at a given value. +/// Implements \c rosa::agent::Abstraction as a sine function, +/// y = Amplitude * sin(Frequency * X + Phase) + Average. +/// +/// \note This implementation is supposed to be used to represent a sine +/// function from an arithmetic domain to an arithmetic range. This is enforced +/// statically. /// /// \tparam D type of the functions domain /// \tparam R type of the functions range template class SineFunction : public Abstraction{ // Make sure the actual type arguments are matching our expectations. STATIC_ASSERT((std::is_arithmetic::value), "SineFunction not arithmetic T"); STATIC_ASSERT((std::is_arithmetic::value), "SineFunction not to arithmetic"); protected: + /// The frequency of the sine wave const D Frequency; + /// The Ampiltude of the sine wave const D Amplitude; + /// The Phase-shift of the sine wave const D Phase; + /// The y-shift of the sine wave const D Average; public: /// Creates an instance. /// /// \param Frequency the frequency of the sine wave /// \param Amplitude the amplitude of the sine wave /// \param Phase the phase of the sine wave /// \param Average the average of the sine wave - /// domain SineFunction(D Frequency, D Amplitude, D Phase, D Average) noexcept : Abstraction(Average), Frequency(Frequency), Amplitude(Amplitude), Phase(Phase), Average(Average) {} /// Destroys \p this object. ~SineFunction(void) = default; /// Checks wether the Abstraction evaluates to default at the given position /// As SineFunctions can be evaluated everythwere, this is always false + /// + /// \param V the value at which to check if the function falls back to it's + /// default value. + /// + /// \return false bool isDefaultAt(const D &V) const{ (void)V; return false; } - /// Evaluates the linear function + /// Evaluates the sine function /// /// \param X the value at which to evaluate the function - /// \return the result + /// \return the value of the sine-function at X virtual R operator()(const D &X) const noexcept override { return Amplitude*sin(Frequency * X + Phase) + Average; } }; - -/// Implements \c rosa::agent::RangeAbstraction as an abstraction from -/// \c std::map from ranges of a type to abstractions of that type to another -/// type. The resulting abstractions are evaluated for the given values. +/// Implements \c rosa::agent::Abstraction as a partial function from a domain +// /to a range. /// -/// \note This implementation is supposed to be used to abstract ranges of -/// arithmetic types into abstractions from that type to another arithmetic -/// type, which is statically enforced. +/// \note This implementation is supposed to be used to represent a partial +/// function from an arithmetic domain to an arithmetic range. This is enforced +/// statically. /// -/// \invariant The keys in the underlying \c std::map define valid ranges -/// such that `first <= second` and there are no overlapping ranges defined by -/// the keys. +/// A partial function is defined as a list of abstractions, where each +/// abstraction is associated a range in which it is defined. These ranges must +/// be mutually exclusive. /// -/// \tparam D type to abstract from -/// \tparam R type to abstract to +/// \tparam D type of the functions domain +/// \tparam R type of the functions range template class PartialFunction : public Abstraction { // 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"); private: + /// A \c rosa::agent::RangeAbstraction RA is used to represent the association + /// from ranges to Abstractions. + /// This returns the Abstraction that is defined for any given value, or + /// a default Abstraction if no Abstraction is defined for that value. RangeAbstraction>> RA; public: - /// Creates an instance by Initializing the underlying \c RangeAbstraction. + /// Creates an instance by Initializing the underlying \c Abstraction. /// /// \param Map the mapping to do abstraction according to /// \param Default abstraction to abstract to by default /// /// \pre Each key defines a valid range such that `first <= second` and /// there are no overlapping ranges defined by the keys. PartialFunction(const std::map, std::shared_ptr>> &Map, const R Default) : Abstraction(Default), RA(Map, std::shared_ptr> (new Abstraction(Default))) { } /// Destroys \p this object. ~PartialFunction(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 bool isDefaultAt(const D &V) const{ return RA.isDefaultAt(V); } - /// Evaluates an Abstraction from type \p T to type \p A based on the set - /// mapping. - /// - /// Results in the value associated by the set mapping to the argument, or - /// \c rosa::agent::RangeAbstraction::Default if the actual argument is not - /// included in any of the ranges in the set mapping. + /// Searches for an Abstraction for the given value and executes it for that + /// value, if such an Abstraction is found. The default Abstraction is + /// evaluated otherwise. /// /// \param V value to abstract /// /// \return the abstracted value based on the set mapping R operator()(const D &V) const noexcept override { return RA(V)->operator()(V); } }; } // End namespace agent } // End namespace rosa #endif // ROSA_AGENT_FUNCTIONABSTRACTIONS_HPP diff --git a/include/rosa/agent/RangeConfidence.hpp b/include/rosa/agent/RangeConfidence.hpp index d93c00d..1aa95bf 100644 --- a/include/rosa/agent/RangeConfidence.hpp +++ b/include/rosa/agent/RangeConfidence.hpp @@ -1,91 +1,95 @@ //===-- rosa/agent/RangeConfidence.hpp --------------------------*- C++ -*-===// // // The RoSA Framework // //===----------------------------------------------------------------------===// /// /// \file rosa/agent/RangeConfidence.hpp /// /// \author Benedikt Tutzer (benedikt.tutzer@tuwien.ac.at) /// /// \date 2019 /// /// \brief Definition of *RangeConfidence* *functionality*. /// //===----------------------------------------------------------------------===// #ifndef ROSA_AGENT_RANGECONFIDENCE_HPP #define ROSA_AGENT_RANGECONFIDENCE_HPP #include "rosa/agent/Functionality.h" #include "rosa/agent/Abstraction.hpp" #include "rosa/agent/FunctionAbstractions.hpp" #include "rosa/support/debug.hpp" #include #include #include #include namespace rosa { namespace agent { -/// Evaluates a vector of Abstractions at a given value and returns the results -/// as a vector +/// Evaluates a map of ID's to Abstractions at a given value and returns the +/// results as a map from ID's to results of the corresponding Abstraction /// /// \note This implementation is supposed to be used to abstract ranges of -/// arithmetic types into vectors of another arithmetic type, which is -/// statically enforced. +/// arithmetic types into maps whose values are of another arithmetic type, +/// which is statically enforced. /// /// \tparam D type to abstract from -/// \tparam I type -/// \tparam R type to abstract a vector of to +/// \tparam I type the type of the ID's +/// \tparam R type of the range template class RangeConfidence : protected Abstraction>, private std::map>{ // 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"); private: + /// Wether to include default results in the result-map or not bool IgnoreDefaults; public: - /// Creates an instance by Initializing the underlying \c RangeAbstraction. + /// Creates an instance by Initializing the underlying \c Abstraction and + /// \c std::map. /// /// \param Abstractions the Abstractions to be evaluated + /// \param IgnoreDefaults wether to include default results in the result-map + /// or not (defaults to false). RangeConfidence(const std::map> &Abstractions, bool IgnoreDefaults = false) : Abstraction>({}), std::map>(Abstractions), IgnoreDefaults(IgnoreDefaults){ } /// Destroys \p this object. ~RangeConfidence(void) = default; - /// Evaluates an Abstraction from type \p T to type \p A based on the set - /// mapping. - /// - /// Results in the value associated by the set mapping to the argument, or - /// \c rosa::agent::RangeAbstraction::Default if the actual argument is not - /// included in any of the ranges in the set mapping. + /// All Abstractions stored in the underlying \c std::map are evaluated for + /// the given value. Their results are stored in another map, with + /// corresponding keys. + /// If IgnoreDefaults is set, Abstractions that default for that value are not + /// evaluated and inserted into the resulting \c std::map /// /// \param V value to abstract /// - /// \return the abstracted value based on the set mapping + /// \return a \c std::map containing the results of the stored Abstractions, + /// indexable by the key's the Abstractions are associated with std::map operator()(const D &V) const noexcept override { std::map ret; for (auto const& p : ((std::map>)*this)){ if(!IgnoreDefaults || !p.second.isDefaultAt(V)) ret.insert(std::pair(p.first, p.second(V))); } return ret; } }; } // End namespace agent } // End namespace rosa #endif // ROSA_AGENT_RANGECONFIDENCE_HPP