Page MenuHomePhorge

No OneTemporary

Size
70 KB
Referenced Files
None
Subscribers
None
diff --git a/examples/agent-functionalities/Reliability-functionality/Reliability-functionality.cpp b/examples/agent-functionalities/Reliability-functionality/Reliability-functionality.cpp
index 9d6ddd3..cad229b 100644
--- a/examples/agent-functionalities/Reliability-functionality/Reliability-functionality.cpp
+++ b/examples/agent-functionalities/Reliability-functionality/Reliability-functionality.cpp
@@ -1,247 +1,247 @@
//===- examples/agent-functionalities/Reliability-functionality.cpp *C++-*-===//
//
// The RoSA Framework
//
//===----------------------------------------------------------------------===//
///
/// \file examples/agent-functionalities/Reliability-functionality.cpp
///
/// \author Daniel Schnoell (daniel.schnoell@tuwien.ac.at )
///
/// \date 2019
///
/// \brief A simple example on defining Relianility Functionalities.
///
//===----------------------------------------------------------------------===//
#define Reliability_trace_level 5
#include "rosa/config/version.h"
#include "rosa/support/log.h"
#include "rosa/agent/CrossCombinator.h"
#include "rosa/agent/RangeConfidence.hpp"
#include "rosa/agent/ReliabilityConfidenceCombinator.h"
#include <map>
#include <vector>
using namespace rosa::agent;
int main(void) {
typedef double SensorValueType;
typedef long StateType;
typedef double ReliabilityType;
std::unique_ptr<RangeConfidence<ReliabilityType, StateType, SensorValueType>>
Confidence(new RangeConfidence<ReliabilityType, StateType,
SensorValueType>(
{{0, PartialFunction<double, double>(
{
{{0, 3},
std::make_shared<LinearFunction<double, double>>(
0, 1.0 / 3)},
{{3, 6},
std::make_shared<LinearFunction<double, double>>(1, 0)},
{{6, 9},
std::make_shared<LinearFunction<double, double>>(
3.0, -1.0 / 3)},
},
0)},
{1, PartialFunction<double, double>(
{
{{6, 9},
std::make_shared<LinearFunction<double, double>>(
-2, 1.0 / 3)},
{{9, 12},
std::make_shared<LinearFunction<double, double>>(1, 0)},
{{12, 15},
std::make_shared<LinearFunction<double, double>>(
5, -1.0 / 3)},
},
0)},
{2, PartialFunction<double, double>(
{
{{12, 15},
std::make_shared<LinearFunction<double, double>>(
-4, 1.0 / 3)},
{{15, 18},
std::make_shared<LinearFunction<double, double>>(1, 0)},
{{18, 21},
std::make_shared<LinearFunction<double, double>>(
7, -1.0 / 3)},
},
0)}}));
std::unique_ptr<Abstraction<SensorValueType, ReliabilityType>> Reliability(
new LinearFunction<SensorValueType, ReliabilityType>(1, -1.0 / 3));
std::unique_ptr<Abstraction<SensorValueType, ReliabilityType>>
ReliabilitySlope(
new LinearFunction<SensorValueType, ReliabilityType>(1, -1.0 / 3));
std::unique_ptr<Abstraction<std::size_t, ReliabilityType>> TimeConfidence(
new LinearFunction<std::size_t, ReliabilityType>(1, -1.0 / 3));
auto lowlevel =
new ReliabilityAndConfidenceCombinator<SensorValueType, StateType,
ReliabilityType>();
std::vector<long> states;
states.push_back(0);
states.push_back(1);
states.push_back(2);
lowlevel->setConfidenceFunction(Confidence);
lowlevel->setReliabilityFunction(Reliability);
lowlevel->setReliabilitySlopeFunction(ReliabilitySlope);
lowlevel->setTimeConfidenceFunction(TimeConfidence);
lowlevel->setStates(states);
lowlevel->setHistoryLength(2);
lowlevel->setValueSetCounter(1);
/* ----------------------------- Do Something
* ---------------------------------------------------------------- */
std::cout << "Testing the lowlevel component with static feedback telling it "
"that the most lickely state is 2.\n";
for (int a = 0; a < 30; a++)
std::cout << "a: " << a << "\n"
<< (lowlevel->feedback({{0, 0}, {1, 0.3}, {2, 0.8}}),
lowlevel->getmostLikelyIdentifierAndReliability(a))
<< "\n";
std::cout << "---------------------------------------------------------------"
"---------------------------------\n";
std::cout << "------------------------------------High level "
"Test---------------------------------------------\n";
std::cout
<< "Configured in a way that the Master thinks that both Sensors "
"should have the same State.\n While feeding both the \"opposite\" "
"values one acending the other decending from the maximum.\n";
std::unique_ptr<RangeConfidence<ReliabilityType, StateType, SensorValueType>>
Confidence2(new RangeConfidence<ReliabilityType, StateType,
SensorValueType>(
{{0, PartialFunction<double, double>(
{
{{0, 3},
std::make_shared<LinearFunction<double, double>>(
0, 1.0 / 3)},
{{3, 6},
std::make_shared<LinearFunction<double, double>>(1, 0)},
{{6, 9},
std::make_shared<LinearFunction<double, double>>(
3.0, -1.0 / 3)},
},
0)},
{1, PartialFunction<double, double>(
{
{{6, 9},
std::make_shared<LinearFunction<double, double>>(
-2, 1.0 / 3)},
{{9, 12},
std::make_shared<LinearFunction<double, double>>(1, 0)},
{{12, 15},
std::make_shared<LinearFunction<double, double>>(
5, -1.0 / 3)},
},
0)},
{2, PartialFunction<double, double>(
{
{{12, 15},
std::make_shared<LinearFunction<double, double>>(
-4, 1.0 / 3)},
{{15, 18},
std::make_shared<LinearFunction<double, double>>(1, 0)},
{{18, 21},
std::make_shared<LinearFunction<double, double>>(
7, -1.0 / 3)},
},
0)}}));
std::unique_ptr<Abstraction<SensorValueType, ReliabilityType>> Reliability2(
new LinearFunction<SensorValueType, ReliabilityType>(1, -1.0 / 9));
std::unique_ptr<Abstraction<SensorValueType, ReliabilityType>>
ReliabilitySlope2(
new LinearFunction<SensorValueType, ReliabilityType>(1, -1.0 / 9));
std::unique_ptr<Abstraction<std::size_t, ReliabilityType>> TimeConfidence2(
new LinearFunction<std::size_t, ReliabilityType>(1, -1.0 / 9));
auto lowlevel2 =
new ReliabilityAndConfidenceCombinator<SensorValueType, StateType,
ReliabilityType>();
std::vector<long> states2;
states2.push_back(0);
states2.push_back(1);
states2.push_back(2);
lowlevel2->setConfidenceFunction(Confidence2);
lowlevel2->setReliabilityFunction(Reliability2);
lowlevel2->setReliabilitySlopeFunction(ReliabilitySlope2);
lowlevel2->setTimeConfidenceFunction(TimeConfidence2);
lowlevel2->setStates(states2);
lowlevel2->setHistoryLength(2);
lowlevel2->setValueSetCounter(1);
CrossCombinator<StateType, ReliabilityType> *highlevel =
new CrossCombinator<StateType, ReliabilityType>();
std::unique_ptr<Abstraction<long, double>> func1(new PartialFunction<long, double>(
{
{{0, 1}, std::make_shared<LinearFunction<long, double>>(1, 0)},
{{1, 2}, std::make_shared<LinearFunction<long, double>>(2, -1.0)},
},
0));
highlevel->addCrossReliabilityProfile(0, 1, func1);
highlevel->setCrossReliabilityCombinatorMethod(
- CrossCombinator<StateType, ReliabilityType>::AVERAGE);
+ CrossCombinator<StateType, ReliabilityType>::predefinedMethods::AVERAGE);
highlevel->setCrossReliabilityParameter(1);
- highlevel->addStates(0, states);
- highlevel->addStates(1, states);
+ highlevel->addIdentifiers(0, states);
+ highlevel->addIdentifiers(1, states);
for (int a = 0; a < 21; a++) {
auto out1 = lowlevel->getmostLikelyIdentifierAndReliability(a),
out2 = lowlevel2->getmostLikelyIdentifierAndReliability((int)21 - a);
std::cout << "s1: " << out1 << "\ns2:" << out2 << "\n";
std::vector<std::tuple<rosa::id_t, StateType, ReliabilityType>> tmp2;
tmp2.push_back({0, out1.Identifier, out1.Reliability});
tmp2.push_back({1, out2.Identifier, out2.Reliability});
auto out_o = highlevel->operator()(tmp2);
std::cout << "it: " << a << "\t rel: " << out_o.CrossReliability << "\n";
std::cout << "\t subs:\n";
for (auto q : out_o.CrossConfidence) {
std::cout << "\t\t id:" << q.first << "\n";
/*
for(auto z: q.second)
{
std::cout << "\t\t\t Identifier: " << z.Identifier << "\tRel: " << z.Reliability
<< "\n"; tmp.push_back({z.Identifier,z.Reliability});
}
*/
for (auto z : q.second) {
std::cout << "\t\t\t Identifier: " << z.Identifier << "\tRel: " << z.Reliability
<< "\n";
}
if (q.first == 0)
lowlevel->feedback(q.second);
else
lowlevel2->feedback(q.second);
}
}
/* ----------------------------- Cleanup
* --------------------------------------------------------------------- */
delete highlevel;
delete lowlevel;
delete lowlevel2;
}
\ No newline at end of file
diff --git a/include/rosa/agent/CrossCombinator.h b/include/rosa/agent/CrossCombinator.h
index 12596b7..7c005d7 100644
--- a/include/rosa/agent/CrossCombinator.h
+++ b/include/rosa/agent/CrossCombinator.h
@@ -1,538 +1,552 @@
//===-- rosa/delux/CrossReliability.h ---------------------------*- C++ -*-===//
//
// The RoSA Framework
//
//===----------------------------------------------------------------------===//
///
/// \file rosa/delux/CrossReliability.h
///
/// \author Daniel Schnoell
///
/// \date 2019
///
/// \brief
///
/// \todo there is 1 exception that needs to be handled correctly.
/// \note the default search function is extremely slow maybe 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/Abstraction.hpp"
#include "rosa/agent/Functionality.h"
#include "rosa/agent/ReliabilityConfidenceCombinator.h"
#include "rosa/core/forward_declarations.h" // needed for id_t
#include "rosa/support/log.h" // needed for error "handling"
// nedded headers
#include <string>
#include <type_traits> //assert
#include <vector>
// for static methods
#include <algorithm>
#include <numeric>
namespace rosa {
namespace agent {
template <typename id, typename IdentifierType, typename ReliabilityType>
-std::vector<std::pair<id_t, IdentifierType>> &
-operator<<(std::vector<std::pair<id_t, IdentifierType>> &me,
- std::vector<std::tuple<id, IdentifierType, ReliabilityType>> Values) {
+std::vector<std::pair<id_t, IdentifierType>> &operator<<(
+ std::vector<std::pair<id_t, IdentifierType>> &me,
+ std::vector<std::tuple<id, IdentifierType, ReliabilityType>> Values) {
for (auto tmp : Values) {
std::pair<id, IdentifierType> tmp2;
tmp2.first = std::get<0>(tmp);
tmp2.second = std::get<1>(tmp);
me.push_back(tmp2);
}
return me;
}
/// This is the Combinator class for cross reliabilities it has many functions
/// with different purposes
-/// \brief It takes the Identifiers and reliabilities of all given ids and calculates
-/// the Reliability of them together. Also it can creates the feedback that is
-/// needed by the \c ReliabilityAndConfidenceCombinator, which is a kind of
-/// confidence.
+/// \brief It takes the Identifiers and reliabilities of all given ids and
+/// calculates the Reliability of them together. Also it can creates the
+/// feedback that is needed by the \c ReliabilityAndConfidenceCombinator, which
+/// is a kind of confidence.
///
-/// \tparam IdentifierType Datatype of the State ( Typically double or float)
-/// \tparam ReliabilityType Datatype of the Reliability (
-/// Typically long or int)
+/// \tparam IdentifierType Datatype of the Identifier ( Typically double or
+/// float) \tparam ReliabilityType Datatype of the Reliability ( Typically
+/// long or int)
///
/// \note This class is commonly in a master slave relationship as master with
/// \c ReliabilityAndConfidenceCombinator. The \c operator()() combines the
/// Reliability of all connected Slaves and uses that as its own Reliability
/// also creates the feedback for the Slaves.
///
/// \note more information about how the Reliability and feedback is
/// created at \c operator()() , \c getCombinedCrossReliability() , \c
/// getCombinedInputReliability() , \c getOutputReliability() [ this is the
/// commonly used Reliability ], \c getCrossConfidence() [ this is the feedback
/// for all Slaves ]
-template <typename IdentifierType, typename ReliabilityType> class CrossCombinator {
+template <typename IdentifierType, typename ReliabilityType>
+class CrossCombinator {
public:
static_assert(std::is_arithmetic<IdentifierType>::value,
"HighLevel: IdentifierType has to be an arithmetic type\n");
static_assert(std::is_arithmetic<ReliabilityType>::value,
"HighLevel: ReliabilityType has to be an arithmetic type\n");
// ---------------------------------------------------------------------------
// useful definitions
// ---------------------------------------------------------------------------
/// typedef To shorten the writing.
/// \c ConfOrRel
using ConfOrRel = ConfOrRel<IdentifierType, ReliabilityType>;
/// To shorten the writing.
using Abstraction =
typename rosa::agent::Abstraction<IdentifierType, ReliabilityType>;
/// The return type for the \c operator()() Method
struct returnType {
ReliabilityType CrossReliability;
std::map<id_t, std::vector<ConfOrRel>> CrossConfidence;
};
// -------------------------------------------------------------------------
// Relevant Methods
// -------------------------------------------------------------------------
/// Calculates the Reliability and the CrossConfidences for each id for all
- /// of there states.
+ /// of there Identifiers.
///
- /// \param Values It gets the States and Reliabilities of
+ /// \param Values It gets the Identifiers and Reliabilities of
/// all connected Slaves inside a vector.
///
/// \return it returns a struct \c returnType containing the \c
/// getCombinedCrossReliability() and \c getCrossConfidence()
- returnType
- operator()(std::vector<std::tuple<id_t, IdentifierType, ReliabilityType>> Values) {
+ returnType operator()(
+ std::vector<std::tuple<id_t, IdentifierType, ReliabilityType>> Values) {
return {getOutputReliability(Values), getCrossConfidence(Values)};
}
/// returns the combined via \c CombinedCrossRelCombinationMethod \c
/// setCombinedCrossRelCombinationMethod() Cross Reliability for all ids \c
/// CrossReliability() \param Values the used Values
ReliabilityType getCombinedCrossReliability(
std::vector<std::tuple<id_t, IdentifierType, ReliabilityType>> Values) {
ReliabilityType combinedCrossRel = -1;
std::vector<std::pair<id_t, IdentifierType>> Agents;
Agents << Values;
for (auto Value : Values) {
id_t id = std::get<0>(Value);
IdentifierType sc = std::get<1>(Value);
// calculate the cross reliability for this slave agent
- ReliabilityType realCrossReliabilityOfSlaveAgent = CrossReliability(
- {id, sc},
- Agents);
+ ReliabilityType realCrossReliabilityOfSlaveAgent =
+ CrossReliability({id, sc}, Agents);
if (combinedCrossRel != -1)
combinedCrossRel = CombinedCrossRelCombinationMethod(
combinedCrossRel, realCrossReliabilityOfSlaveAgent);
else
combinedCrossRel = realCrossReliabilityOfSlaveAgent;
}
return combinedCrossRel;
}
/// returns the combined via \c CombinedInputRelCombinationMethod \c
/// setCombinedInputRelCombinationMethod() input relibility \param Values the
/// used Values
ReliabilityType getCombinedInputReliability(
std::vector<std::tuple<id_t, IdentifierType, ReliabilityType>> Values) {
ReliabilityType combinedInputRel = -1;
std::vector<std::pair<id_t, IdentifierType>> Agents;
Agents << Values;
for (auto Value : Values) {
ReliabilityType rel = std::get<2>(Value);
if (combinedInputRel != -1)
combinedInputRel =
CombinedInputRelCombinationMethod(combinedInputRel, rel);
else
combinedInputRel = rel;
}
return combinedInputRel;
}
/// returns the combination via \c OutputReliabilityCombinationMethod \c
/// setOutputReliabilityCombinationMethod() of the Cross reliability and
/// input reliability \param Values the used Values
ReliabilityType getOutputReliability(
std::vector<std::tuple<id_t, IdentifierType, ReliabilityType>> Values) {
return OutputReliabilityCombinationMethod(
getCombinedInputReliability(Values),
getCombinedCrossReliability(Values));
}
/// retruns the crossConfidence for all ids \c CrossConfidence()
/// \param Values the used Values
std::map<id_t, std::vector<ConfOrRel>> getCrossConfidence(
std::vector<std::tuple<id_t, IdentifierType, ReliabilityType>> Values) {
std::vector<std::pair<id_t, IdentifierType>> Agents;
std::map<id_t, std::vector<ConfOrRel>> output;
std::vector<ConfOrRel> output_temporary;
Agents << Values;
for (auto Value : Values) {
id_t id = std::get<0>(Value);
output_temporary.clear();
- for (IdentifierType thoIdentifier : States[id]) {
+ for (IdentifierType thoIdentifier : Identifiers[id]) {
ConfOrRel data;
data.Identifier = thoIdentifier;
data.Reliability = CrossConfidence(id, thoIdentifier, Agents);
output_temporary.push_back(data);
}
output.insert({id, output_temporary});
}
return output;
}
/// Calculates the Cross Confidence
- /// \brief it uses the state represented by a numerical value and calculates
+ /// \brief it uses the Identifier value and calculates
/// the Confidence of a given agent( represented by there id ) for a given
- /// state in connection to all other given agents
+ /// Identifiers in connection to all other given agents
///
/// \note all combination of agents and there corresponding Cross Reliability
/// function have to be specified
ReliabilityType
CrossConfidence(id_t MainAgent, IdentifierType TheoreticalValue,
std::vector<std::pair<id_t, IdentifierType>> &SlaveAgents) {
ReliabilityType crossReliabiability;
std::vector<ReliabilityType> values;
for (std::pair<id_t, IdentifierType> SlaveAgent : SlaveAgents) {
if (SlaveAgent.first == MainAgent)
continue;
if (TheoreticalValue == SlaveAgent.second)
crossReliabiability = 1;
else
crossReliabiability =
1 / (crossReliabilityParameter *
AbsuluteValue(TheoreticalValue, SlaveAgent.second));
// profile reliability
ReliabilityType crossReliabilityFromProfile =
getCrossReliabilityFromProfile(
MainAgent, SlaveAgent.first,
AbsuluteValue(TheoreticalValue, SlaveAgent.second));
values.push_back(
std::max(crossReliabiability, crossReliabilityFromProfile));
}
return Method(values);
}
/// Calculates the Cross Reliability
- /// \brief it uses the state represented by a numerical value and calculates
+ /// \brief it uses the Identifier value and calculates
/// the Reliability of a given agent( represented by there id ) in connection
/// to all other given agents
///
/// \note all combination of agents and there corresponding Cross Reliability
/// function have to be specified
ReliabilityType
CrossReliability(std::pair<id_t, IdentifierType> &&MainAgent,
std::vector<std::pair<id_t, IdentifierType>> &SlaveAgents) {
ReliabilityType crossReliabiability;
std::vector<ReliabilityType> values;
for (std::pair<id_t, IdentifierType> 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
ReliabilityType crossReliabilityFromProfile =
getCrossReliabilityFromProfile(
MainAgent.first, SlaveAgent.first,
AbsuluteValue(MainAgent.second, SlaveAgent.second));
values.push_back(
std::max(crossReliabiability, crossReliabilityFromProfile));
}
return Method(values);
}
// --------------------------------------------------------------------------
// Defining the class
// --------------------------------------------------------------------------
- /// adds a Cross Reliability Profile used to get the Reliability of the state
- /// difference
+ /// adds a Cross Reliability Profile used to get the Reliability of the
+ /// Identifier difference
+ ///
/// \param idA The id of the one \c Agent ( idealy the id of \c Unit to make
/// it absolutly unique )
///
/// \param idB The id of the other \c Agent
///
/// \param Function A unique pointer to an \c Abstraction it would use the
/// difference in Identifier for its input
void addCrossReliabilityProfile(id_t idA, id_t idB,
std::unique_ptr<Abstraction> &Function) {
Abstraction *ptr = Function.release();
Functions.push_back({true, idA, idB, ptr});
}
/// sets the cross reliability parameter
void setCrossReliabilityParameter(ReliabilityType val) {
crossReliabilityParameter = val;
}
- /// This is the adder for the states
- /// \param id The id of the Agent of the states
- /// \param States id specific states. this will be copied So that if Slaves
- /// have different States they can be used correctly.
- /// \brief The States of all connected lowlevel Agents has to be known to be
- /// able to iterate over them
- void addStates(id_t id, std::vector<IdentifierType> States) {
- this->States.insert({id, States});
+ /// This is the adder for the Identifiers
+ /// \param id The id of the Agent of the Identifiers
+ /// \param Identifiers id specific Identifiers. this will be copied So that if
+ /// Slaves have different Identifiers they can be used correctly. \brief The
+ /// Identifiers of all connected lowlevel Agents has to be known to be able to
+ /// iterate over them
+ void addIdentifiers(id_t id, std::vector<IdentifierType> Identifiers) {
+ this->Identifiers.insert({id, Identifiers});
}
// -------------------------------------------------------------------------
// Combinator Settings
// -------------------------------------------------------------------------
/// sets the used method to combine the values
/// \param Meth The Function which defines the combination method. predef: \c
/// CONJUNCTION() \c AVERAGE() \c DISJUNCTION()
void setCrossReliabilityCombinatorMethod(
- ReliabilityType (*Meth)(std::vector<ReliabilityType> values)) {
+ std::function<ReliabilityType(std::vector<ReliabilityType> values)>
+ Meth) {
Method = Meth;
}
/// sets the combination method for the combined cross reliability
/// \param Meth the method which should be used. predef: \c
/// CombinedCrossRelCombinationMethodMin() \c
/// CombinedCrossRelCombinationMethodMax() \c
/// CombinedCrossRelCombinationMethodMult() \c
/// CombinedCrossRelCombinationMethodAverage()
void setCombinedCrossRelCombinationMethod(
- ReliabilityType (*Meth)(ReliabilityType, ReliabilityType)) {
+ std::function<ReliabilityType(ReliabilityType, ReliabilityType)> Meth) {
CombinedCrossRelCombinationMethod = Meth;
}
/// sets the combined input rel method
/// \param Meth the method which should be used predef: \c
/// CombinedInputRelCombinationMethodMin() \c
/// CombinedInputRelCombinationMethodMax() \c
/// CombinedInputRelCombinationMethodMult() \c
/// CombinedInputRelCombinationMethodAverage()
void setCombinedInputRelCombinationMethod(
- ReliabilityType (*Meth)(ReliabilityType, ReliabilityType)) {
+ std::function<ReliabilityType(ReliabilityType, ReliabilityType)> Meth) {
CombinedInputRelCombinationMethod = Meth;
}
/// sets the used OutputReliabilityCombinationMethod
/// \param Meth the used Method. predef: \c
/// OutputReliabilityCombinationMethodMin() \c
/// OutputReliabilityCombinationMethodMax() \c
/// OutputReliabilityCombinationMethodMult() \c
/// OutputReliabilityCombinationMethodAverage()
void setOutputReliabilityCombinationMethod(
- ReliabilityType (*Meth)(ReliabilityType, ReliabilityType)) {
+ std::function<ReliabilityType(ReliabilityType, ReliabilityType)> Meth) {
OutputReliabilityCombinationMethod = Meth;
}
// -------------------------------------------------------------------------
// Predefined Functions
// -------------------------------------------------------------------------
/// predefined combination method
- static ReliabilityType CONJUNCTION(std::vector<ReliabilityType> values) {
- return *std::min_element(values.begin(), values.end());
- }
+ struct predefinedMethods {
+ static ReliabilityType CONJUNCTION(std::vector<ReliabilityType> values) {
+ return *std::min_element(values.begin(), values.end());
+ }
- /// predefined combination method
- static ReliabilityType AVERAGE(std::vector<ReliabilityType> values) {
- return std::accumulate(values.begin(), values.end(), 0.0) / values.size();
- }
+ /// predefined combination method
+ static ReliabilityType AVERAGE(std::vector<ReliabilityType> values) {
+ return std::accumulate(values.begin(), values.end(), 0.0) / values.size();
+ }
- /// predefined combination method
- static ReliabilityType DISJUNCTION(std::vector<ReliabilityType> values) {
- return *std::max_element(values.begin(), values.end());
- }
+ /// predefined combination method
+ static ReliabilityType DISJUNCTION(std::vector<ReliabilityType> values) {
+ return *std::max_element(values.begin(), values.end());
+ }
- /// predefined combination Method
- static ReliabilityType
- CombinedCrossRelCombinationMethodMin(ReliabilityType A, ReliabilityType B) {
- return std::min(A, B);
- }
+ /// predefined combination Method
+ static ReliabilityType
+ CombinedCrossRelCombinationMethodMin(ReliabilityType A, ReliabilityType B) {
+ return std::min(A, B);
+ }
- /// predefined combination Method
- static ReliabilityType
- CombinedCrossRelCombinationMethodMax(ReliabilityType A, ReliabilityType B) {
- return std::max(A, B);
- }
+ /// predefined combination Method
+ static ReliabilityType
+ CombinedCrossRelCombinationMethodMax(ReliabilityType A, ReliabilityType B) {
+ return std::max(A, B);
+ }
- /// predefined combination Method
- static ReliabilityType
- CombinedCrossRelCombinationMethodMult(ReliabilityType A, ReliabilityType B) {
- return A * B;
- }
+ /// predefined combination Method
+ static ReliabilityType
+ CombinedCrossRelCombinationMethodMult(ReliabilityType A,
+ ReliabilityType B) {
+ return A * B;
+ }
- /// predefined combination Method
- static ReliabilityType
- CombinedCrossRelCombinationMethodAverage(ReliabilityType A,
- ReliabilityType B) {
- return (A + B) / 2;
- }
+ /// predefined combination Method
+ static ReliabilityType
+ CombinedCrossRelCombinationMethodAverage(ReliabilityType A,
+ ReliabilityType B) {
+ return (A + B) / 2;
+ }
- /// predefined combination Method
- static ReliabilityType
- CombinedInputRelCombinationMethodMin(ReliabilityType A, ReliabilityType B) {
- return std::min(A, B);
- }
+ /// predefined combination Method
+ static ReliabilityType
+ CombinedInputRelCombinationMethodMin(ReliabilityType A, ReliabilityType B) {
+ return std::min(A, B);
+ }
- /// predefined combination Method
- static ReliabilityType
- CombinedInputRelCombinationMethodMax(ReliabilityType A, ReliabilityType B) {
- return std::max(A, B);
- }
+ /// predefined combination Method
+ static ReliabilityType
+ CombinedInputRelCombinationMethodMax(ReliabilityType A, ReliabilityType B) {
+ return std::max(A, B);
+ }
- /// predefined combination Method
- static ReliabilityType
- CombinedInputRelCombinationMethodMult(ReliabilityType A, ReliabilityType B) {
- return A * B;
- }
+ /// predefined combination Method
+ static ReliabilityType
+ CombinedInputRelCombinationMethodMult(ReliabilityType A,
+ ReliabilityType B) {
+ return A * B;
+ }
- /// predefined combination Method
- static ReliabilityType
- CombinedInputRelCombinationMethodAverage(ReliabilityType A,
- ReliabilityType B) {
- return (A + B) / 2;
- }
+ /// predefined combination Method
+ static ReliabilityType
+ CombinedInputRelCombinationMethodAverage(ReliabilityType A,
+ ReliabilityType B) {
+ return (A + B) / 2;
+ }
- /// predefined combination method
- static ReliabilityType
- OutputReliabilityCombinationMethodMin(ReliabilityType A, ReliabilityType B) {
- return std::min(A, B);
- }
+ /// predefined combination method
+ static ReliabilityType
+ OutputReliabilityCombinationMethodMin(ReliabilityType A,
+ ReliabilityType B) {
+ return std::min(A, B);
+ }
- /// predefined combination method
- static ReliabilityType
- OutputReliabilityCombinationMethodMax(ReliabilityType A, ReliabilityType B) {
- return std::max(A, B);
- }
+ /// predefined combination method
+ static ReliabilityType
+ OutputReliabilityCombinationMethodMax(ReliabilityType A,
+ ReliabilityType B) {
+ return std::max(A, B);
+ }
- /// predefined combination method
- static ReliabilityType
- OutputReliabilityCombinationMethodMult(ReliabilityType A, ReliabilityType B) {
- return A * B;
- }
+ /// predefined combination method
+ static ReliabilityType
+ OutputReliabilityCombinationMethodMult(ReliabilityType A,
+ ReliabilityType B) {
+ return A * B;
+ }
- /// predefined combination method
- static ReliabilityType
- OutputReliabilityCombinationMethodAverage(ReliabilityType A,
- ReliabilityType B) {
- return (A + B) / 2;
- }
+ /// predefined combination method
+ static ReliabilityType
+ OutputReliabilityCombinationMethodAverage(ReliabilityType A,
+ ReliabilityType B) {
+ return (A + B) / 2;
+ }
+ };
// -------------------------------------------------------------------------
// Cleanup
// -------------------------------------------------------------------------
~CrossCombinator() {
for (auto tmp : Functions)
delete tmp.Funct;
Functions.clear();
}
// --------------------------------------------------------------------------
// Needed stuff and stored stuff
// --------------------------------------------------------------------------
private:
struct Functionblock {
bool exists = false;
id_t A;
id_t B;
Abstraction *Funct;
};
- std::map<id_t, std::vector<IdentifierType>> States;
+ std::map<id_t, std::vector<IdentifierType>> Identifiers;
/// From Maxi in his code defined as 1 can be changed by set
ReliabilityType crossReliabilityParameter = 1;
/// Stored Cross Reliability Functions
std::vector<Functionblock> Functions;
/// Method which is used to combine the generated values
- ReliabilityType (*Method)(std::vector<ReliabilityType> values) = AVERAGE;
+ std::function<ReliabilityType(std::vector<ReliabilityType>)> Method =
+ predefinedMethods::AVERAGE;
- ReliabilityType (*CombinedCrossRelCombinationMethod)(
- ReliabilityType, ReliabilityType) = CombinedCrossRelCombinationMethodMin;
+ std::function<ReliabilityType(ReliabilityType, ReliabilityType)>
+ CombinedCrossRelCombinationMethod =
+ predefinedMethods::CombinedCrossRelCombinationMethodMin;
- ReliabilityType (*CombinedInputRelCombinationMethod)(
- ReliabilityType, ReliabilityType) = CombinedInputRelCombinationMethodMin;
+ std::function<ReliabilityType(ReliabilityType, ReliabilityType)>
+ CombinedInputRelCombinationMethod =
+ predefinedMethods::CombinedInputRelCombinationMethodMin;
- ReliabilityType (*OutputReliabilityCombinationMethod)(
- ReliabilityType, ReliabilityType) = OutputReliabilityCombinationMethodMin;
+ std::function<ReliabilityType(ReliabilityType, ReliabilityType)>
+ OutputReliabilityCombinationMethod =
+ predefinedMethods::OutputReliabilityCombinationMethodMin;
//--------------------------------------------------------------------------------
// helper function
/// evaluates the absolute Value of two values
/// \note this is actually the absolute distance but to keep it somewhat
/// conform with maxis code
template <typename Type_t> Type_t AbsuluteValue(Type_t A, Type_t B) {
return ((A - B) < 0) ? B - A : A - B;
}
/// very inefficient searchFunction
Functionblock (*searchFunction)(std::vector<Functionblock> vect,
const id_t nameA, const id_t nameB) =
[](std::vector<Functionblock> 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();
};
/// evaluates the corresponding LinearFunction with the Identifier difference
/// \param nameA these two parameters are the unique identifiers
/// \param nameB these two parameters are the unique identifiers
/// for the LinerFunction
///
/// \note it doesn't matter if they are swapped
- ReliabilityType getCrossReliabilityFromProfile(id_t nameA, id_t nameB,
- IdentifierType IdentifierDifference) {
+ ReliabilityType
+ getCrossReliabilityFromProfile(id_t nameA, id_t nameB,
+ IdentifierType IdentifierDifference) {
Functionblock block = searchFunction(Functions, nameA, nameB);
if (!block.exists) {
LOG_ERROR(("CrossReliability: Block:" + std::to_string(nameA) + "," +
std::to_string(nameB) + "doesn't exist returning 0"));
return 0;
}
return block.Funct->operator()(IdentifierDifference);
}
};
} // End namespace agent
} // End namespace rosa
#endif // ROSA_AGENT_CROSSRELIABILITY_H
\ No newline at end of file
diff --git a/include/rosa/agent/ReliabilityConfidenceCombinator.h b/include/rosa/agent/ReliabilityConfidenceCombinator.h
index 901a12e..6670b0e 100644
--- a/include/rosa/agent/ReliabilityConfidenceCombinator.h
+++ b/include/rosa/agent/ReliabilityConfidenceCombinator.h
@@ -1,804 +1,745 @@
//===-- rosa/agent/ReliabilityConfidenceCombinator.h ------------*- C++ -*-===//
//
// The RoSA Framework
//
//===----------------------------------------------------------------------===//
///
/// \file rosa/agent/ReliabilityConfidenceCombinator.h
///
/// \author Daniel Schnoell (daniel.schnoell@tuwien.ac.at)
///
/// \date 2019
///
/// \brief Definition of *ReliabilityConfidenceCombinator* *functionality*.
///
/// \note based on Maximilian Goetzinger (maxgot@utu.fi) code in
/// CAM_Dirty_include SA-EWS2_Version... inside Agent.cpp
///
/// \note By defining and setting Reliability_trace_level it is possible to
/// change the level to which it should be traced. \note All classes throw
/// runtime errors if not all things are set
///
/// \note should the Reliability be capped?
///
///
//===----------------------------------------------------------------------===//
#ifndef ROSA_AGENT_ReliabilityConfidenceCombinator_H
#define ROSA_AGENT_ReliabilityConfidenceCombinator_H
#include "rosa/core/forward_declarations.h" // needed for id_t
#include "rosa/support/log.h"
#include "rosa/agent/FunctionAbstractions.hpp"
#include "rosa/agent/Functionality.h"
#include "rosa/agent/RangeConfidence.hpp"
#include <algorithm>
+#include <functional>
#include <type_traits>
#include <vector>
/// 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 Reliability Combinator
/// more readable \tparam IdentifierType The datatype of the States \tparam
/// ReliabilityType The datatype of the Reliability
template <typename IdentifierType, typename ReliabilityType> struct ConfOrRel {
/// making both Template Arguments readable to make a few things easier
using _IdentifierType = IdentifierType;
/// making both Template Arguments readable to make a few things easier
using _ReliabilityType = ReliabilityType;
/// The actual place where the data is stored
IdentifierType Identifier;
/// The actual place where the data is stored
ReliabilityType Reliability;
ConfOrRel(IdentifierType _Identifier, ReliabilityType _Reliability)
: Identifier(_Identifier), 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 << "Identifier: " << c.Identifier << "\t Reliability: " << c.Reliability
<< " ";
return out;
}
/// needed or it throws an clang diagnosic error
using map =
std::map<IdentifierType, ReliabilityType>; // needed or it throws an
// clang diagnosic error
/// 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 is to push the data inside a vector in a human readable 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 Reliabilities
-/// \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 calculates the maximum of the Reliabilities & the given value
-/// \param me The vector with the Reliabilities
-/// \param value The comparing value
-template <typename Conf>
-std::vector<Conf> max(std::vector<Conf> me,
- typename Conf::_ReliabilityType value) {
- static_assert(std::is_arithmetic<typename Conf::_ReliabilityType>::value);
- for (auto tmp : me)
- tmp.Reliability = std::max(tmp.Reliability, value);
- return me;
-}
-/// This calculates the average of the Reliabilities & the given value
-/// \param me The vector with the Reliabilities
-/// \param value The comparing value
-template <typename Conf>
-std::vector<Conf> average(std::vector<Conf> me,
- typename Conf::_ReliabilityType value) {
- static_assert(std::is_arithmetic<typename Conf::_ReliabilityType>::value);
- for (auto tmp : me)
- tmp.Reliability = (tmp.Reliability + value) / 2;
- return me;
-}
-
-/// This calculates the average of the Reliabilities & the given value
-/// \param me The vector with the Reliabilities
-/// \param value The comparing value
-template <typename Conf>
-std::vector<Conf> mult(std::vector<Conf> me,
- typename Conf::_ReliabilityType value) {
- static_assert(std::is_arithmetic<typename Conf::_ReliabilityType>::value);
- for (auto tmp : me)
- tmp.Reliability = tmp.Reliability * value / 2;
- return me;
-}
-
-/// This average's the Reliabilities of the same Identifiers
-template <typename Conf>
-std::vector<Conf> average(std::vector<Conf> A, std::vector<Conf> B) {
- static_assert(std::is_arithmetic<typename Conf::_ReliabilityType>::value);
- for (auto &tmp_me : A)
- for (auto &tmp_other : B) {
- if (tmp_me.Identifier == tmp_other.Identifier) {
- tmp_me.Reliability = (tmp_me.Reliability + tmp_other.Reliability) / 2;
- }
- }
- return A;
-}
-/// This min's the Reliabilities of the same Identifiers
-template <typename Conf>
-std::vector<Conf> min(std::vector<Conf> A, std::vector<Conf> B) {
- static_assert(std::is_arithmetic<typename Conf::_ReliabilityType>::value);
- for (auto &tmp_me : A)
- for (auto &tmp_other : B) {
- if (tmp_me.Identifier == tmp_other.Identifier) {
- tmp_me.Reliability =
- std::min(tmp_me.Reliability + tmp_other.Reliability);
- }
- }
- return A;
-}
-/// This max's the Reliabilities of the same Identifiers
-template <typename Conf>
-std::vector<Conf> max(std::vector<Conf> A, std::vector<Conf> B) {
- static_assert(std::is_arithmetic<typename Conf::_ReliabilityType>::value);
- for (auto &tmp_me : A)
- for (auto &tmp_other : B) {
- if (tmp_me.Identifier == tmp_other.Identifier) {
- tmp_me.Reliability =
- std::max(tmp_me.Reliability + tmp_other.Reliability);
- }
- }
- return A;
-}
-/// This mult's the Reliabilities of the same Identifiers
-template <typename Conf>
-std::vector<Conf> mult(std::vector<Conf> A, std::vector<Conf> B) {
- static_assert(std::is_arithmetic<typename Conf::_ReliabilityType>::value);
- for (auto &tmp_me : A)
- for (auto &tmp_other : B) {
- if (tmp_me.Identifier == tmp_other.Identifier) {
- tmp_me.Reliability = tmp_me.Reliability * tmp_other.Reliability;
- }
- }
- return A;
-}
-
/// This is the combinator for Reliability and confidences it takes the
/// Sensor value, its "History" and feedback from \c
/// CrossCombinator to calculate different Reliabilities.
/// \tparam SensorValueType Datatype of the Sensor value ( Typically
/// double or float) \tparam IdentifierType Datatype of the State ( Typically
/// long or int)
/// \tparam ReliabilityType Datatype of the Reliability (
/// Typically double or float)
///
/// \note more information about how it calculates
/// the Reliabilities it should be considered feedback is a sort of Confidence
/// \verbatim
///----------------------------------------------------------------------------------
///
///
/// ->Reliability---> getInputReliability()
/// | |
/// | V
/// Sensor Value ---| PossibleIdentifierCombinationMethod -> next line
/// | A |
/// | | V
/// ->Confidence--- getPossibleIdentifiers()
///
///-----------------------------------------------------------------------------------
///
/// feedback
/// |
/// V
/// ValuesFromMaster
/// | -> History ---|
/// V | V
/// here -> FeedbackCombinatorMethod --------> HistoryCombinatorMethod->nextline
/// | |
/// V V
/// getpossibleIdentifiersWithMasterFeedback()getPossibleIdentifiersWithHistory()
///
///----------------------------------------------------------------------------------
///
/// here -> sort -> most likely -> getmostLikelyIdentifierAndReliability()
///
/// ---------------------------------------------------------------------------------
/// \endverbatim
/// the mentioned methods are early outs so if two ore more of them are run in
/// the same step they will be interpreted as different time steps
/// <pre>
/// Default values for Combinators:
/// InputReliabilityCombinator = combinationMin;
/// PossibleIdentifierCombinationMethod=PossibleIdentifierCombinationMethodMin;
/// FeedbackCombinatorMethod = FeedbackCombinatorMethodAverage;
/// HistoryCombinatorMethod = HistoryCombinatorMethodMax;
/// </pre>
/// To understand the place where the combinator methods come into play a list
/// for each getter which Methods are used.
///
/// <pre>
/// \c getInputReliability():
/// -InputReliabilityCombinator
/// \c getPossibleIdentifiers():
/// -InputReliabilityCombinator
/// -PossibleIdentifierCombinationMethod
/// \c getpossibleIdentifiersWithMasterFeedback():
/// -InputReliabilityCombinator
/// -PossibleIdentifierCombinationMethod
/// -FeedbackCombinatorMethod
/// \c getPossibleIdentifiersWithHistory():
/// -InputReliabilityCombinator
/// -PossibleIdentifierCombinationMethod
/// -FeedbackCombinatorMethod
/// -HistoryCombinatorMethod
/// \c getmostLikelyIdentifierAndReliability():
/// -InputReliabilityCombinator
/// -PossibleIdentifierCombinationMethod
/// -FeedbackCombinatorMethod
/// -HistoryCombinatorMethod
/// </pre>
///
///
///
///
template <typename SensorValueType, typename IdentifierType,
typename ReliabilityType>
class ReliabilityAndConfidenceCombinator {
public:
static_assert(std::is_arithmetic<SensorValueType>::value,
"LowLevel: SensorValueType has to an arithmetic type\n");
static_assert(std::is_arithmetic<IdentifierType>::value,
"LowLevel: IdentifierType has to an arithmetic type\n");
static_assert(std::is_arithmetic<ReliabilityType>::value,
"LowLevel: ReliabilityType has to an arithmetic type\n");
/// Typedef to shorten the writing.
/// \c ConfOrRel
using ConfOrRel = ConfOrRel<IdentifierType, ReliabilityType>;
/// Calculates the input reliability by combining Reliability of the Sensor
/// and the Slope Reliability \param SensorValue The sensor Value \note to set
/// the combination method \c setInputReliabilityCombinator()
auto getInputReliability(SensorValueType SensorValue) {
auto inputReliability =
getReliability(SensorValue, previousSensorValue, valueSetCounter);
previousSensorValue = SensorValue;
PreviousSensorValueExists = true;
return inputReliability;
}
/// Calculates the possible Identifiers
/// \param SensorValue the Sensor Value
/// \brief it combines the input reliability and the confidence of the Sensor.
/// The use combination method can be set using \c
/// setPossibleIdentifierCombinationMethod()
auto getPossibleIdentifiers(SensorValueType SensorValue) {
std::vector<ConfOrRel> possibleIdentifiers;
ReliabilityType inputReliability = getInputReliability(SensorValue);
#if Reliability_trace_level <= trace_vectors
LOG_TRACE_STREAM << "\ninput Rel: " << inputReliability << trace_end;
#endif
possibleIdentifiers << Confidence->operator()(SensorValue);
possibleIdentifiers = PossibleIdentifierCombinationMethod(
possibleIdentifiers, inputReliability);
return possibleIdentifiers;
}
/// return the Possible Values with the feedback in mind
/// \param SensorValue The sensor Value
/// \brief it combines the input reliability and the confidence of the Sensor.
/// The combines them with FeedbackCombinatorMethod and returns the result.
auto getpossibleIdentifiersWithMasterFeedback(SensorValueType SensorValue) {
std::vector<ConfOrRel> possibleIdentifiers;
ReliabilityType inputReliability = getInputReliability(SensorValue);
#if Reliability_trace_level <= trace_vectors
LOG_TRACE_STREAM << "\ninput Rel: " << inputReliability << trace_end;
#endif
possibleIdentifiers << Confidence->operator()(SensorValue);
possibleIdentifiers = PossibleIdentifierCombinationMethod(
possibleIdentifiers, inputReliability);
possibleIdentifiers =
FeedbackCombinatorMethod(possibleIdentifiers, ValuesFromMaster);
return possibleIdentifiers;
}
/// returns all possible Identifiers and Reliabilities with the History in
/// mind \param SensorValue the Sensor value how this is done is described at
/// the class.
auto getPossibleIdentifiersWithHistory(SensorValueType SensorValue) {
std::vector<ConfOrRel> ActuallPossibleIdentifiers;
std::vector<ConfOrRel> possibleIdentifiers;
ReliabilityType inputReliability = getInputReliability(SensorValue);
#if Reliability_trace_level <= trace_vectors
LOG_TRACE_STREAM << "\ninput Rel: " << inputReliability << trace_end;
#endif
possibleIdentifiers << Confidence->operator()(SensorValue);
possibleIdentifiers = PossibleIdentifierCombinationMethod(
possibleIdentifiers, inputReliability);
possibleIdentifiers =
FeedbackCombinatorMethod(possibleIdentifiers, ValuesFromMaster);
saveInHistory(possibleIdentifiers);
#if Reliability_trace_level <= trace_vectors
LOG_TRACE_STREAM << "\nActuallPossibleIdentifiers:\n"
<< possibleIdentifiers << trace_end;
LOG_TRACE_STREAM << "\npossibleIdentifiers:\n"
<< possibleIdentifiers << trace_end;
#endif
possibleIdentifiers.clear();
return getAllPossibleIdentifiersBasedOnHistory();
}
-
/// Calculates the Reliability
/// \param SensorValue The current Values of the Sensor
///
/// \return Reliability and Identifier of the current SensorValue
///
ConfOrRel getmostLikelyIdentifierAndReliability(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> ActuallPossibleIdentifiers;
std::vector<ConfOrRel> possibleIdentifiers;
ReliabilityType inputReliability = getInputReliability(SensorValue);
#if Reliability_trace_level <= trace_vectors
LOG_TRACE_STREAM << "\ninput Rel: " << inputReliability << trace_end;
#endif
possibleIdentifiers << Confidence->operator()(SensorValue);
possibleIdentifiers = PossibleIdentifierCombinationMethod(
possibleIdentifiers, inputReliability);
possibleIdentifiers =
FeedbackCombinatorMethod(possibleIdentifiers, ValuesFromMaster);
saveInHistory(possibleIdentifiers);
#if Reliability_trace_level <= trace_vectors
LOG_TRACE_STREAM << "\nActuallPossibleIdentifiers:\n"
<< possibleIdentifiers << trace_end;
LOG_TRACE_STREAM << "\npossibleIdentifiers:\n"
<< possibleIdentifiers << trace_end;
#endif
possibleIdentifiers.clear();
possibleIdentifiers = getAllPossibleIdentifiersBasedOnHistory();
std::sort(possibleIdentifiers.begin(), possibleIdentifiers.end(),
[](ConfOrRel A, ConfOrRel B) -> bool {
return A.Reliability > B.Reliability;
});
#if Reliability_trace_level <= trace_outputs
LOG_TRACE_STREAM << "\noutput lowlevel: " << possibleIdentifiers.at(0)
<< trace_end;
#endif
return possibleIdentifiers.at(0);
}
-
/// feedback for this functionality most commonly it comes from a Master Agent
/// \param ValuesFromMaster The Identifiers + Reliability for the feedback
/// \brief This input kind of resembles a confidence but not
/// directly it more or less says: compared to the other Identifiers inside
/// the System these are the Identifiers with the Reliability that you have.
void feedback(std::vector<ConfOrRel> ValuesFromMaster) {
this->ValuesFromMaster = ValuesFromMaster;
}
//
// ----------------------Reliability and Confidence Function setters----------
//
/// This is the setter for Confidence Function
/// \param Confidence A pointer to the Functional for the \c Confidence of the
/// Sensor value
void setConfidenceFunction(
std::unique_ptr<RangeConfidence<ReliabilityType, IdentifierType,
SensorValueType>> &Confidence) {
this->Confidence = std::move(Confidence);
}
/// This is the setter for Reliability Function
/// \param Reliability A pointer to the Functional for the Reliability
/// \brief The Reliability takes the current Sensor value and return the
/// Reliability of the value.
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
/// \brief The ReliabilitySlope takes the difference of the current Sensor
/// Value to the last one and tells you how likely the change is.
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
/// \brief The time function takes the position in the History with greater
/// equals older and return a Reliability of how "relevant" it is.
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 vector containing all states
/// \brief This exists even though \c State Type is an arithmetic Type because
/// the states do not need to be "next" to each other ( ex. states={ 1 7 24 })
void setStates(std::vector<IdentifierType> states) { this->States = states; }
/// This sets the Maximum length of the History
/// \param length The length
void setHistoryLength(std::size_t length) { this->HistoryMaxSize = length; }
/// This sets the Value set Counter
/// \param ValueSetCounter the new Value
/// \note This might actually be only an artifact. It is only used to get the
/// reliability from the \c ReliabilitySlope [ ReliabilitySlope->operator()(
/// (lastValue - actualValue) / (SensorValueType)valueSetCounter) ]
void setValueSetCounter(unsigned int ValueSetCounter) {
this->valueSetCounter = ValueSetCounter;
}
//
// ----------------combinator setters-----------------------------------------
//
/// This sets the combination method used by the History
/// \param Meth the method which should be used. predefined \c
/// HistoryCombinatorMethodMin() \c HistoryCombinatorMethodMax() \c
/// HistoryCombinatorMethodMult() \c HistoryCombinatorMethodAverage()
- void setHistoryCombinatorMethod(ReliabilityType (*Meth)(ReliabilityType,
- ReliabilityType)) {
+ void setHistoryCombinatorMethod(
+ std::function<ReliabilityType(ReliabilityType, ReliabilityType)> Meth) {
HistoryCombinatorMethod = Meth;
}
/// sets the predefined method for the combination of the possible Identifiers
/// and the master \param Meth the method predefined ones are \c
/// FeedbackCombinatorMethodAverage() \c FeedbackCombinatorMethodMin() \c
/// FeedbackCombinatorMethodMax() \c FeedbackCombinatorMethodMult()
- void setFeedbackCombinatorMethod(std::vector<ConfOrRel> (*Meth)(
- std::vector<ConfOrRel>, std::vector<ConfOrRel>)) {
+ void setFeedbackCombinatorMethod(
+ std::function<std::vector<ConfOrRel>(std::vector<ConfOrRel>,
+ std::vector<ConfOrRel>)>
+ Meth) {
FeedbackCombinatorMethod = Meth;
}
/// Sets the used combination method for Possible Identifiers
/// \param Meth a Pointer for the used Method. Predefined methods \c
/// PossibleIdentifierCombinationMethodMin() \c
/// PossibleIdentifierCombinationMethodMax() \c
/// PossibleIdentifierCombinationMethodAverage()
void setPossibleIdentifierCombinationMethod(
- std::vector<ConfOrRel> (*Meth)(std::vector<ConfOrRel>, ReliabilityType)) {
+ std::function<std::vector<ConfOrRel>(std::vector<ConfOrRel>,
+ ReliabilityType)>
+ Meth) {
PossibleIdentifierCombinationMethod = Meth;
}
/// sets the input reliability combinator method
/// \param method the to be used method
/// \note there are predefined methods \c combinationMin() \c combinationMax()
/// \c combinationAverage()
void setInputReliabilityCombinator(
- ReliabilityType (*method)(ReliabilityType, ReliabilityType)) {
+ std::function<ReliabilityType(ReliabilityType, ReliabilityType)> method) {
InputReliabilityCombinator = method;
}
//
// ----------------predefined combinators------------------------------------
//
struct predefinedMethods {
/// predefined Method
static ReliabilityType HistoryCombinatorMethodMin(ReliabilityType A,
ReliabilityType B) {
return std::min(A, B);
}
/// predefined Method
static ReliabilityType HistoryCombinatorMethodMax(ReliabilityType A,
ReliabilityType B) {
return std::max(A, B);
}
/// predefined Method
static ReliabilityType HistoryCombinatorMethodMult(ReliabilityType A,
ReliabilityType B) {
return A * B;
}
/// predefined Method
static ReliabilityType HistoryCombinatorMethodAverage(ReliabilityType A,
ReliabilityType B) {
return (A + B) / 2;
}
/// predefined method
static std::vector<ConfOrRel>
FeedbackCombinatorMethodAverage(std::vector<ConfOrRel> A,
std::vector<ConfOrRel> B) {
- return average(A, B);
+ for (auto &tmp_me : A)
+ for (auto &tmp_other : B) {
+ if (tmp_me.Identifier == tmp_other.Identifier) {
+ tmp_me.Reliability =
+ (tmp_me.Reliability + tmp_other.Reliability) / 2;
+ }
+ }
+ return A;
}
/// predefined method
static std::vector<ConfOrRel>
FeedbackCombinatorMethodMin(std::vector<ConfOrRel> A,
std::vector<ConfOrRel> B) {
- return min(A, B);
+ for (auto &tmp_me : A)
+ for (auto &tmp_other : B) {
+ if (tmp_me.Identifier == tmp_other.Identifier) {
+ tmp_me.Reliability =
+ std::min(tmp_me.Reliability + tmp_other.Reliability);
+ }
+ }
+ return A;
}
/// predefined method
static std::vector<ConfOrRel>
FeedbackCombinatorMethodMax(std::vector<ConfOrRel> A,
std::vector<ConfOrRel> B) {
- return max(A, B);
+ for (auto &tmp_me : A)
+ for (auto &tmp_other : B) {
+ if (tmp_me.Identifier == tmp_other.Identifier) {
+ tmp_me.Reliability =
+ std::max(tmp_me.Reliability + tmp_other.Reliability);
+ }
+ }
+ return A;
}
/// predefined method
static std::vector<ConfOrRel>
FeedbackCombinatorMethodMult(std::vector<ConfOrRel> A,
std::vector<ConfOrRel> B) {
- return mult(A, B);
+ for (auto &tmp_me : A)
+ for (auto &tmp_other : B) {
+ if (tmp_me.Identifier == tmp_other.Identifier) {
+ tmp_me.Reliability = tmp_me.Reliability * tmp_other.Reliability;
+ }
+ }
+ return A;
}
/// Predefined combination method for possible Identifiers
static std::vector<ConfOrRel>
PossibleIdentifierCombinationMethodMin(std::vector<ConfOrRel> A,
ReliabilityType B) {
- return min(A, B);
+ for (auto tmp : A)
+ tmp.Reliability = std::min(tmp.Reliability, B);
+ return A;
}
/// Predefined combination method for possible Identifiers
static std::vector<ConfOrRel>
PossibleIdentifierCombinationMethodMax(std::vector<ConfOrRel> A,
ReliabilityType B) {
- return max(A, B);
+ for (auto tmp : A)
+ tmp.Reliability = std::max(tmp.Reliability, B);
+ return A;
}
/// Predefined combination method for possible Identifiers
static std::vector<ConfOrRel>
PossibleIdentifierCombinationMethodAverage(std::vector<ConfOrRel> A,
ReliabilityType B) {
- return average(A, B);
+ for (auto tmp : A)
+ tmp.Reliability = (tmp.Reliability + B) / 2;
+ return A;
}
/// Predefined combination method for possible Identifiers
static std::vector<ConfOrRel>
PossibleIdentifierCombinationMethodMult(std::vector<ConfOrRel> A,
ReliabilityType B) {
- return mult(A, B);
+ for (auto tmp : A)
+ tmp.Reliability = tmp.Reliability * B / 2;
+ return A;
}
/// The predefined min combinator method
static ReliabilityType combinationMin(ReliabilityType A,
ReliabilityType B) {
return std::min(A, B);
}
/// The predefined max combinator method
static ReliabilityType combinationMax(ReliabilityType A,
ReliabilityType B) {
return std::max(A, B);
}
/// The predefined average combinator method
static ReliabilityType combinationAverage(ReliabilityType A,
ReliabilityType B) {
return (A + B) / 2;
}
/// The predefined average combinator method
static ReliabilityType combinationMult(ReliabilityType A,
ReliabilityType B) {
return A * B;
}
};
// ----------------------------------------------------------------
// Stored Values
// ----------------------------------------------------------------
private:
std::vector<std::vector<ConfOrRel>> History;
std::size_t HistoryMaxSize;
std::vector<ConfOrRel> ValuesFromMaster;
SensorValueType previousSensorValue;
unsigned int valueSetCounter;
std::vector<IdentifierType> States;
bool PreviousSensorValueExists = false;
std::unique_ptr<
RangeConfidence<ReliabilityType, IdentifierType, 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;
// combination functions
- ReliabilityType (*InputReliabilityCombinator)(
- ReliabilityType, ReliabilityType) = predefinedMethods::combinationMin;
-
- std::vector<ConfOrRel> (*PossibleIdentifierCombinationMethod)(
- std::vector<ConfOrRel>, ReliabilityType) =
- predefinedMethods::PossibleIdentifierCombinationMethodMin;
-
- std::vector<ConfOrRel> (*FeedbackCombinatorMethod)(std::vector<ConfOrRel>,
- std::vector<ConfOrRel>) =
- predefinedMethods::FeedbackCombinatorMethodAverage;
-
- ReliabilityType (*HistoryCombinatorMethod)(ReliabilityType, ReliabilityType) =
- predefinedMethods::HistoryCombinatorMethodMax;
+ std::function<ReliabilityType(ReliabilityType, ReliabilityType)>
+ InputReliabilityCombinator = predefinedMethods::combinationMin;
+
+ std::function<std::vector<ConfOrRel>(std::vector<ConfOrRel>, ReliabilityType)>
+ PossibleIdentifierCombinationMethod =
+ predefinedMethods::PossibleIdentifierCombinationMethodMin;
+
+ std::function<std::vector<ConfOrRel>(std::vector<ConfOrRel>,
+ std::vector<ConfOrRel>)>
+ FeedbackCombinatorMethod =
+ predefinedMethods::FeedbackCombinatorMethodAverage;
+ std::function<ReliabilityType(ReliabilityType, ReliabilityType)>
+ HistoryCombinatorMethod = predefinedMethods::HistoryCombinatorMethodMax;
// ---------------------------------------------------------------------------
// needed Functions
// ---------------------------------------------------------------------------
/// 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
/// \brief it returns the combination the \c Reliability function and \c
/// ReliabilitySlope if the previous value exists. if it doesn't it only
/// returns the \c Reliability function value.
ReliabilityType getReliability(SensorValueType actualValue,
SensorValueType lastValue,
unsigned int valueSetCounter) {
ReliabilityType relAbs = Reliability->operator()(actualValue);
if (PreviousSensorValueExists) {
ReliabilityType relSlo = ReliabilitySlope->operator()(
(lastValue - actualValue) / (SensorValueType)valueSetCounter);
return InputReliabilityCombinator(relAbs, relSlo);
} else
return relAbs;
}
/// adapts the possible Identifiers by checking the History and combines those
/// values. currently with max
/// \brief combines the historic values with the \c TimeConfidence function
/// and returns the maximum Reliability for all Identifiers.
std::vector<ConfOrRel> getAllPossibleIdentifiersBasedOnHistory() {
// iterate through all history entries
std::size_t posInHistory = 0;
std::vector<ConfOrRel> possibleIdentifiers;
for (auto pShE = History.begin(); pShE < History.end();
pShE++, posInHistory++) {
// iterate through all possible Identifiers of each history entry
for (ConfOrRel &pSh : *pShE) {
IdentifierType historyIdentifier = pSh.Identifier;
ReliabilityType historyConf = pSh.Reliability;
historyConf = historyConf * TimeConfidence->operator()(posInHistory);
bool foundIdentifier = false;
for (ConfOrRel &pS : possibleIdentifiers) {
if (pS.Identifier == historyIdentifier) {
pS.Reliability =
HistoryCombinatorMethod(pS.Reliability, historyConf);
foundIdentifier = true;
}
}
if (foundIdentifier == false) {
ConfOrRel possibleIdentifier;
possibleIdentifier.Identifier = historyIdentifier;
possibleIdentifier.Reliability = historyConf;
possibleIdentifiers.push_back(possibleIdentifier);
}
}
}
return possibleIdentifiers;
}
/// saves the Identifiers in the History
/// \brief It checks the incoming Identifiers if any have a Reliability
/// greater than 0.5 all of them get saved inside the History and then the
/// History get shortened to the maximal length. It only saves the Value if
/// the History is empty.
///
/// \param actualPossibleIdentifiers The Identifiers which should be saved
///
/// \note Does the History really make sense if the values are to small it
/// only stores something if it's empty and not if it isn't completely filled
void saveInHistory(std::vector<ConfOrRel> actualPossibleIdentifiers) {
// check if the reliability of at least one possible Identifier is high
// enough
bool atLeastOneRelIsHigh = false;
for (ConfOrRel pS : actualPossibleIdentifiers) {
if (pS.Reliability > 0.5) {
atLeastOneRelIsHigh = true;
}
}
// save possible Identifiers if at least one possible Identifier is high
// enough (or if the history is empty)
if (History.size() < 1 || atLeastOneRelIsHigh == true) {
History.insert(History.begin(), actualPossibleIdentifiers);
// if history size is higher than allowed, save oldest element
while (History.size() > HistoryMaxSize) {
// delete possibleIdentifierHistory.back();
History.pop_back();
}
}
}
};
} // namespace agent
} // namespace rosa
#endif // !ROSA_AGENT_ReliabilityConfidenceCombinator_H

File Metadata

Mime Type
text/x-diff
Expires
Thu, Jul 3, 4:05 AM (1 d, 6 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
157181
Default Alt Text
(70 KB)

Event Timeline