Page MenuHomePhorge

No OneTemporary

Size
16 KB
Referenced Files
None
Subscribers
None
diff --git a/include/rosa/agent/State.hpp b/include/rosa/agent/State.hpp
index 99365de..ef5b85a 100644
--- a/include/rosa/agent/State.hpp
+++ b/include/rosa/agent/State.hpp
@@ -1,165 +1,179 @@
//===-- 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;
/// 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
};
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 StateIsValidAfterReentrance shows whether a state is valid after the
/// variable changed back to it again.
bool StateIsValidAfterReentrance;
};
// TODO (1/2): change name of DABSTORETYPE to something else
/// \tparam INDATATYPE type of input data, \tparam DABSTORETYPE type of data
/// in which DABs are saved,
template <typename INDATATYPE, typename DABSTORETYPE>
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<DABSTORETYPE>::value),
"DAB storage type is not to arithmetic");
private:
+ // For the convinience to write a shorter data type name
using partFuncPointer =
std::shared_ptr<PartialFunction<INDATATYPE, DABSTORETYPE>>;
-
// TODO (2/2): because here, DABSTORETYPE makes no sense
- StateInformation<DABSTORETYPE> StateInfo;
+ using stateInfoPtr = std::shared_ptr<StateInformation<DABSTORETYPE>>;
+
+ stateInfoPtr StateInfo;
partFuncPointer PartialFunctionSampleMatches;
partFuncPointer PartialFunctionSampleMismatches;
partFuncPointer PartialFunctionNumOfSamplesMatches;
partFuncPointer PartialFunctionNumOfSamplesMismatches;
DynamicLengthHistory<INDATATYPE, HistoryPolicy::FIFO> SampleHistory;
DynamicLengthHistory<INDATATYPE, HistoryPolicy::SRWF> DAB;
DynamicLengthHistory<DABSTORETYPE, 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:
State(partFuncPointer PartialFunctionSampleMatches,
partFuncPointer PartialFunctionSampleMismatches,
partFuncPointer PartialFunctionNumOfSamplesMatches,
partFuncPointer PartialFunctionNumOfSamplesMismatches,
unsigned int sampleHistorySize, unsigned int DABSize,
unsigned int DABHistorySize) noexcept
: SampleHistory(sampleHistorySize), DAB(DABSize),
DABHistory(DABHistorySize),
PartialFunctionSampleMatches(PartialFunctionSampleMatches),
PartialFunctionSampleMismatches(PartialFunctionSampleMismatches),
PartialFunctionNumOfSamplesMatches(PartialFunctionNumOfSamplesMatches),
PartialFunctionNumOfSamplesMismatches(
PartialFunctionNumOfSamplesMismatches) {
/*
StateIsValid = false;
StateIsValidAfterReentrance = false;
*/
}
/// Destroys \p this object.
~State(void) = default;
void leaveState(void) {
DAB.clear();
StateIsValidAfterReentrance = false;
}
bool insertSample(INDATATYPE Sample) {
bool workedForAll; // maybe ignor that //auc hnicht abchecken einfach kübeln
workedForAll = SampleHistory.addEntry(Sample);
// QUESTION: is it important to have this flag (workedForAll). What should I
// do if it does not work at some point?
if (workedForAll) {
workedForAll &= DAB.addEntry(Sample);
if (workedForAll) {
if (DAB.full()) {
DABSTORETYPE AvgOfDAB = DAB.average<DABSTORETYPE>();
workedForAll &= DABHistory.addEntry(AvgOfDAB);
if (workedForAll) {
DAB.clear();
} // QUESTION: - what should be done if it has not worked?
}
if (workedForAll) {
// TODO: calculate whether state is valid
+
+ // TODO: check actual state whether it drifts
+ // TODO: write in StateInfo
}
}
}
return workedForAll;
}
DABSTORETYPE confSampleMatchesState(INDATATYPE sample) {}
DABSTORETYPE confSampleMismatchesState(INDATATYPE sample) {}
// unsigned int stateId(void) { return StateId; }
+ /// 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;
+ }
};
} // 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 18486d5..052a60e 100644
--- a/include/rosa/agent/StateDetector.hpp
+++ b/include/rosa/agent/StateDetector.hpp
@@ -1,226 +1,232 @@
//===-- 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 detection* *functionality*.
+/// \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 =
std::shared_ptr<PartialFunction<INDATATYPE, CONFTYPE>>;
using statePtr = std::shared_ptr<StateInformation<CONFTYPE>>;
using stateInfoPtr = std::shared_ptr<StateInformation<CONFTYPE>>;
/// 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;
/// The DetectedStates is vector in that all detected states are saved.
std::vector<statePtr> DetectedStates;
/// The PartialFunctionSampleMatches 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
/// convidence how bad the new sample matches another sample in the sample
/// history.
partFuncPointer PartialFunctionSampleMismatches;
/// The PartialFunctionSampleMatches 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
/// convidence how many samples from the sampe history mismatch the new
/// sample.
partFuncPointer PartialFunctionNumOfSamplesMismatches;
/// 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,
unsigned int SampleHistorySize, unsigned int DABSize,
unsigned int DABHistorySize) noexcept
: StateHasChanged(false), CurrentState(NULL),
PartialFunctionSampleMatches(PartialFunctionSampleMatches),
PartialFunctionSampleMismatches(PartialFunctionSampleMismatches),
PartialFunctionNumOfSamplesMatches(PartialFunctionNumOfSamplesMatches),
PartialFunctionNumOfSamplesMismatches(
PartialFunctionNumOfSamplesMismatches),
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
///
/// \return the information of the actual state (state ID and other
/// parameters)
stateInfoPtr detectState(INDATATYPE Sample) {
if (CurrentState == NULL) {
ASSERT(DetectedStates.empty());
statePtr S = createNewState();
if (S) {
CurrentState = S;
} else {
- // TODO: handle (or at least log) if now state could be created
+ // TODO: handle (or at least log) if now state could be created.
+ // However, this handling/logging could be also done in
+ // createNewState().
}
} else {
CONFTYPE ConfidenceSampleMatchesState =
CurrentState->confSampleMatchesState(Sample);
CONFTYPE ConfidenceSampleMismatchesState =
CurrentState->confSampleMismatchesState(Sample);
if (ConfidenceSampleMatchesState > ConfidenceSampleMismatchesState) {
StateHasChanged = false;
} else {
StateHasChanged = true;
- // TODO: check whether ActiveState is valid
-
- // TODO: if invalid -> deleteState (einfach pop weil shared pointer)
- // a.erase(std::find(a.begin(),a.end(),2));
- // TODO: else leaveState
+ if (CurrentState->stateInformation()->StateIsValid) {
+ leaveState();
+ } else {
+ DetectedStates.erase(std::find(DetectedStates.begin(),
+ DetectedStates.end(), CurrentState));
+ }
- // TODO FAR AWAY FUTURE: additionally save averages to enable fast
- // iteration through recorded state vector
- //- maybe sort vector based on these average values
+ // TODO (future): additionally save averages to enable fast
+ // iteration through recorded state vector (maybe sort vector based on
+ // these average values)
CurrentState = NULL;
for (auto &SavedState : DetectedStates) {
-
if (SavedState != CurrentState) {
CONFTYPE ConfidenceSampleMatchesState =
SavedState->confSampleMatchesState(Sample);
CONFTYPE ConfidenceSampleMismatchesState =
SavedState->confSampleMismatchesState(Sample);
if (ConfidenceSampleMatchesState >
ConfidenceSampleMismatchesState) {
-
- // QUESTION: maybe it would be better to compare
- // ConfidenceSampleMatchesState
- // of all states in the vector
+ // 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;
-
- } // QUESTION: should there an output (log) when it was not
- // successfull?
+ } else {
+ // TODO: handle (or at least log) if now state could be created.
+ // However, this handling/logging could be also done in
+ // createNewState().
+ }
}
}
}
CurrentState->insertSample(Sample);
- // TODO: check actual state whether it drifts
- // TODO: write in StateInfo
+ return CurrentState->stateInfo();
+ }
+ /// Gives information about the current state.
+ ///
+ /// \return a struct StateInformation that contains information about the
+ /// current state.
+ stateInfoPtr currentStateInformation(void) {
+ // TODO: check what happens when currentStateInformation(void) is called in
+ // the beginning when no state has recognized at all.
return CurrentState->stateInfo();
}
+ /// 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; }
- bool stateIsUnchanged(void) { return !StateHasChanged; }
-
- // TODO: get confidences, get drift/stable get, get active state number,
- // TODO: maybe just return struct with everything
-
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;
} 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:16 PM (9 h, 4 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
157366
Default Alt Text
(16 KB)

Event Timeline