Page MenuHomePhorge

Reliability.h
No OneTemporary

Size
16 KB
Referenced Files
None
Subscribers
None

Reliability.h

//===-- 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 <vector>
#include <algorithm>
#include <type_traits>
/// 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<StateType,ReliabilityType> 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<ConfOrRel>& operator<<(std::vector<ConfOrRel> &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<ConfOrRel> operator+=(std::vector<ConfOrRel> &me, std::vector<ConfOrRel> other)
{
static_assert(std::is_arithmetic<ReliabilityType>::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<ConfOrRel>& 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<typename Conf>
std::vector<Conf> min(std::vector<Conf> me,typename Conf::_ReliabilityType value )
{
static_assert(std::is_arithmetic<typename Conf::_ReliabilityType>::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 <typename SensorValueType, typename StateType, typename ReliabilityType>
class LowLevel {
public:
typedef ConfOrRel<StateType,ReliabilityType> 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"
)
<<trace_end;
#endif
std::vector<ConfOrRel> ActuallPossibleScores;
std::vector<ConfOrRel> possibleScores;
ReliabilityType inputReliability =getRelibility(SensorValue, previousSensorValue, valueSetCounter);
#if Reliability_trace_level<=trace_vectors
LOG_TRACE_STREAM << "\ninput Rel: " << inputReliability << trace_end;
#endif
possibleScores << Confidence->operator()(SensorValue);
possibleScores = min(possibleScores,inputReliability);
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();
std::sort(possibleScores.begin(), possibleScores.end(),
[](ConfOrRel A, ConfOrRel B)-> bool {
static_assert(std::is_arithmetic<ReliabilityType>::value);
return A.Reliability > B.Reliability; }
);
previousSensorValue = SensorValue;
PreviousSensorValueExists = true;
#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<ConfOrRel> 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<RangeConfidence<ReliabilityType, StateType, SensorValueType>> &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<Abstraction<SensorValueType, ReliabilityType>> &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<Abstraction<SensorValueType, ReliabilityType>> &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<Abstraction<std::size_t, ReliabilityType>> &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<StateType> 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<std::vector<ConfOrRel>> History;
std::size_t HistoryMaxSize;
std::vector<ConfOrRel> ValuesFromMaster;
SensorValueType previousSensorValue;
unsigned int valueSetCounter;
std::vector<StateType> States;
bool PreviousSensorValueExists = false;
std::unique_ptr<RangeConfidence<ReliabilityType, StateType, SensorValueType>> Confidence;
std::unique_ptr<Abstraction<SensorValueType, ReliabilityType>> Reliability;
std::unique_ptr<Abstraction<SensorValueType, ReliabilityType>> ReliabilitySlope;
std::unique_ptr<Abstraction<std::size_t, ReliabilityType>> 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<ReliabilityType>::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
std::vector<ConfOrRel> getAllPossibleScoresBasedOnHistory()
{
//iterate through all history entries
std::size_t posInHistory = 0;
std::vector<ConfOrRel> 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<ConfOrRel> 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<typename StateType, typename ReliabilityType>
class HighLevel
{
public:
typedef ConfOrRel<StateType,ReliabilityType> ConfOrRel;
struct returnType {
ReliabilityType CrossReliability;
std::map<id_t, std::vector<ConfOrRel>> CrossConfidence;
};
returnType operator()(std::vector<std::tuple<id_t, StateType, ReliabilityType>> &Values)
{
StateType EWS = 0;
ReliabilityType combinedInputRel = 1;
ReliabilityType combinedCrossRel = 1;
ReliabilityType outputReliability;
std::vector<std::pair<id_t, StateType>> Agents;
std::map<id_t, std::vector<ConfOrRel>> output;
std::vector<ConfOrRel> output_temporary;
for (auto tmp : Values)
{
std::pair<id_t, StateType> 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<StateType, ReliabilityType>> &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 <StateType, ReliabilityType>> &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<StateType> States)
{
this->States.insert({id,States});
}
private:
std::unique_ptr<CrossReliability<StateType, ReliabilityType>> CrossReliability;
std::unique_ptr<CrossConfidence <StateType, ReliabilityType>> CrossConfidence ;
std::map<id_t,std::vector<StateType>> States;
};
} // namespace agent
}// namespace rosa
#endif // !ROSA_AGENT_RELIABILITY_H

File Metadata

Mime Type
text/x-c++
Expires
Sat, Aug 29, 2:26 PM (1 d, 19 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
376494
Default Alt Text
Reliability.h (16 KB)

Event Timeline