diff --git a/include/rosa/agent/Reliability.h b/include/rosa/agent/Reliability.h index 06c0354..0d6bb22 100644 --- a/include/rosa/agent/Reliability.h +++ b/include/rosa/agent/Reliability.h @@ -1,489 +1,489 @@ //===-- rosa/agent/Reliability.h --------------------------------*- C++ -*-===// // // The RoSA Framework // //===----------------------------------------------------------------------===// /// /// \file rosa/agent/Reliability.h /// /// \author Daniel Schnoell (danielschnoell@tuwien.ac.at) /// /// \date 2019 /// /// \brief Definition of *reliability* *functionality*. /// /// \note All classes throw runtime errors if not all things are set /// //===----------------------------------------------------------------------===// #ifndef ROSA_AGENT_RELIABILITY_H #define ROSA_AGENT_RELIABILITY_H #include "rosa/agent/FunctionAbstractions.hpp" #include "rosa/agent/Functionality.h" #include "rosa/agent/RangeConfidence.hpp" #include "rosa/agent/CrossReliability.h" #include #include #include /// 0 everything /// 1 vectors /// 2 outputs #define trace_everything 0 #define trace_vectors 1 #define trace_outputs 2 #ifndef Reliability_trace_level #define Reliability_trace_level 0 #endif #define trace_end "\n\n\n" namespace rosa { namespace agent { /// This is a struct with a few methods that make lowlevel Reliability more readable /// \tparam StateType The datatype of the States /// \tparam ReliabilityType The datatype of the Reliability template< typename StateType,typename ReliabilityType> struct ConfOrRel { typedef StateType _StateType; typedef ReliabilityType _ReliabilityType; StateType score; ReliabilityType Reliability; ConfOrRel(StateType _score, ReliabilityType _Reliability) :score(_score), Reliability(_Reliability) {}; ConfOrRel() {}; /// Pushes the Data in a Human readable form /// \param out The stream where it is written to /// \param c The struct itself friend std::ostream& operator << (std::ostream& out, const ConfOrRel& c) { out << "Score: " << c.score << "\t Reliability: " << c.Reliability << " "; return out; } typedef std::map map; // needed or it throws an clang diagnosic erroor /// Filles the vector with the data inside the map /// \param me The vector to be filled /// \param data The data wich is to be pushed into the vector friend std::vector& operator<<(std::vector &me, map&& data) { for (auto tmp : data) { me.push_back(ConfOrRel(tmp.first, tmp.second)); #if Reliability_trace_level<=trace_everything LOG_TRACE_STREAM << "\n" << ConfOrRel(tmp.first, tmp.second) << trace_end; #endif } return me; } /// This adds the Reliabilities of the same Scores /// \param me The vector to wich is written to /// \param other The other data vector friend std::vector operator+=(std::vector &me, std::vector other) { static_assert(std::is_arithmetic::value); for (auto tmp_me:me) for (auto tmp_other:other) { if (tmp_me.score == tmp_other.score) { tmp_me.Reliability =tmp_me.Reliability + tmp_other.Reliability; } } return me; } /// This is to push the data inside a vector in a humanreadable way into the ostream /// \param out The ostream /// \param c The vector which is read friend std::ostream& operator << (std::ostream& out, const std::vector& c) { std::size_t index=0; for(ConfOrRel data:c) { out << index << " : " << data << "\n"; index++; } return out; } }; /// This calculates the minimum of the Reliabilities & the given value /// \param me The vector with the Reliabilites /// \param value The comparing value template std::vector min(std::vector me,typename Conf::_ReliabilityType value ) { static_assert(std::is_arithmetic::value); for (auto tmp:me) tmp.Reliability = std::min(tmp.Reliability,value); return me; } /// This is the Reliability Functionality for a low level Agent /// \tparam SensorValueType Datatype of the Sensor value ( Typically double or float) /// \tparam StateType Datatype of the State ( Typically long or int) /// \tparam ReliabilityType Datatype of the Reliability ( Typically double or float) /// /// use the () operator to get the reliability and feed the information from the master back to this /// \note all pointer for the functionalities will be deleted when this is object ist destroyed template class LowLevel { public: typedef ConfOrRel ConfOrRel; /// Calculates the Conf/ Reliability /// \param SensorValue The current Values of the Sensor /// /// \return Reliability of the current Value ConfOrRel operator()(SensorValueType SensorValue) { #if Reliability_trace_level<=trace_outputs LOG_TRACE_STREAM << "\nTrace level is set to: " << Reliability_trace_level <<"\n" << "Will trace: " << ((Reliability_trace_level==trace_outputs)? "outputs" : (Reliability_trace_level==trace_vectors)? "vectors" : (Reliability_trace_level==trace_everything)? "everything" : "undefined" ) < ActuallPossibleScores; std::vector possibleScores; ReliabilityType inputReliability =getRelibility(SensorValue, previousSensorValue, valueSetCounter); #if Reliability_trace_level<=trace_vectors LOG_TRACE_STREAM << "\ninput Rel: " << inputReliability << trace_end; #endif - ActuallPossibleScores << Confidence->operator()(SensorValue); + possibleScores << Confidence->operator()(SensorValue); - ActuallPossibleScores = min(ActuallPossibleScores,inputReliability); + possibleScores = min(possibleScores,inputReliability); - ActuallPossibleScores += ValuesFromMaster; - - saveInHistory(ActuallPossibleScores); + possibleScores += ValuesFromMaster; + saveInHistory(possibleScores); +#if Reliability_trace_level<=trace_vectors + LOG_TRACE_STREAM << "\nActuallPossibleScores:\n" << possibleScores << trace_end; + LOG_TRACE_STREAM << "\npossibleScores:\n" << possibleScores << trace_end; +#endif + possibleScores.clear(); - possibleScores = getAllPossibleScoresBasedOnHistory(possibleScores); + possibleScores = getAllPossibleScoresBasedOnHistory(); std::sort(possibleScores.begin(), possibleScores.end(), [](ConfOrRel A, ConfOrRel B)-> bool { static_assert(std::is_arithmetic::value); return A.Reliability > B.Reliability; } ); previousSensorValue = SensorValue; PreviousSensorValueExists = true; -#if Reliability_trace_level<=trace_vectors - LOG_TRACE_STREAM << "\nActuallPossibleScores:\n" << ActuallPossibleScores << trace_end; - LOG_TRACE_STREAM << "\npossibleScores:\n" << possibleScores << trace_end; -#endif #if Reliability_trace_level<=trace_outputs LOG_TRACE_STREAM << "\noutput lowlevel: " << possibleScores.at(0) << trace_end; #endif return possibleScores.at(0); } /// Needed feedback from the Master /// \param ValuesFromMaster The Scores + Reliability from the Master for this Agent void feedback(std::vector ValuesFromMaster) { this->ValuesFromMaster = ValuesFromMaster; } /// This is the setter for Confidence Function /// \param Confidence A pointer to the Functional for the Confidence void setConfidenceFunction(std::unique_ptr> &Confidence) { this->Confidence = std::move(Confidence); } /// This is the setter for Reliability Function /// \param Reliability A pointer to the Functional for the Reliability void setReliabilityFunction(std::unique_ptr> &Reliability) { this->Reliability = std::move(Reliability); } /// This is the setter for ReliabilitySlope Function /// \param ReliabilitySlope A pointer to the Functional for the ReliabilitySlope void setReliabilitySlopeFunction(std::unique_ptr> &ReliabilitySlope) { this->ReliabilitySlope = std::move(ReliabilitySlope); } /// This is the setter for TimeConfidence Function /// \param TimeConfidence A pointer to the Functional for the TimeConfidence void setTimeConfidenceFunction(std::unique_ptr> &TimeConfidence) { this->TimeConfidence = std::move(TimeConfidence); } /// This is the setter for all possible States /// \param states A vertor for all states void setStates(std::vector states) { this->States=states; } /// This sets the Maximum length of the Histpry /// \param length The length void setHistoryLength(std::size_t length) { this->HistoryMaxSize=length; } /// This sets the Value set Counter /// \param ValueSetCounter the new Value void setValueSetCounter(unsigned int ValueSetCounter) { this->valueSetCounter=ValueSetCounter; } private: std::vector> History; std::size_t HistoryMaxSize; std::vector ValuesFromMaster; SensorValueType previousSensorValue; unsigned int valueSetCounter; std::vector States; bool PreviousSensorValueExists = false; std::unique_ptr> Confidence; std::unique_ptr> Reliability; std::unique_ptr> ReliabilitySlope; std::unique_ptr> TimeConfidence; /*--------------------------------- needed Funktions -----------------------------------------------------*/ /// returns the Reliability /// \param actualValue The Value of the Sensor /// \param lastValue of the Sensor this is stored in the class /// \param valueSetCounter It has an effect on the difference of the current and last value This might not be needed anymore ReliabilityType getRelibility(SensorValueType actualValue, SensorValueType lastValue, unsigned int valueSetCounter) { static_assert(std::is_arithmetic::value); ReliabilityType relAbs = Reliability->operator()(actualValue); if (PreviousSensorValueExists) { ReliabilityType relSlo = ReliabilitySlope->operator()((lastValue - actualValue) / (SensorValueType)valueSetCounter); // calculate signal input reliability // NOTE: options would be multiply, average, AND (best to worst: // average = AND > multiply) rel = relAbs * relSlo; rel = (relAbs + // relSlo)/2; return std::min(relAbs, relSlo); } else return relAbs; } /// adabts the possible Scores by checking the History and combines those values currently with max - /// \param possibleScores This is returned from the Master - std::vector getAllPossibleScoresBasedOnHistory(std::vector possibleScores) + std::vector getAllPossibleScoresBasedOnHistory() { //iterate through all history entries std::size_t posInHistory = 0; + std::vector possibleScores; for (auto pShE = History.begin(); pShE < History.end(); pShE++, posInHistory++) { //iterate through all possible scores of each history entry for (ConfOrRel& pSh : *pShE) { StateType historyScore = pSh.score; ReliabilityType historyConf = pSh.Reliability; //combine each history score with the confidence of time //NOTE: multiplication, AND, or average would be alternatives (best to worst: multiplication = AND = average) historyConf = historyConf * TimeConfidence->operator()(posInHistory); //historyConf = (historyConf + TimeConfidence(posInHistory)) / 2; //historyConf = std::min(historyConf, TimeConfidence(posInHistory)); bool foundScore = false; for (ConfOrRel& pS : possibleScores) { if (pS.score == historyScore) { //calculate confidence for score //NOTE: multiplication, AND, or average would be alternatives (best to worst: AND >> average = multiplication ) //pS->confOrRel = pS->confOrRel * historyConf; //pS->confOrRel = (pS->confOrRel + historyConf) / 2; pS.Reliability = std::max(pS.Reliability, historyConf); foundScore = true; } } if (foundScore == false) { ConfOrRel possibleScore; possibleScore.score = historyScore; possibleScore.Reliability = historyConf; possibleScores.push_back(possibleScore); } } } return possibleScores; } /// saves the Scores in the History /// \param actualPossibleScores The Scores which should be saved /// /// \note Does the History realy make sence if the values are to smal it only stores something if its empty and not if it isn't completly filled void saveInHistory(std::vector actualPossibleScores) { //check if the reliability of at least one possible score is high enough bool atLeastOneRelIsHigh = false; for (ConfOrRel pS : actualPossibleScores) { if (pS.Reliability > 0.5) { atLeastOneRelIsHigh = true; } } //save possible scores if at least one possible score is high enough (or if the history is empty) if (History.size() < 1 || atLeastOneRelIsHigh == true) { History.insert(History.begin(),actualPossibleScores); //if history size is higher than allowed, savo oldest element while (History.size() > HistoryMaxSize) { //delete possibleScoreHistory.back(); History.pop_back(); } } } }; /// This is the Reliability Functionality for the Highlevel Agent /// \tparam StateType Datatype of the State ( Typically double or float) /// \tparam ReliabilityType Datatype of the Reliability ( Typically long or int) /// /// use the () operator to calculate the Reliability and all cross confidences for all slaves /// \note all pointer to Funcionalities get deleted upon deletion of the object template class HighLevel { public: typedef ConfOrRel ConfOrRel; struct returnType { ReliabilityType CrossReliability; std::map> CrossConfidence; }; returnType operator()(std::vector> &Values) { StateType EWS = 0; ReliabilityType combinedInputRel = 1; ReliabilityType combinedCrossRel = 1; ReliabilityType outputReliability; std::vector> Agents; std::map> output; std::vector output_temporary; for (auto tmp : Values) { std::pair tmp2; tmp2.first = std::get<0>(tmp); tmp2.second = std::get<1>(tmp); Agents.push_back(tmp2); } for (auto Value : Values) { id_t id = std::get<0>(Value); StateType sc = std::get<1>(Value); ReliabilityType rel = std::get<2>(Value); EWS = EWS + sc; combinedInputRel = std::min(combinedInputRel, rel); //calculate the cross reliability for this slave agent ReliabilityType realCrossReliabilityOfSlaveAgent = CrossReliability->operator()({id,sc }, Agents); //AVERAGE, MULTIPLICATION, CONJUNCTION (best to worst: AVERAGE = CONJUNCTION > MULTIPLICATION >> ) output_temporary.clear(); for (StateType thoScore:States[id]) { //calculate the cross reliability for this slave agent ConfOrRel data; data.score = thoScore; data.Reliability = CrossConfidence->operator()(id, thoScore, Agents); output_temporary.push_back(data); } output.insert({ std::get<0>(Value),output_temporary }); combinedCrossRel = std::min(combinedCrossRel, realCrossReliabilityOfSlaveAgent); } //combine cross reliabilites and input reliabilites of all slave agents //NOTE: options would be multiply, average, AND (best to worst: ) //outputReliability = combinedInputRel * combinedCrossRel; //outputReliability = (combinedInputRel + combinedCrossRel) / 2; outputReliability = std::min(combinedInputRel, combinedCrossRel); return { outputReliability,output }; } /// This is the setter for CrossReliability Function /// \param CrossReliability A pointer to the Functional for the CrossReliability void setFunction(std::unique_ptr> &CrossReliability) { this->CrossReliability = std::move(CrossReliability); } /// This is the setter for CrossConfidence Function /// \param CrossConfidence A pointer to the Functional for the CrossConfidence void setFunction(std::unique_ptr> &CrossConfidence) { this->CrossConfidence = std::move(CrossConfidence); } /// This the adder for the states /// \param States id spezific states this will be copied void addStates( id_t id, std::vector States) { this->States.insert({id,States}); } private: std::unique_ptr> CrossReliability; std::unique_ptr> CrossConfidence ; std::map> States; }; } // namespace agent }// namespace rosa #endif // !ROSA_AGENT_RELIABILITY_H