Page MenuHomePhorge

No OneTemporary

Size
23 KB
Referenced Files
None
Subscribers
None
diff --git a/include/rosa/agent/State.hpp b/include/rosa/agent/State.hpp
index 9675d62..39ef8af 100644
--- a/include/rosa/agent/State.hpp
+++ b/include/rosa/agent/State.hpp
@@ -1,230 +1,243 @@
//===-- rosa/agent/State.hpp ----------------------------*- C++ -*-===//
//
// The RoSA Framework
//
//===----------------------------------------------------------------------===//
///
/// \file rosa/agent/State.hpp
///
/// \author Maximilian Götzinger (maximilian.goetzinger@tuwien.ac.at)
///
/// \date 2019
///
/// \brief Definition of *state* *functionality*.
///
//===----------------------------------------------------------------------===//
#ifndef ROSA_AGENT_STATE_HPP
#define ROSA_AGENT_STATE_HPP
#include "rosa/agent/FunctionAbstractions.hpp"
#include "rosa/agent/Functionality.h"
#include "rosa/agent/History.hpp"
namespace rosa {
namespace agent {
-// QUESTION: I would like to define the variable nextID as static variable
-// inside the struct or the class but it is not possible because I cannot define
-// it there (initialize it with 0) because "no const variable". However, using a
-// global variable is not that nice in my opinion.
-unsigned int nextID = 0;
-
+// TODO: think about call it VariableStateInformation
/// State conditions defining how the condition of a \c rosa::agent::State is
/// saved in \c rosa::agent::StateInformation.
enum class StateCondition {
STABLE, ///< The state is stable
DRIFTING, ///< The state is drifting
UNKNOWN ///< The state is unknown
};
template <typename CONFTYPE> struct StateInformation {
// Make sure the actual type arguments are matching our expectations.
STATIC_ASSERT((std::is_arithmetic<CONFTYPE>::value),
"confidence type is not to arithmetic");
/// The state ID saved as an unsigned integer number
unsigned int StateID;
/// The StateConfidence shows the overall confidence value of the state.
CONFTYPE StateConfidence;
/// The StateCondition shows the condition of a state (stable or drifting)
StateCondition StateCondition;
/// The StateIsValid shows whether a state is valid or invalid. In this
/// context, valid means that enough samples which are in close proximitry
/// have been inserted into the state.
bool StateIsValid;
+ /// The StateJustGotValid shows whether a state got valid (toggled from
+ /// invalid to valid) during the current inserted sample.
+ bool StateJustGotValid;
/// The StateIsValidAfterReentrance shows whether a state is valid after the
/// variable changed back to it again.
bool StateIsValidAfterReentrance;
};
-// TODO: check whethter name of CONFTYPE is good for each context here
+// TODO: check whethter name of CONFTYPE is good for each context here -> mach
+// einen dritten datatype
/// \tparam INDATATYPE type of input data, \tparam CONFTYPE is type of
/// data in that the confidence values are given. It is also the type of data
/// in which DABs are saved,
template <typename INDATATYPE, typename CONFTYPE>
class State : public Functionality {
// Make sure the actual type arguments are matching our expectations.
STATIC_ASSERT((std::is_arithmetic<INDATATYPE>::value),
"input data type not arithmetic");
STATIC_ASSERT((std::is_arithmetic<CONFTYPE>::value),
"DAB storage type is not to arithmetic");
private:
// For the convinience to write a shorter data type name
- using partFuncPointer =
+ using PartFuncPointer =
std::shared_ptr<PartialFunction<INDATATYPE, CONFTYPE>>;
- using stateInfoPtr = std::shared_ptr<StateInformation<CONFTYPE>>;
+ using StateInfoPtr = std::shared_ptr<StateInformation<CONFTYPE>>;
- stateInfoPtr StateInfo;
+ StateInfoPtr StateInfo;
- partFuncPointer PartialFunctionSampleMatches;
- partFuncPointer PartialFunctionSampleMismatches;
- partFuncPointer PartialFunctionNumOfSamplesMatches;
- partFuncPointer PartialFunctionNumOfSamplesMismatches;
+ // TODO: rename fuzzy function
+ PartFuncPointer PartialFunctionSampleMatches;
+ PartFuncPointer PartialFunctionSampleMismatches;
+ std::shared_ptr<StepFunction<INDATATYPE, CONFTYPE>>
+ StepFunctionNumOfSamplesMatches;
+ std::shared_ptr<StepFunction<INDATATYPE, CONFTYPE>>
+ StepFunctionNumOfSamplesMismatches;
+ // TODO: partFunc Drift, NoDrift
DynamicLengthHistory<INDATATYPE, HistoryPolicy::FIFO> SampleHistory;
DynamicLengthHistory<INDATATYPE, HistoryPolicy::SRWF> DAB;
DynamicLengthHistory<CONFTYPE, HistoryPolicy::LIFO> DABHistory;
/// The StateIsValid shows whether a state is valid or invalid. In this
/// context, valid means that enough samples which are in close proximitry
/// have been inserted into the state.
bool StateIsValid;
/// The StateIsValidAfterReentrance shows whether a state is valid after the
/// variable changed back to it again.
bool StateIsValidAfterReentrance;
public:
/// Creates an instance by setting all parameters
- State(partFuncPointer PartialFunctionSampleMatches,
- partFuncPointer PartialFunctionSampleMismatches,
- partFuncPointer PartialFunctionNumOfSamplesMatches,
- partFuncPointer PartialFunctionNumOfSamplesMismatches,
+ State(unsigned int StateID, PartFuncPointer PartialFunctionSampleMatches,
+ PartFuncPointer PartialFunctionSampleMismatches,
+ std::shared_ptr<StepFunction<INDATATYPE, CONFTYPE>>
+ StepFunctionNumOfSamplesMatches,
+ std::shared_ptr<StepFunction<INDATATYPE, CONFTYPE>>
+ StepFunctionNumOfSamplesMismatches,
unsigned int sampleHistorySize, unsigned int DABSize,
unsigned int DABHistorySize) noexcept
- : StateInfo(nextID, 0, StateCondition::UNKNOWN, false, false),
+ : StateInfo(StateID, 0, StateCondition::UNKNOWN, false, false),
SampleHistory(sampleHistorySize), DAB(DABSize),
DABHistory(DABHistorySize),
PartialFunctionSampleMatches(PartialFunctionSampleMatches),
PartialFunctionSampleMismatches(PartialFunctionSampleMismatches),
- PartialFunctionNumOfSamplesMatches(PartialFunctionNumOfSamplesMatches),
- PartialFunctionNumOfSamplesMismatches(
- PartialFunctionNumOfSamplesMismatches) {}
+ StepFunctionNumOfSamplesMatches(StepFunctionNumOfSamplesMatches),
+ StepFunctionNumOfSamplesMismatches(StepFunctionNumOfSamplesMismatches) {
+ }
/// Destroys \p this object.
~State(void) = default;
void leaveState(void) {
DAB.clear();
StateIsValidAfterReentrance = false;
}
+ // TODO: maybe return immediatly StateInfo
void insertSample(INDATATYPE Sample) {
// TODO: think about some error handling in case of not beeing able to add
// an entry or create a new object
SampleHistory.addEntry(Sample);
DAB.addEntry(Sample);
if (DAB.full()) {
- CONFTYPE AvgOfDAB = DAB.average<CONFTYPE>();
+ CONFTYPE AvgOfDAB = DAB.template average<CONFTYPE>();
DABHistory.addEntry(AvgOfDAB);
DAB.clear();
}
- // TODO: calculate whether state is valid
+ //@Benedikt: stepfunction auch andere richtung
+ StepFunctionNumOfSamplesMatches->setRightLimit(
+ SampleHistory->numberOfEntries());
+ StepFunctionNumOfSamplesMismatches->setRightLimit(
+ SampleHistory->numberOfEntries());
+
+ // TODO: calculate whether state is valid and properly set StateIsValid,
+ // StateJustGotValid, StateIsValidAfterReentrance
// TODO: check actual state whether it drifts
+
// TODO: write in StateInfo
}
// TODO: check this function again
CONFTYPE
confSampleMatchesState(INDATATYPE sample) {
CONFTYPE RelDiff;
CONFTYPE HighestConf = 0;
// QUESTION: should I also use a history (array) for that?
std::vector<CONFTYPE> RelDiffHistValuesAndSampleValue;
for (auto &hs : SampleHistory) {
RelDiff = relativeDifference(sample, hs);
RelDiffHistValuesAndSampleValue.push_back(RelDiff);
}
sort(begin(RelDiffHistValuesAndSampleValue),
end(RelDiffHistValuesAndSampleValue));
+ // TODO (future): to accelerate -> don't start with 1
for (unsigned int numOfHistSamplesIncluded = 1;
numOfHistSamplesIncluded <= RelDiffHistValuesAndSampleValue.size();
numOfHistSamplesIncluded++) {
CONFTYPE LowestConfOfSamplesIncluded = 1;
unsigned int HistSampleCounter = 0;
for (auto &D : RelDiffHistValuesAndSampleValue) {
if (HistSampleCounter >= numOfHistSamplesIncluded)
break;
CONFTYPE confRelDiff;
// TODO: check if infinity check is needed here?
if (std::isinf(D) == false) {
- confRelDiff = PartialFunctionSampleMatches->getY(D);
+ confRelDiff = PartialFunctionSampleMatches(D);
} else {
confRelDiff = 0;
}
- // std::min is equal to Fuzzy AND
+ // std::min is equal to Fuzzy AND -> maybe using
LowestConfOfSamplesIncluded =
std::min(LowestConfOfSamplesIncluded, confRelDiff);
HistSampleCounter++;
}
// std::max is equal to Fuzzy OR
- HighestConf = std::max(HighestConf,
- std::max(LowestConfOfSamplesIncluded,
- PartialFunctionNumOfSamplesMatches->getY(
- (CONFTYPE)HistSampleCounter)));
+ HighestConf =
+ std::max(HighestConf, std::max(LowestConfOfSamplesIncluded,
+ StepFunctionNumOfSamplesMatches(
+ (CONFTYPE)HistSampleCounter)));
}
}
CONFTYPE
confSampleMismatchesState(INDATATYPE sample) {
// TODO: do it in the same way as confSampleMatchesState(INDATATYPE sample)
}
/// Gives information about the current state.
///
/// \return a struct StateInformation that contains information about the
/// current state.
- stateInfoPtr stateInformation(void) {
- // TODO: check what happens when currentStateInformation(void) is called in
- // the beginning when no state has recognized at all.
- return StateInfo;
- }
+ StateInfoPtr stateInformation(void) { return StateInfo; }
private:
// QUESTION: is such a function already implemented? If not where should put
// this function?
+ // TODO: rename in distance
+ // TODO: ask david where to move that
CONFTYPE relativeDifference(INDATATYPE SampleValue, INDATATYPE HistoryValue) {
CONFTYPE Diff = HistoryValue - SampleValue;
if (Diff == 0) {
return 0;
} else {
Diff = Diff / SampleValue;
if (Diff < 0) {
Diff = Diff * (-1);
}
return (Diff);
}
}
};
} // End namespace agent
} // End namespace rosa
#endif // ROSA_AGENT_STATE_HPP
diff --git a/include/rosa/agent/StateDetector.hpp b/include/rosa/agent/StateDetector.hpp
index 9b9182b..7f31f53 100644
--- a/include/rosa/agent/StateDetector.hpp
+++ b/include/rosa/agent/StateDetector.hpp
@@ -1,234 +1,267 @@
//===-- rosa/agent/StateDetector.hpp ----------------------------*- C++ -*-===//
//
// The RoSA Framework
//
//===----------------------------------------------------------------------===//
///
/// \file rosa/agent/StateDetector.hpp
///
/// \author Maximilian Götzinger (maximilian.goetzinger@tuwien.ac.at)
///
/// \date 2019
///
/// \brief Definition of *state detector* *functionality*.
///
//===----------------------------------------------------------------------===//
#ifndef ROSA_AGENT_STATEDETECTOR_HPP
#define ROSA_AGENT_STATEDETECTOR_HPP
#include "rosa/agent/FunctionAbstractions.hpp"
#include "rosa/agent/Functionality.h"
#include "rosa/agent/State.hpp"
#include <vector>
namespace rosa {
namespace agent {
/// Implements \c rosa::agent::StateDetector as a functionality that detects
/// states given on input samples.
///
/// \note This implementation is supposed to be used for samples of an
/// arithmetic type.
///
/// \tparam INDATATYPE is the type of input data, \tparam CONFTYPE is type of
/// data in that the confidence values are given
template <typename INDATATYPE, typename CONFTYPE>
class StateDetector : public Functionality {
// Make sure the actual type arguments are matching our expectations.
STATIC_ASSERT((std::is_arithmetic<INDATATYPE>::value),
"input data type not arithmetic");
STATIC_ASSERT((std::is_arithmetic<CONFTYPE>::value),
"confidence abstraction type is not to arithmetic");
private:
// For the convinience to write a shorter data type name
- using partFuncPointer =
+ using PartFuncPointer =
std::shared_ptr<PartialFunction<INDATATYPE, CONFTYPE>>;
- using statePtr = std::shared_ptr<StateInformation<CONFTYPE>>;
- using stateInfoPtr = std::shared_ptr<StateInformation<CONFTYPE>>;
+ using StatePtr = std::shared_ptr<StateInformation<CONFTYPE>>;
+ using StateInfoPtr = std::shared_ptr<StateInformation<CONFTYPE>>;
+
+ /// The NextStateID is a counter variable which stores the ID which the next
+ /// state shall have.
+ unsigned int NextStateID;
/// The StateHasChanged is a flag that show whether a state change has
/// happened.
bool StateHasChanged;
/// The CurrentState is a pointer to the (saved) state in which the actual
/// variable (signal) of the observed system is.
- std::shared_ptr<statePtr> CurrentState;
+ StatePtr CurrentState;
/// The DetectedStates is vector in that all detected states are saved.
- std::vector<statePtr> DetectedStates;
+ std::vector<StatePtr> DetectedStates;
- /// The PartialFunctionSampleMatches is the fuzzy function that gives the
+ /// The FuzzyFunctionSampleMatches is the fuzzy function that gives the
/// convidence how good the new sample matches another sample in the sample
/// history.
- partFuncPointer PartialFunctionSampleMatches;
- /// The PartialFunctionSampleMatches is the fuzzy function that gives the
+ PartFuncPointer FuzzyFunctionSampleMatches;
+ /// The FuzzyFunctionSampleMatches is the fuzzy function that gives the
/// convidence how bad the new sample matches another sample in the sample
/// history.
- partFuncPointer PartialFunctionSampleMismatches;
- /// The PartialFunctionSampleMatches is the fuzzy function that gives the
+ PartFuncPointer FuzzyFunctionSampleMismatches;
+ /// The FuzzyFunctionSampleMatches is the fuzzy function that gives the
/// convidence how many samples from the sampe history match the new sample.
- partFuncPointer PartialFunctionNumOfSamplesMatches;
- /// The PartialFunctionSampleMatches is the fuzzy function that gives the
+ PartFuncPointer FuzzyFunctionNumOfSamplesMatches;
+ /// The FuzzyFunctionSampleMatches is the fuzzy function that gives the
/// convidence how many samples from the sampe history mismatch the new
/// sample.
- partFuncPointer PartialFunctionNumOfSamplesMismatches;
+ PartFuncPointer FuzzyFunctionNumOfSamplesMismatches;
/// SampleHistorySize is the (maximum) size of the sample history.
unsigned int SampleHistorySize;
/// DABSize the size of a DAB (Discrete Average Block).
unsigned int DABSize;
/// DABHistorySize is the (maximum) size of the DAB history.
unsigned int DABHistorySize;
public:
/// Creates an instance by setting all parameters
- StateDetector(partFuncPointer PartialFunctionSampleMatches,
- partFuncPointer PartialFunctionSampleMismatches,
- partFuncPointer PartialFunctionNumOfSamplesMatches,
- partFuncPointer PartialFunctionNumOfSamplesMismatches,
+ StateDetector(PartFuncPointer FuzzyFunctionSampleMatches,
+ PartFuncPointer FuzzyFunctionSampleMismatches,
+ PartFuncPointer FuzzyFunctionNumOfSamplesMatches,
+ PartFuncPointer FuzzyFunctionNumOfSamplesMismatches,
unsigned int SampleHistorySize, unsigned int DABSize,
unsigned int DABHistorySize) noexcept
- : StateHasChanged(false), CurrentState(NULL),
- PartialFunctionSampleMatches(PartialFunctionSampleMatches),
- PartialFunctionSampleMismatches(PartialFunctionSampleMismatches),
- PartialFunctionNumOfSamplesMatches(PartialFunctionNumOfSamplesMatches),
- PartialFunctionNumOfSamplesMismatches(
- PartialFunctionNumOfSamplesMismatches),
+ : NextStateID(1), StateHasChanged(false), CurrentState(NULL),
+ FuzzyFunctionSampleMatches(FuzzyFunctionSampleMatches),
+ FuzzyFunctionSampleMismatches(FuzzyFunctionSampleMismatches),
+ FuzzyFunctionNumOfSamplesMatches(FuzzyFunctionNumOfSamplesMatches),
+ FuzzyFunctionNumOfSamplesMismatches(
+ FuzzyFunctionNumOfSamplesMismatches),
SampleHistorySize(SampleHistorySize), DABSize(DABSize),
DABHistorySize(DABHistorySize) {}
/// Destroys \p this object.
~StateDetector(void) = default;
/// Detects the state to which the new sample belongs or create a new state if
/// the new sample does not match to any of the saved states.
///
- /// \param Sample
+ /// \param Sample is the actual sample of the observed signal.
+ ///
+ /// \return the state ID as unsigend integer type. State IDs start with number
+ /// 1; that means if there is no current state, the return value is 0.
+ unsigned int detectState(INDATATYPE Sample) {
+ StateInfoPtr StateInfo = detectState__debug(Sample);
+ return StateInfo->StateID;
+ }
+
+ /// Gives information about the current state.
+ ///
+ /// \return a the State ID (as unsigned integer type) of the current state.
+ /// State IDs start with number 1; that means if there is no current state,
+ /// the return value is 0.
+ unsigned int currentStateInformation(void) {
+ StateInfoPtr StateInfo = currentStateInformation__debug();
+ if (StateInfo) {
+ return StateInfo->StateID;
+ } else {
+ return 0;
+ }
+ }
+
+ /// Gives information whether a state change has happened or not.
+ ///
+ /// \return true if a state change has happened, and false if not.
+ bool stateHasChanged(void) { return StateHasChanged; }
+
+private:
+ /// Creates a new state and adds this state to the state vector in which all
+ /// known states are saved.
+ ///
+ /// \param SampleHistorySize the (maximum) size of the sample history.
+ /// \param DABSize the size of a DAB.
+ /// \param DABHistorySize the (maximum) size of the DAB history.
+ /// \param FuzzyFunctionSampleMatches the
+ /// \param FuzzyFunctionSampleMismatches
+ /// \param FuzzyFunctionNumOfSamplesMatches
+ /// \param FuzzyFunctionNumOfSamplesMismatches
+ ///
+ /// \return the new created state or NULL if no state could be created.
+ StatePtr createNewState(void) {
+
+ StatePtr S = new (std::nothrow) State(
+ SampleHistorySize, DABSize, DABHistorySize, FuzzyFunctionSampleMatches,
+ FuzzyFunctionSampleMismatches, FuzzyFunctionNumOfSamplesMatches,
+ FuzzyFunctionNumOfSamplesMismatches);
+
+ // TODO: maybe assert which checks if push_back worked (ask benedikt)
+ DetectedStates.push_back(S);
+
+ return S;
+ }
+
+#ifdef STATEDETECTORDEBUGMODE
+public:
+#else
+private:
+#endif // STATEDETECTORDEBUGMODE
+
+ /// Detects the state to which the new sample belongs or create a new state if
+ /// the new sample does not match to any of the saved states.
+ ///
+ /// \param Sample is the actual sample of the observed signal.
///
/// \return the information of the actual state (state ID and other
- /// parameters)
- stateInfoPtr detectState(INDATATYPE Sample) {
+ /// parameters).
+ // TODO: return something const.. cannot remember exactly (ask benedikt)
+ StateInfoPtr detectState__debug(INDATATYPE Sample) {
- if (CurrentState == NULL) {
+ if (!CurrentState) {
ASSERT(DetectedStates.empty());
- statePtr S = createNewState();
- if (S) {
- CurrentState = S;
- } else {
- // TODO: handle (or at least log) if now state could be created.
- // However, this handling/logging could be also done in
- // createNewState().
- }
+ StatePtr S = createNewState();
+ CurrentState = S;
} else {
CONFTYPE ConfidenceSampleMatchesState =
CurrentState->confSampleMatchesState(Sample);
CONFTYPE ConfidenceSampleMismatchesState =
CurrentState->confSampleMismatchesState(Sample);
if (ConfidenceSampleMatchesState > ConfidenceSampleMismatchesState) {
StateHasChanged = false;
} else {
StateHasChanged = true;
if (CurrentState->stateInformation()->StateIsValid) {
CurrentState->leaveState();
} else {
DetectedStates.erase(std::find(DetectedStates.begin(),
DetectedStates.end(), CurrentState));
}
// TODO (future): additionally save averages to enable fast
// iteration through recorded state vector (maybe sort vector based on
// these average values)
- CurrentState = NULL;
+ CurrentState = nullptr;
for (auto &SavedState : DetectedStates) {
if (SavedState != CurrentState) {
CONFTYPE ConfidenceSampleMatchesState =
SavedState->confSampleMatchesState(Sample);
CONFTYPE ConfidenceSampleMismatchesState =
SavedState->confSampleMismatchesState(Sample);
if (ConfidenceSampleMatchesState >
ConfidenceSampleMismatchesState) {
// TODO (future): maybe it would be better to compare
// ConfidenceSampleMatchesState of all states in the vector in
// order to find the best matching state.
CurrentState = SavedState;
break;
}
}
}
if (!CurrentState) {
- if (statePtr S = createNewState()) {
- CurrentState = S;
- } else {
- // TODO: handle (or at least log) if now state could be created.
- // However, this handling/logging could be also done in
- // createNewState().
- }
+ StatePtr S = createNewState();
+ CurrentState = S;
}
}
}
- CurrentState->insertSample(Sample);
+ StateInfoPtr StateInfo = CurrentState->insertSample(Sample);
+
+ if (StateInfo->StateJustGotValid) {
+ NextStateID++;
+ }
- return CurrentState->stateInfo();
+ return CurrentState->stateInformation();
}
+#ifdef STATEDETECTORDEBUGMODE
+public:
+#else
+private:
+#endif // STATEDETECTORDEBUGMODE
+
/// Gives information about the current state.
///
/// \return a struct StateInformation that contains information about the
/// current state or NULL if no current state exists.
- stateInfoPtr currentStateInformation(void) {
+ StateInfoPtr currentStateInformation__debug(void) {
if (CurrentState) {
- return CurrentState->stateInfo();
- } else {
- return NULL;
- }
- }
-
- /// Gives information whether a state change has happened or not.
- ///
- /// \return true if a state change has happened, and false if not.
- bool stateHasChanged(void) { return StateHasChanged; }
-
-private:
- /// Creates a new state and adds this state to the state vector in which all
- /// known states are saved.
- ///
- /// \param SampleHistorySize the (maximum) size of the sample history.
- /// \param DABSize the size of a DAB.
- /// \param DABHistorySize the (maximum) size of the DAB history.
- /// \param PartialFunctionSampleMatches the
- /// \param PartialFunctionSampleMismatches
- /// \param PartialFunctionNumOfSamplesMatches
- /// \param PartialFunctionNumOfSamplesMismatches
- ///
- /// \return the new created state or NULL if no state could be created.
- statePtr createNewState(void) {
-
- statePtr S = new (std::nothrow)
- State(SampleHistorySize, DABSize, DABHistorySize,
- PartialFunctionSampleMatches, PartialFunctionSampleMismatches,
- PartialFunctionNumOfSamplesMatches,
- PartialFunctionNumOfSamplesMismatches);
-
- if (S) {
- DetectedStates.push_back(S);
- return S;
+ return CurrentState->stateInformation();
} else {
return NULL;
}
}
};
} // End namespace agent
} // End namespace rosa
#endif // ROSA_AGENT_STATEDETECTOR_HPP

File Metadata

Mime Type
text/x-diff
Expires
Thu, Jul 3, 10:24 PM (9 h, 4 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
157380
Default Alt Text
(23 KB)

Event Timeline