diff --git a/include/rosa/agent/CrossReliability.h b/include/rosa/agent/CrossReliability.h new file mode 100644 index 0000000..c2681da --- /dev/null +++ b/include/rosa/agent/CrossReliability.h @@ -0,0 +1,289 @@ +//===-- rosa/delux/CrossReliability.h ---------------------------*- C++ -*-===// +// +// The RoSA Framework +// +//===----------------------------------------------------------------------===// +/// +/// \file rosa/delux/CrossReliability.h +/// +/// \author Daniel Schnoell +/// +/// \date 2019 +/// +/// \brief This file is temporarly for the functions/methods CrossConfidence and +/// CrossReliability. +/// \todo As soon as a Delux Reliabl Agent exist modify to this or add it to the +/// Agent. +/// \todo there is 1 exception that needs to be handled correctly. +/// \note the default search function is extremely slow maby this could be done +/// via template for storage class and the functions/methods to efficiently find +/// the correct LinearFunction +//===----------------------------------------------------------------------===// +#ifndef ROSA_AGENT_CROSSRELIABILITY_H +#define ROSA_AGENT_CROSSRELIABILITY_H + +#include "rosa/agent/Functionality.h" +#include "rosa/agent/LinearFunctions.hpp" +#include "rosa/core/forward_declarations.h" // needed for id_t + +// nedded headers + +#include //assert +#include +// for static methods +#include +#include + +namespace rosa { +namespace agent { + +template class CrossReliability : public Functionality { + using PartialFunction = typename rosa::agent::PartialFunction; + + struct Functionblock { + bool exists = false; + id_t A; + id_t B; + PartialFunction *Funct; + }; + + Type crossReliabilityParameter = 1; + + std::vector Functions; + Type (*Method)(std::vector values) = AVERAGE; + + //-------------------------------------------------------------------------------- + // helper functions + /// evalues the absolute distance between two values + Type AbsuluteValue(Type A, Type B) { return ((A - B) < 0) ? B - A : A - B; } + + + /// verry inefficient searchFunction + Functionblock (*searchFunction)(std::vector vect, + const id_t nameA, + const id_t nameB) = + [](std::vector vect, const id_t nameA, + const id_t nameB) -> Functionblock { + for (Functionblock tmp : vect) { + if (tmp.A == nameA && tmp.B == nameB) + return tmp; + if (tmp.A == nameB && tmp.B == nameA) + return tmp; + } + return Functionblock(); + }; + + /// evaluest the corisponding LinearFunction thith the score difference + /// \param nameA + /// \param nameB these two parameters are the unique identifiers + /// for the LinerFunction \note it doesn't matter if they are swapped + Type getCrossReliabilityFromProfile(id_t nameA, id_t nameB, + Type scoreDifference) { + Functionblock block = searchFunction(Functions, nameA, nameB); + if (!block.exists) + throw "does not exist"; // exceptions are disabled in rosa Todo : handle + // this right + return block.Funct->operator()(scoreDifference); + } + +public: + void addCrossReliabilityProfile(id_t idA, id_t idB, + PartialFunction *Function) { + Functions.push_back({true, idA, idB, Function}); + } + + void setCrossReliabilityParameter(Type val) { + crossReliabilityParameter = val; + } + + void setCrossReliabilityMethod(Type (*Meth)(std::vector values)) { + Method = Meth; + } + + ~CrossReliability() { + for (auto tmp : Functions) + delete tmp.Funct; + } + + /// Calculets the CrossReliability + /// \note both Main and Slaveagents are represented by there data and an + /// unique identifier + /// + /// \param MainAgent defines the value pair around which the Cross Reliability + /// is calculated + /// \param SlaveAgents defines all value pairs of the connected Agents + Type operator()(std::pair &MainAgent, + std::vector> &SlaveAgents); + + /// predefined combination method + static Type CONJUNCTION(std::vector values) { + static_assert(std::is_arithmetic::value); // sanitny check + return *std::min_element(values.begin(), values.end()); + } + + /// predefined combination method + static Type AVERAGE(std::vector values) { + static_assert(std::is_arithmetic::value); // sanitny check + return std::accumulate(values.begin(), values.end(), 0.0) / values.size(); + } + + /// predefined combination method + static Type DISJUNCTION(std::vector values) { + static_assert(std::is_arithmetic::value); // sanitny check + return *std::max_element(values.begin(), values.end()); + } +}; + +template +inline Type CrossReliability:: +operator()(std::pair &MainAgent, + std::vector> &SlaveAgents) { + static_assert(std::is_arithmetic::value); // sanitny check + + Type crossReliabiability; + std::vector values; + + for (std::pair SlaveAgent : SlaveAgents) { + + if (SlaveAgent.first == MainAgent.first) + continue; + + if (MainAgent.second == SlaveAgent.second) + crossReliabiability = 1; + else + crossReliabiability = + 1 / (crossReliabilityParameter * + AbsuluteValue(MainAgent.second, SlaveAgent.second)); + + // profile reliability + Type crossReliabilityFromProfile = getCrossReliabilityFromProfile( + MainAgent.first, SlaveAgent.first, + AbsuluteValue(MainAgent.second, SlaveAgent.second)); + values.push_back( + std::max(crossReliabiability, crossReliabilityFromProfile)); + } + return Method(values); +} + +template class CrossConfidence : public Functionality { + using PartialFunction = typename rosa::agent::PartialFunction; + + struct Functionblock { + bool exists = false; + id_t A; + id_t B; + PartialFunction *Funct; + }; + + Type crossReliabilityParameter = 1; + + std::vector Functions; + Type (*Method)(std::vector values) = AVERAGE; + + //-------------------------------------------------------------------------------- + // helper functions + /// evalues the absolute distance between two values + Type AbsuluteValue(Type A, Type B) { return ((A - B) < 0) ? B - A : A - B; } + + /// verry inefficient searchFunction + Functionblock (*searchFunction)(std::vector vect, + const id_t nameA, const id_t nameB) = + [](std::vector vect, const id_t nameA, + const id_t nameB) -> Functionblock { + for (Functionblock tmp : vect) { + if (tmp.A == nameA && tmp.B == nameB) + return tmp; + if (tmp.A == nameB && tmp.B == nameA) + return tmp; + } + return Functionblock(); + }; + + /// evaluest the corisponding LinearFunction thith the score difference + /// \param nameA + /// \param nameB these two parameters are the unique identifiers + /// for the LinerFunction \note it doesn't matter if they are swapped + Type getCrossReliabilityFromProfile(id_t nameA, id_t nameB, + Type scoreDifference) { + Functionblock block = searchFunction(Functions, nameA, nameB); + if (!block.exists) + throw "does not exist"; // exceptions are disabled in rosa Todo : handle + // this right + return block.Funct->operator()(scoreDifference); + } + +public: + void addCrossReliabilityProfile(id_t idA, id_t idB, + PartialFunction *Function) { + Functions.push_back({true, idA, idB, Function}); + } + + void setCrossReliabilityParameter(Type val) { + crossReliabilityParameter = val; + } + + void setCrossReliabilityMethod(Type (*Meth)(std::vector values)) { + Method = Meth; + } + + ~CrossReliabilityModule() { + for (auto tmp : Functions) + delete tmp.Funct; + } + + Type operator()(id_t MainAgent, Type TheoreticalValue, + std::vector> &SlaveAgents); + + /// predefined combination method + static Type CONJUNCTION(std::vector values) { + static_assert(std::is_arithmetic::value); // sanitny check + return *std::min_element(values.begin(), values.end()); + } + + /// predefined combination method + static Type AVERAGE(std::vector values) { + static_assert(std::is_arithmetic::value); // sanitny check + return std::accumulate(values.begin(), values.end(), 0.0) / values.size(); + } + + /// predefined combination method + static Type DISJUNCTION(std::vector values) { + static_assert(std::is_arithmetic::value); // sanitny check + return *std::max_element(values.begin(), values.end()); + } +}; + +template +inline Type CrossConfidence:: +operator()(id_t MainAgent, Type TheoreticalValue, + std::vector> &SlaveAgents) { + Type crossReliabiability; + + std::vector values; + + for (std::pair SlaveAgent : SlaveAgents) { + + if (SlaveAgent.first == MainAgent) + continue; + + if (TheoreticalValue == SlaveAgent.second) + crossReliabiability = 1; + else + crossReliabiability = + 1 / (crossReliabilityParameter * + AbsuluteValue(TheoreticalValue, SlaveAgent.second)); + + // profile reliability + Type crossReliabilityFromProfile = getCrossReliabilityFromProfile( + MainAgent, SlaveAgent.first, + AbsuluteValue(TheoreticalValue, SlaveAgent.second)); + values.push_back( + std::max(crossReliabiability, crossReliabilityFromProfile)); + } + return Method(values); +} + +} // End namespace agent +} // End namespace rosa + +#endif // ROSA_AGENT_CROSSRELIABILITY_H \ No newline at end of file diff --git a/include/rosa/deluxe/CrossReliability.h b/include/rosa/deluxe/CrossReliability.h deleted file mode 100644 index 396e3c4..0000000 --- a/include/rosa/deluxe/CrossReliability.h +++ /dev/null @@ -1,240 +0,0 @@ -#pragma once -//===-- rosa/delux/CrossReliability.h ---------------------------*- C++ -*-===// -// -// The RoSA Framework -// -//===----------------------------------------------------------------------===// -/// -/// \file rosa/delux/CrossReliability.h -/// -/// \author Daniel Schnoell -/// -/// \date 2019 -/// -/// \brief This file is temporarly for the functions/methods CrossConfidence and -/// CrossReliability. -/// \todo As soon as a Delux Reliabl Agent exist modify to this or add it to the -/// Agent. -/// \todo there is 1 exception that needs to be handled correctly. -/// \note the default search function is extremely slow maby this could be done -/// via template for storage class and the functions/methods to efficiently find -/// the correct LinearFunction -//===----------------------------------------------------------------------===// - -// nedded headers - -#include //assert -#include -// for static methods -#include -#include -#include - -// LinearFunction -#include "rosa/agent/LinearFunctions.hpp" - -#include "CrossReliability_helper_file.h" - -template class CrossReliabilityModule { - - using LinearFunction = typename rosa::agent::LinearFunction; - using ReliableAgent = typename ReliableAgent; - - struct Functionblock { - bool exists = false; - std::string nameA; - std::string nameB; - LinearFunction *Funct; - }; - -public: - /// adds a Function to the module - /// \param nameA - /// \param nameB these parameters have to be unique - /// \param Function should be uniquely owned by the Module and will be deleted - /// upon Deletion of the object - void addCrossReliabilityProfile(std::string nameA, std::string nameB, - LinearFunction *Function); - /// sets the cross Reliability Parameter - void setcrossReliabilityParameter(Type val) { - crossReliabilityParameter = val; - } - - /// Deconstructor deletes all stored LinearFunctions ! - ~CrossReliabilityModule() { - for (auto tmp : Functions) - delete tmp.Funct; - } - -protected: - //-------------------------------------------------------------------------------- - // Relevvant methods - - /// Calculets the CrossReliability - /// \param mainagent pointer of the relevant SlaveAgent - /// \param SlaveAgents pointers to all Slave Agents of the - /// \note all the given Agents need to have at least 1 possibleScore - /// \param Method a function pointer to the used combination method - /// \note im currently using getScore(0) this isn't correct maxi uses - /// getPossibleScoreCount() which returns possibleScoreCount. - /// possibleScoreCount isn't reset/set/inc inside or outside the use of this - /// function - Type CrossReliability(ReliableAgent *MainAgent, - std::vector SlaveAgents, - Type Method(std::vector values)); - - /// Calculets the CrossReliability - /// \param mainagent pointer of the relevant SlaveAgent - /// \param SlaveAgents pointers to all Slave Agents of the - /// \note all the given Agents need to have at least 1 possibleScore - /// \param Method a function pointer to the used combination method - /// \param TheoreticalValue uses this value instead of the MainAgents score - /// needed for playing "what if" - Type CrossConfidence(ReliableAgent *mainAgent, - std::vector SlaveAgents, - Type Method(std::vector values), - Type TheoreticalValue); - - //-------------------------------------------------------------------------------- - // helper functions - /// evalues the absolute distance between two values - Type AbsuluteValue(Type A, Type B) { return ((A - B) < 0) ? B - A : A - B; } - - /// evaluest the corisponding LinearFunction thith the score difference - /// \param nameA - /// \param nameB these two parameters are the unique identifiers - /// for the LinerFunction \note it doesn't matter if they are swapped - Type getCrossReliabilityFromProfile(std::string nameA, std::string nameB, - Type scoreDifference) { - Functionblock block = searchFunction(Functions, nameA, nameB); - if (!block.exists) - throw "does not exist"; // exceptions are disabled in rosa Todo : handle - // this right - return block.Funct->operator()(scoreDifference); - } - - //-------------------------------------------------------------------------------- - // stored Data - - Type crossReliabilityParameter = 1; - - /// this could be changed to use a template - /// template class - /// CrossReliabilityModule [...] - /// storagecontainer Functions; - std::vector Functions; - - /// verry inefficient searchFunction - Functionblock (*searchFunction)(std::vector vect, - const std::string nameA, - const std::string nameB) = - [](std::vector vect, const std::string nameA, - const std::string nameB) -> Functionblock { - for (Functionblock tmp : vect) { - if (tmp.nameA == nameA && tmp.nameB == nameB) - return tmp; - if (tmp.nameA == nameB && tmp.nameB == nameA) - return tmp; - } - return Functionblock(); - }; - - //-------------------------------------------------------------------------------- - // pre defined combination methods -public: - /// predefined combination method - static Type CONJUNCTION(std::vector values) { - static_assert(std::is_arithmetic::value); // sanitny check - return *std::min_element(values.begin(), values.end()); - } - - /// predefined combination method - static Type AVERAGE(std::vector values) { - static_assert(std::is_arithmetic::value); // sanitny check - return std::accumulate(values.begin(), values.end(), 0.0) / values.size(); - } - - /// predefined combination method - static Type DISJUNCTION(std::vector values) { - static_assert(std::is_arithmetic::value); // sanitny check - return *std::max_element(values.begin(), values.end()); - } - //------------------------------------------------------------------------------- -}; - -template -inline void CrossReliabilityModule::addCrossReliabilityProfile( - std::string nameA, std::string nameB, LinearFunction *Function) { - Functions.push_back({true, nameA, nameB, Function}); -} - -/* -The following things are needed inside this method -- getScore -- ReliableAgent -*/ -template -inline Type CrossReliabilityModule::CrossReliability( - ReliableAgent *mainAgent, std::vector SlaveAgents, - Type Method(std::vector values)) { - static_assert(std::is_arithmetic::value); // sanitny check - - Type crossReliabiability; - std::vector values; - - for (ReliableAgent *SlaveAgent : SlaveAgents) { - - if (SlaveAgent == mainAgent) - continue; - - if (mainAgent->getScore(0) == SlaveAgent->getScore(0)) - crossReliabiability = 1; - else - crossReliabiability = - 1 / (crossReliabilityParameter * - AbsuluteValue(mainAgent->getScore(0), SlaveAgent->getScore(0))); - - // profile reliability - Type crossReliabilityFromProfile = getCrossReliabilityFromProfile( - mainAgent->getName(), SlaveAgent->getName(), - AbsuluteValue(mainAgent->getScore(0), SlaveAgent->getScore(0))); - values.push_back( - std::max(crossReliabiability, crossReliabilityFromProfile)); - } - return Method(values); -} - -/* -The following things are needed inside this method -- getScore -- ReliableAgent -*/ -template -inline Type CrossReliabilityModule::CrossConfidence( - ReliableAgent *mainAgent, std::vector SlaveAgents, - Type Method(std::vector values), Type TheoreticalValue) { - Type crossReliabiability; - - std::vector values; - - for (ReliableAgent *SlaveAgent : SlaveAgents) { - - if (SlaveAgent == mainAgent) - continue; - - if (TheoreticalValue == SlaveAgent->getScore(0)) - crossReliabiability = 1; - else - crossReliabiability = - 1 / (crossReliabilityParameter * - AbsuluteValue(TheoreticalValue, SlaveAgent->getScore(0))); - - // profile reliability - Type crossReliabilityFromProfile = getCrossReliabilityFromProfile( - mainAgent->getName(), SlaveAgent->getName(), - AbsuluteValue(mainAgent->getScore(0), SlaveAgent->getScore(0))); - values.push_back( - std::max(crossReliabiability, crossReliabilityFromProfile)); - } - return Method(values); -} diff --git a/include/rosa/deluxe/CrossReliability_helper_file.h b/include/rosa/deluxe/CrossReliability_helper_file.h deleted file mode 100644 index 66bf5bd..0000000 --- a/include/rosa/deluxe/CrossReliability_helper_file.h +++ /dev/null @@ -1,152 +0,0 @@ -#pragma once -//===-- rosa/delux/CrossReliability_helper_file.h ----------------*- C++ -//-*-===// -// -// The RoSA Framework -// -//===----------------------------------------------------------------------===// -/// -/// \file rosa/delux/CrossReliability_helper_file.h -/// -/// \author Daniel Schnoell -/// -/// \date 2019 -/// -/// \brief This file shouldn't exist when everything is finished. It is only a -/// temporary part to hava all needed references and it also contains source -/// code for test compiling -//===----------------------------------------------------------------------===// - -#ifdef __fake__LinearFunction -namespace rosa { -namespace agent { -template class LinearFunction { -public: - virtual A operator()(B val) = 0; -}; -template -class testFunction : public LinearFunction { -public: - virtual A operator()(B val) { return val; } -}; -} // namespace agent -} // namespace rosa -#endif - -template class ReliableAgent { - //------------------------------------------------------------------------------ - // Reliability or Confidence -public: - // at=0 should be the most reliable score - Type getReliability(std::size_t at) { return PossibleScores.at(at)->second; } - void setReliability(std::size_t at, Type Reliability) { - this->Reliability = PossibleScores.at(at)->second; - } - - Type getScore(std::size_t at) { return PossibleScores.at(at)->first; } - void setScore(std::size_t at, Type Score) { - this->Reliability = PossibleScores.at(at)->first; - } - - void createPossibleScore(Type Score, Type Reliability) { - PossibleScores.push_back(new std::pair(Score, Reliability)); - } - std::size_t getNumberOfPossibleScores() { return PossibleScores.size(); } - void setName(std::string nam) { Name = nam; } - std::string getName() { return Name; } - -protected: - Type crossReliabilityParameter = 1; - -private: - std::string Name; - std::vector *> - PossibleScores; // first: Score second: Reliability or Confidence - //-------------------------------------------------------------------------------- - // ReliableAgent -public: - std::vector Slaves; - ReliableAgent *Master; - -private: -}; - -/* -//test file include correct path - -#define __fake__LinearFunction -#include "CrossReliability.h" -#include - -class tester :public ReliableAgent, public -CrossReliabilityModule -{ -public: - // pure testmethod - void makeReliability( - double Method(std::vector values)) { - std::cout << "score" - << "\tCR\t"; - for (std::size_t tmp = 0; tmp < 10; tmp++) - std::cout << "\t" << ((double)tmp) / 10; - std::cout << "\n"; - for ( auto mainagent : Slaves) { - std::cout << mainagent->getScore(0) << "\t" // carefull -not fale save - << CrossReliability(mainagent, Slaves, Method) -<< "\t"; for (std::size_t tmp = 0; tmp < 10; tmp++) std::cout << "\t" - << CrossConfidence(mainagent, Slaves, Method, -((double)tmp) / 10); std::cout << "\n"; - } - } - - -}; - -int main(void) -{ - std::vector Slaves; - std::size_t size = 20; - for (std::size_t a = 0; a < size; a++) - { - auto tmp = new tester(); - tmp->createPossibleScore(((double)a) / size, - ((double)a) / size); - tmp->setName(std::to_string(a)); - Slaves.push_back(tmp); - } - - tester Master; - Master.Slaves.insert(Master.Slaves.begin(), Slaves.begin(), - Slaves.end()); - - for (std::size_t a = 0; a < size; a++) - { - for (std::size_t b = 0; b < size; b++) - { - Master.addCrossReliabilityProfile(std::to_string(a), -std::to_string(b),new rosa::agent::testFunction()); - } - } - - Master.makeReliability(tester::AVERAGE); - - - - - - //cleanup - for (auto tmp : Slaves) - delete tmp; - Slaves.clear(); - Master.Slaves.clear(); - - Master.~Master(); - - long q; - std::cin >> q; - - return 0; -} - -*/ \ No newline at end of file diff --git a/lib/agent/CMakeLists.txt b/lib/agent/CMakeLists.txt index 3d6e5ab..38b5f83 100644 --- a/lib/agent/CMakeLists.txt +++ b/lib/agent/CMakeLists.txt @@ -1,16 +1,18 @@ set(LIB_INCLUDE_DIR ${ROSA_MAIN_INCLUDE_DIR}/rosa/agent) add_library(ROSAAgent ${LIB_INCLUDE_DIR}/namespace.h namespace.cpp ${LIB_INCLUDE_DIR}/Functionality.h Functionality.cpp ${LIB_INCLUDE_DIR}/Abstraction.hpp Abstraction.cpp ${LIB_INCLUDE_DIR}/LinearFunctions.hpp LinearFunctions.cpp ${LIB_INCLUDE_DIR}/History.hpp History.cpp ${LIB_INCLUDE_DIR}/Confidence.hpp Confidence.cpp + ${LIB_INCLUDE_DIR}/CrossReliability.h + CrossReliability.cpp ) diff --git a/lib/agent/CrossReliability.cpp b/lib/agent/CrossReliability.cpp new file mode 100644 index 0000000..21ed3b4 --- /dev/null +++ b/lib/agent/CrossReliability.cpp @@ -0,0 +1,20 @@ +//===-- agent/CrossReliability.cpp ------------------------------*- C++ -*-===// +// +// The RoSA Framework +// +//===----------------------------------------------------------------------===// +/// +/// \file agent/CrossReliability.cpp +/// +/// \author Daniel Schnoell (daniel.schnoell@tuwien.ac.at) +/// +/// \date 2019 +/// +/// \brief Implementation for rosa/agent/CrossReliability.cpp +/// +/// \note Empty implementation, source file here to have a compile database +/// entry for rosa/agent/CrossReliability.h +/// +//===----------------------------------------------------------------------===// + +#include "rosa/agent/CrossReliability.h"