diff --git a/include/rosa/agent/State.hpp b/include/rosa/agent/State.hpp index 709824b..2d926c2 100644 --- a/include/rosa/agent/State.hpp +++ b/include/rosa/agent/State.hpp @@ -1,128 +1,130 @@ //===-- 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/Functionality.h" #include "rosa/agent/History.hpp" + + + namespace rosa { namespace agent { + +using PartFuncPointer = std::shared_ptr>; /// \tparam DIN type of data of input, \tparam DDAB type of data in which DABs are saved, -/// \tparam DOUT type of data of abstracted value -template class State : public Functionality { +template class State : public Functionality { private: - unsigned int StateId; + unsigned int StateId; + + //counter static und nur raufzählen, wenn sprung von invalid auf valid DynamicHistory SampleHistory; DynamicHistory DAB; DynamicHistory DABHistory; - std::shared_ptr> PartialFunctionSampleMatches; - std::shared_ptr> PartialFunctionSampleMismatches; - std::shared_ptr> PartialFunctionNumOfSamplesMatches; - std::shared_ptr> PartialFunctionNumOfSamplesMismatches; + PartFuncPointer PartialFunctionSampleMatches; + PartFuncPointer PartialFunctionSampleMismatches; + PartFuncPointer PartialFunctionNumOfSamplesMatches; + PartFuncPointer PartialFunctionNumOfSamplesMismatches; bool StateIsValid; bool StateIsValidAfterReentrance; public: State(unsigned int StateId, unsigned int sampleHistorySize, unsigned int DABSize, - unsigned int DABHistorySize, PartialFunction* PartialFunctionSampleMatches, + unsigned int DABHistorySize, PartFuncPointer PartialFunctionSampleMatches, PartialFunction* PartialFunctionSampleMismatches, PartialFunction* PartialFunctionNumOfSamplesMatches, PartialFunction* PartialFunctionNumOfSamplesMismatches) noexcept : SampleHistory(sampleHistorySize), DAB(DABSize), DABHistory(DABHistorySize) { - this->StateId = StateId; + this->StateId = StateId; //TODO: oben machen this->PartialFunctionSampleMatches = PartialFunctionSampleMatches; this->PartialFunctionSampleMismatches = PartialFunctionSampleMismatches; this->PartialFunctionNumOfSamplesMatches = PartialFunctionNumOfSamplesMatches; this->PartialFunctionNumOfSamplesMismatches = PartialFunctionNumOfSamplesMismatches; StateIsValid = false; StateIsValidAfterReentrance = false; } //TODO: static assert -> check: // 1) if DIN == arithmetic, - // 2) if DDAB == float, double, ...? - // 3) output could be arithemtic or char/string, right? + // 2) if DDAB == float, double, ...? (vielleicht annäherung mit int) ~State(void) = default; void leaveState(void) { - //QUESTION: is it important to check first if DAB is empty? - if(!DAB.empty()) { - DAB.clear(); - } + DAB.clear(); StateIsValidAfterReentrance = false; } - bool insertSample(D Sample) { - bool workedForAll; + 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 (numberOfEntries >= DAB) { - DOUT AvgOfDAB = template average(); + if (DAB.full()) { + DDAB AvgOfDAB = DAB.average(); 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 } } } return workedForAll; } - DOUT confSampleMatchesState (DIN sample) { + DDAB confSampleMatchesState (DIN sample) { } - DOUT confSampleMismatchesState () { + DDAB confSampleMismatchesState () { } unsigned int stateId(void) { return StateId; } }; } // End namespace agent } // End namespace rosa #endif // ROSA_AGENT_STATE_HPP \ No newline at end of file diff --git a/include/rosa/agent/StateDetector.hpp b/include/rosa/agent/StateDetector.hpp index e91f00f..87856e4 100644 --- a/include/rosa/agent/StateDetector.hpp +++ b/include/rosa/agent/StateDetector.hpp @@ -1,190 +1,226 @@ //===-- 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*. /// //===----------------------------------------------------------------------===// #ifndef ROSA_AGENT_STATEDETECTOR_HPP #define ROSA_AGENT_STATEDETECTOR_HPP #include "rosa/agent/Functionality.h" #include "rosa/agent/State.hpp" namespace rosa { namespace agent { - +//maybe using + + +template struct StateInformation { + unsigned int statenumber; + CONFTYPE confidences; + bool stable; //maybe: conf + bool drift; //maybe: conf + bool stateUnchanged; //check name +} + + //DIN = Input Datatype, CONF = Confidence Datatype -template class StateDetector : public Functionality { +template class StateDetector : public Functionality { + +//TODO: STATIC_ASSERT (maybe auch integer) private: unsigned int discreteAveragePartitionCounter; vector DetectedStates; bool stateIsValid; bool stateIsValidAfterReentrance; PartialFunction ConfidenceSimilarToSample; State *ActualState; unsigned int SampleHistorySize; unsigned int DABSize; unsigned int DABHistorySize; + //@Benedikt: partialfunction/linearfunction: steigung/domain ändern + //@Benedikt: linearfunction set k,d or x1/y1 and x2/y2 std::shared_ptr> PartialFunctionSampleMatches; std::shared_ptr> PartialFunctionSampleMismatches; std::shared_ptr> PartialFunctionNumOfSamplesMatches; std::shared_ptr> PartialFunctionNumOfSamplesMismatches; //QUESTION: Do we need the following to flag bool StateHasChanged; //QUESTION: Would this be better as a static variable in State.hpp (there would be the problem when deleting a state) unsigned int StateIdCounter = 1; public: //TODO: finish constructor StateDetector() noexcept { - ActualState = NULL; + ActualState = NULL; //MAYBE CHANGE TO CURRENT oder Active } - unsigned int detectState (DIN Sample) { - if(ActualState == NULL && DetectedStates.empty()) { - + std::shared_ptr detectState (DIN Sample) { //return tuple oder struct (statenumber, confidences, stable, drift, changed/unchanged) + + std::shared_ptr StateInfo; + + if(ActualState == NULL) { + ASSERT(DetectedStates.empty()); + if(State *S = createNewState()) { ActualState = S; } //QUESTION: should there an output (log) when it was not successfull? } else { CONF ConfidenceSampleMatchesState = ActualState->confSampleMatchesState(Sample); CONF ConfidenceSampleMismatchesState = ActualState->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) + //TODO: else leaveState + + + //TODO FAR AWAY FUTURE: additionally save averages to enable fast iteration through recorded state vector + //- maybe sort vector based on these average values + ActualState = NULL; for(auto &SavedState : DetectedStates) { if(SavedState != ActualState) { CONF ConfidenceSampleMatchesState = SavedState->confSampleMatchesState(Sample); CONF ConfidenceSampleMismatchesState = SavedState->confSampleMismatchesState(Sample); if(ConfidenceSampleMatchesState > ConfidenceSampleMismatchesState) { - //TODO: check whether ActiveState is valid - //TODO: if invalid -> deleteState and decrease StateIdCounter - //QUESTION: maybe it would be better to compare ConfidenceSampleMatchesState //of all states in the vector ActualState = SavedState; break; } } - } + } + + if(!ActualState) { + if(State *S = createNewState()) { + + ActualState = S; + + } //QUESTION: should there an output (log) when it was not successfull? + } } } ActualState->insertSample(Sample); - + //TODO: check actual state whether it drifts + //TODO: write in StateInfo - return ActualState->stateId; + + return StateInfo; } 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: - State* createNewState(){ + std::shared_ptr createNewState(){ bool CreatingWorked; - State *S = new (nothrow) State(StateIdCounter, SampleHistorySize, DABSize, + std::shared_ptr = new (nothrow) State(StateIdCounter, SampleHistorySize, DABSize, DABHistorySize, PartialFunctionSampleMatches, PartialFunctionSampleMismatches, PartialFunctionNumOfSamplesMatches, PartialFunctionNumOfSamplesMismatches); if(S) { DetectedStates.push_back(S); //QUESTION: how to make this without any exception? CreatingWorked = true; //TODO: if push_back did not work -> CreatingWorked = false; } else { - delete S; + //delete S; CreatingWorked = false; } if(CreatingWorked) { StateIdCounter++; return S; } else { return NULL; } } }; } // End namespace agent } // End namespace rosa #endif // ROSA_AGENT_STATEDETECTOR_HPP \ No newline at end of file