diff --git a/apps/ccam/ccam.cpp b/apps/ccam/ccam.cpp index 19cf9f9..7ae44de 100644 --- a/apps/ccam/ccam.cpp +++ b/apps/ccam/ccam.cpp @@ -1,38 +1,58 @@ //===-- apps/ccam/ccam.cpp --------------------------------------*- C++ -*-===// // // The RoSA Framework -- Application CCAM // //===----------------------------------------------------------------------===// /// /// \file apps/ccam/ccam.cpp /// /// \author Maximilian Goetzinger (maximilian.goetzinger@tuwien.ac.at) /// /// \date 2019 /// /// \brief The application CCAM implements the case study from the paper: /// M. Goetzinger, N. TaheriNejad, H. A. Kholerdi, A. Jantsch, E. Willegger, /// T. Glatzl, A.M. Rahmani, T.Sauter, P. Liljeberg: Model - Free Condition /// Monitoring with Confidence //===----------------------------------------------------------------------===// +#include "rosa/agent/FunctionAbstractions.hpp" #include "rosa/agent/SignalStateDetector.hpp" #include int main(void) { // Just some tests :D std::vector vec = {7, 3, 5, 1, 9}; std::sort(vec.rbegin(), vec.rend()); // std::reverse(vec.begin(), vec.end()); for (auto it = vec.cbegin(); it != vec.cend(); ++it) { std::cout << *it << ' '; } - // TODO: make signal state detector object + std::shared_ptr> PartFunc( + new rosa::agent::PartialFunction( + { + {{0.f, 3.f}, + std::make_shared>( + 0.f, 1.f / 3)}, + {{3.f, 6.f}, + std::make_shared>( + 1.f, 0.f)}, + {{6.f, 9.f}, + std::make_shared>( + 3.f, -1.f / 3)}, + }, + 0)); + + std::shared_ptr> StepFunc( + new rosa::agent::StepFunction(1 / 10)); + + rosa::agent::SignalStateDetector TestSigSD( + PartFunc, PartFunc, StepFunc, StepFunc, PartFunc, PartFunc, 10, 5, 1000); return 0; } diff --git a/include/rosa/agent/SignalState.hpp b/include/rosa/agent/SignalState.hpp index 85b8fff..77d575c 100644 --- a/include/rosa/agent/SignalState.hpp +++ b/include/rosa/agent/SignalState.hpp @@ -1,370 +1,415 @@ //===-- 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*. /// //===----------------------------------------------------------------------===// // TODO: change to signal state #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" #include namespace rosa { namespace agent { /// State conditions defining how the condition of a \c rosa::agent::State is /// saved in \c rosa::agent::StateInformation. enum class VariableStateCondition { STABLE, ///< The state is stable DRIFTING, ///< The state is drifting UNKNOWN ///< The state is unknown }; template struct StateInformation { // Make sure the actual type arguments are matching our expectations. STATIC_ASSERT((std::is_arithmetic::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. CONFDATATYPE StateConfidence; /// The VariableStateCondition shows the condition of a state (stable or /// drifting) VariableStateCondition VariableStateCondition; /// 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; }; // @Benedikt: now there are 4 datatypes. Do you think we can merge PROCDATATYPE // and PROCDATATYPE somehow? /// \tparam INDATATYPE type of input data, \tparam CONFDATATYPE type of /// data in that the confidence values are given, \param PROCDATATYPE type of /// the relative distance and the type of data in which DABs are saved. template class State : public Functionality { // Make sure the actual type arguments are matching our expectations. STATIC_ASSERT((std::is_arithmetic::value), "input data type not arithmetic"); STATIC_ASSERT((std::is_arithmetic::value), "confidence data type is not to arithmetic"); STATIC_ASSERT( (std::is_arithmetic::value), "process data type (DAB and Relative Distance) is not to arithmetic"); private: // For the convinience to write a shorter data type name using PartFuncPointer = std::shared_ptr>; using StepFuncPointer = std::shared_ptr>; /// StateInfo is a struct StateInformation that contains information about the /// current state. StateInformation StateInfo; /// The FuzzyFunctionSampleMatches is the fuzzy function that gives the /// confidence how good the new sample matches another sample in the sample /// history. PartFuncPointer FuzzyFunctionSampleMatches; - /// The FuzzyFunctionSampleMatches is the fuzzy function that gives the + + /// The FuzzyFunctionSampleMismatches is the fuzzy function that gives the /// confidence how bad the new sample matches another sample in the sample /// history. PartFuncPointer FuzzyFunctionSampleMismatches; - /// The FuzzyFunctionSampleMatches is the fuzzy function that gives the + + /// The FuzzyFunctionNumOfSamplesMatches is the fuzzy function that gives the /// confidence how many samples from the sampe history match the new sample. StepFuncPointer FuzzyFunctionNumOfSamplesMatches; - /// The FuzzyFunctionSampleMatches is the fuzzy function that gives the - /// confidence how many samples from the sampe history mismatch the new + + /// The FuzzyFunctionNumOfSamplesMismatches is the fuzzy function that gives + /// the confidence how many samples from the sampe history mismatch the new /// sample. StepFuncPointer FuzzyFunctionNumOfSamplesMismatches; /// The FuzzyFunctionSignalIsDrifting is the fuzzy function that gives the /// confidence how likely it is that the signal (resp. the state of a signal) /// is drifting. PartFuncPointer FuzzyFunctionSignalIsDrifting; + /// The FuzzyFunctionSignalIsStable is the fuzzy function that gives the /// confidence how likely it is that the signal (resp. the state of a signal) /// is stable (not drifting). PartFuncPointer FuzzyFunctionSignalIsStable; /// SampleHistory is a history in that the last sample values are stored. DynamicLengthHistory SampleHistory; /// DAB is a (usually) small history of the last sample values of which a /// average is calculated if the DAB is full. DynamicLengthHistory DAB; /// DABHistory is a history in that the last DABs (to be exact, the averages /// of the last DABs) are stored. DynamicLengthHistory 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: + // @Maxi doxygen per default doesn't display private attributes of a class. So + // I copied them to the constructor. So the user has more information. /// Creates an instance by setting all parameters + /// \param StateID The Id of the Stateinfo \c StateInformation . + /// + /// \param FuzzyFunctionSampleMatches The FuzzyFunctionSampleMatches is the + /// fuzzy function that gives the confidence how good the new sample matches + /// another sample in the sample history. + /// + /// \param FuzzyFunctionSampleMismatches The FuzzyFunctionSampleMismatches is + /// the fuzzy function that gives the confidence how bad the new sample + /// matches another sample in the sample history. + /// + /// \param FuzzyFunctionNumOfSamplesMatches The + /// FuzzyFunctionNumOfSamplesMatches is the fuzzy function that gives the + /// confidence how many samples from the sampe history match the new sample. + /// + /// \param FuzzyFunctionNumOfSamplesMismatches The + /// FuzzyFunctionNumOfSamplesMismatches is the fuzzy function that gives the + /// confidence how many samples from the sampe history mismatch the new + /// sample. + /// + /// \param FuzzyFunctionSignalIsDrifting The FuzzyFunctionSignalIsDrifting is + /// the fuzzy function that gives the confidence how likely it is that the + /// signal (resp. the state of a signal) is drifting. + /// + /// \param FuzzyFunctionSignalIsStable The FuzzyFunctionSignalIsStable is the + /// fuzzy function that gives the confidence how likely it is that the signal + /// (resp. the state of a signal) is stable (not drifting). + /// + /// \param SampleHistorySize Size of the Sample History \c + /// DynamicLengthHistory . SampleHistory is a history in that the last sample + /// values are stored. + /// + /// \param DABSize Size of DAB \c DynamicLengthHistory . DAB is a (usually) + /// small history of the last sample values of which a average is calculated + /// if the DAB is full. + /// + /// \param DABHistorySize Size of the DABHistory \c DynamicLengthHistory . + /// DABHistory is a history in that the last DABs (to be exact, the averages + /// of the last DABs) are stored. + /// State(unsigned int StateID, PartFuncPointer FuzzyFunctionSampleMatches, PartFuncPointer FuzzyFunctionSampleMismatches, StepFuncPointer FuzzyFunctionNumOfSamplesMatches, StepFuncPointer FuzzyFunctionNumOfSamplesMismatches, PartFuncPointer FuzzyFunctionSignalIsDrifting, PartFuncPointer FuzzyFunctionSignalIsStable, - unsigned int sampleHistorySize, unsigned int DABSize, + unsigned int SampleHistorySize, unsigned int DABSize, unsigned int DABHistorySize) noexcept : StateInfo(StateID, 0, VariableStateCondition::UNKNOWN, false, false), - SampleHistory(sampleHistorySize), DAB(DABSize), + SampleHistory(SampleHistorySize), DAB(DABSize), DABHistory(DABHistorySize), FuzzyFunctionSampleMatches(FuzzyFunctionSampleMatches), FuzzyFunctionSampleMismatches(FuzzyFunctionSampleMismatches), FuzzyFunctionNumOfSamplesMatches(FuzzyFunctionNumOfSamplesMatches), FuzzyFunctionNumOfSamplesMismatches( FuzzyFunctionNumOfSamplesMismatches), FuzzyFunctionSignalIsDrifting(FuzzyFunctionSignalIsDrifting), FuzzyFunctionSignalIsStable(FuzzyFunctionSignalIsStable) {} /// Destroys \p this object. ~State(void) = default; void leaveState(void) noexcept { DAB.clear(); StateIsValidAfterReentrance = false; } StateInformation insertSample(INDATATYPE Sample) noexcept { SampleHistory.addEntry(Sample); DAB.addEntry(Sample); if (DAB.full()) { PROCDATATYPE AvgOfDAB = DAB.template average(); DABHistory.addEntry(AvgOfDAB); DAB.clear(); } FuzzyFunctionNumOfSamplesMatches->setRightLimit( SampleHistory->numberOfEntries()); FuzzyFunctionNumOfSamplesMismatches->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 return StateInfo; } /// Gives the confidence how likely the new sample matches the state. /// /// \param Sample is the actual sample of the observed signal. /// /// \return the confidence of the new sample is matching the state. CONFDATATYPE confSampleMatchesState(INDATATYPE Sample) noexcept { CONFDATATYPE ConfidenceOfBestCase = 0; DynamicLengthHistory RelativeDistanceHistory; // calculate distances to all history samples for (auto &HistorySample : SampleHistory) { PROCDATATYPE RelativeDistance = relativeDistance(Sample, HistorySample); RelativeDistanceHistory.addEntry(RelativeDistance); } // sort all calculated distances so that the lowest distance (will get the // highest confidence) is at the beginning. RelativeDistanceHistory.sortAscending(); CONFDATATYPE ConfidenceOfWorstFittingSample = 1; // Case 1 means that one (the best fitting) sample of the history is // compared with the new sample. Case 2 means the two best history samples // are compared with the new sample. And so on. // TODO (future): to accelerate -> don't start with 1 start with some higher // number because a low number (i guess lower than 5) will definetely lead // to a low confidence. except the history is not full. for (unsigned int Case = 0; Case < RelativeDistanceHistory.numberOfEntries(); Case++) { CONFDATATYPE ConfidenceFromRelativeDistance; if (std::isinf(RelativeDistanceHistory[Case])) { // TODO (future) if fuzzy is defined in a way that infinity is not 0 it // would be a problem //@benedikt: check if your partialfunctions can take infinity as // argument ConfidenceFromRelativeDistance = 0; } else { ConfidenceFromRelativeDistance = FuzzyFunctionSampleMatches(RelativeDistanceHistory[Case]); } ConfidenceOfWorstFittingSample = fuzzyAND(ConfidenceOfWorstFittingSample, ConfidenceFromRelativeDistance); // @benedikt: change old-style cast to one of these: reinterpret_cast, // static_cast, dynamic_cast or const_cast. Which should I use? Or should // the HistSampleCounter variable already be CONFDATATYPE type? ConfidenceOfBestCase = fuzzyOR( ConfidenceOfBestCase, fuzzyAND(ConfidenceOfWorstFittingSample, FuzzyFunctionNumOfSamplesMatches((CONFDATATYPE)Case + 1))); } return ConfidenceOfBestCase; } /// Gives the confidence how likely the new sample mismatches the state. /// /// \param Sample is the actual sample of the observed signal. /// /// \return the confidence of the new sample is mismatching the state. CONFDATATYPE confSampleMismatchesState(INDATATYPE Sample) noexcept { float ConfidenceOfWorstCase = 1; DynamicLengthHistory RelativeDistanceHistory; // calculate distances to all history samples for (auto &HistorySample : SampleHistory) { RelativeDistanceHistory.addEntry(relativeDistance(Sample, HistorySample)); } // sort all calculated distances so that the highest distance (will get the // lowest confidence) is at the beginning. RelativeDistanceHistory.sortDescending(); CONFDATATYPE ConfidenceOfBestFittingSample = 0; unsigned int Case = 1; // Case 1 means that one (the worst fitting) sample of the history is // compared with the new sample. Case 2 means the two worst history samples // are compared with the new sample. And so on. // TODO (future): to accelerate -> don't go until end. Confidences will only // get higher. See comment in "CONFDATATYPE // confSampleMatchesState(INDATATYPE Sample)". for (unsigned int Case = 0; Case < RelativeDistanceHistory.numberOfEntries(); Case++) { CONFDATATYPE ConfidenceFromRelativeDistance; if (std::isinf(RelativeDistanceHistory[Case])) { ConfidenceFromRelativeDistance = 1; } else { ConfidenceFromRelativeDistance = FuzzyFunctionSampleMismatches(RelativeDistanceHistory[Case]); } ConfidenceOfBestFittingSample = fuzzyOR(ConfidenceOfBestFittingSample, ConfidenceFromRelativeDistance); // @benedikt: change old-style cast to one of these: reinterpret_cast, // static_cast, dynamic_cast or const_cast. Which should I use? Or should // the HistSampleCounter variable already be CONFDATATYPE type? ConfidenceOfWorstCase = fuzzyAND( ConfidenceOfWorstCase, fuzzyOR(ConfidenceOfBestFittingSample, FuzzyFunctionNumOfSamplesMismatches((CONFDATATYPE)Case + 1))); } return ConfidenceOfWorstCase; } /// Gives information about the current state. /// /// \return a struct StateInformation that contains information about the /// current state. StateInformation stateInformation(void) noexcept { return StateInfo; } private: // @David: Where should these next functions (fuzzyAND, fuzzyOR, // relativeDistance) moved to (I guess we will use them also somewhere else)? // copied from the internet and adapted // (https://stackoverflow.com/questions/1657883/variable-number-of-arguments-in-c) CONFDATATYPE fuzzyAND(int n_args, ...) noexcept { va_list ap; va_start(ap, n_args); CONFDATATYPE min = va_arg(ap, CONFDATATYPE); for (int i = 2; i <= n_args; i++) { CONFDATATYPE a = va_arg(ap, CONFDATATYPE); min = std::min(a, min); } va_end(ap); return min; } // copied from the internet // (https://stackoverflow.com/questions/1657883/variable-number-of-arguments-in-c) CONFDATATYPE fuzzyOR(int n_args, ...) noexcept { va_list ap; va_start(ap, n_args); CONFDATATYPE max = va_arg(ap, CONFDATATYPE); for (int i = 2; i <= n_args; i++) { CONFDATATYPE a = va_arg(ap, CONFDATATYPE); std::max(a, max); } va_end(ap); return max; } PROCDATATYPE relativeDistance(INDATATYPE SampleValue, INDATATYPE HistoryValue) noexcept { PROCDATATYPE Dist = HistoryValue - SampleValue; if (Dist == 0) { return 0; } else { Dist = Dist / SampleValue; if (Dist < 0) { //@benedikt: I guess this multiplication here should not be done because // it could be that the distance fuzzy functions are not symetrical //(negative and positive side) Dist = Dist * (-1); } return (Dist); } } }; } // End namespace agent } // End namespace rosa #endif // ROSA_AGENT_STATE_HPP diff --git a/include/rosa/agent/SignalStateDetector.hpp b/include/rosa/agent/SignalStateDetector.hpp index 460ca67..8c77758 100644 --- a/include/rosa/agent/SignalStateDetector.hpp +++ b/include/rosa/agent/SignalStateDetector.hpp @@ -1,288 +1,402 @@ //===-- 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*. /// //===----------------------------------------------------------------------===// +<<<<<<< HEAD +======= +// TODO: noexcept + +>>>>>>> 13709b6ff470b4e2a4c18bdff670dfe32eca69c7 #ifndef ROSA_AGENT_STATEDETECTOR_HPP #define ROSA_AGENT_STATEDETECTOR_HPP #include "rosa/agent/FunctionAbstractions.hpp" #include "rosa/agent/Functionality.h" #include "rosa/agent/SignalState.hpp" #include // TODO: change everything from state to signal state 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 CONFDATATYPE is type /// of /// data in that the confidence values are given template class SignalStateDetector : public Functionality { // Make sure the actual type arguments are matching our expectations. STATIC_ASSERT((std::is_arithmetic::value), "input data type not arithmetic"); STATIC_ASSERT((std::is_arithmetic::value), "confidence abstraction type is not to arithmetic"); private: // For the convinience to write a shorter data type name using PartFuncPointer = std::shared_ptr>; using StepFuncPointer = std::shared_ptr>; using StatePtr = std::shared_ptr>; using StateInfoPtr = std::shared_ptr>; /// The NextStateID is a counter variable which stores the ID which the next /// state shall have. unsigned int NextStateID; /// The SignalStateHasChanged is a flag that show whether a state change has /// happened. bool SignalStateHasChanged; /// The CurrentState is a pointer to the (saved) state in which the actual /// variable (signal) of the observed system is. StatePtr CurrentState; + /// The DetectedStates is vector in that all detected states are saved. // TODO: make it to history std::vector DetectedStates; /// The FuzzyFunctionSampleMatches is the fuzzy function that gives the /// confidence how good the new sample matches another sample in the sample /// history. PartFuncPointer FuzzyFunctionSampleMatches; - /// The FuzzyFunctionSampleMatches is the fuzzy function that gives the + + /// The FuzzyFunctionSampleMismatches is the fuzzy function that gives the /// confidence how bad the new sample matches another sample in the sample /// history. PartFuncPointer FuzzyFunctionSampleMismatches; - /// The FuzzyFunctionSampleMatches is the fuzzy function that gives the + + /// The FuzzyFunctionNumOfSamplesMatches is the fuzzy function that gives the /// confidence how many samples from the sampe history match the new sample. StepFuncPointer FuzzyFunctionNumOfSamplesMatches; - /// The FuzzyFunctionSampleMatches is the fuzzy function that gives the - /// confidence how many samples from the sampe history mismatch the new + + /// The FuzzyFunctionNumOfSamplesMismatches is the fuzzy function that gives + /// the confidence how many samples from the sampe history mismatch the new /// sample. StepFuncPointer FuzzyFunctionNumOfSamplesMismatches; /// The FuzzyFunctionSignalIsDrifting is the fuzzy function that gives the /// confidence how likely it is that the signal is drifting. PartFuncPointer FuzzyFunctionSignalIsDrifting; + /// The FuzzyFunctionSignalIsStable is the fuzzy function that gives the /// confidence how likely it is that the signal is stable (not drifting). PartFuncPointer FuzzyFunctionSignalIsStable; /// 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 +<<<<<<< HEAD SignalStateDetector(PartFuncPointer FuzzyFunctionSampleMatches, PartFuncPointer FuzzyFunctionSampleMismatches, StepFuncPointer FuzzyFunctionNumOfSamplesMatches, StepFuncPointer FuzzyFunctionNumOfSamplesMismatches, PartFuncPointer FuzzyFunctionSignalIsDrifting, PartFuncPointer FuzzyFunctionSignalIsStable, unsigned int SampleHistorySize, unsigned int DABSize, unsigned int DABHistorySize) noexcept : NextStateID(1), SignalStateHasChanged(false), CurrentState(NULL), +======= + /// \param FuzzyFunctionSampleMatches The FuzzyFunctionSampleMatches is the + /// fuzzy function that gives the confidence how good the new sample matches + /// another sample in the sample history. + /// + /// \param FuzzyFunctionSampleMismatches The FuzzyFunctionSampleMismatches is + /// the fuzzy function that gives the confidence how bad the new sample + /// matches another sample in the sample history. + /// + /// \param FuzzyFunctionNumOfSamplesMatches The + /// FuzzyFunctionNumOfSamplesMatches is the fuzzy function that gives the + /// confidence how many samples from the sampe history match the new sample. + /// + /// \param FuzzyFunctionNumOfSamplesMismatches The + /// FuzzyFunctionNumOfSamplesMismatches is the fuzzy function that gives the + /// confidence how many samples from the sampe history mismatch the new + /// sample. + /// + /// \param FuzzyFunctionSignalIsDrifting The FuzzyFunctionSignalIsDrifting is + /// the fuzzy function that gives the confidence how likely it is that the + /// signal (resp. the state of a signal) is drifting. + /// + /// \param FuzzyFunctionSignalIsStable The FuzzyFunctionSignalIsStable is the + /// fuzzy function that gives the confidence how likely it is that the signal + /// (resp. the state of a signal) is stable (not drifting). + /// + /// \param SampleHistorySize Sets the History size which will be used by \c + /// State . + /// + /// \param DABSize Sets the DAB size which will be used by \c State . + /// + /// \param DABHistorySize Sets the size which will be used by \c State . + /// + StateDetector(PartFuncPointer FuzzyFunctionSampleMatches, + PartFuncPointer FuzzyFunctionSampleMismatches, + StepFuncPointer FuzzyFunctionNumOfSamplesMatches, + StepFuncPointer FuzzyFunctionNumOfSamplesMismatches, + PartFuncPointer FuzzyFunctionSignalIsDrifting, + PartFuncPointer FuzzyFunctionSignalIsStable, + unsigned int SampleHistorySize, unsigned int DABSize, + unsigned int DABHistorySize) noexcept + : NextStateID(1), StateHasChanged(false), CurrentState(NULL), +>>>>>>> 13709b6ff470b4e2a4c18bdff670dfe32eca69c7 FuzzyFunctionSampleMatches(FuzzyFunctionSampleMatches), FuzzyFunctionSampleMismatches(FuzzyFunctionSampleMismatches), FuzzyFunctionNumOfSamplesMatches(FuzzyFunctionNumOfSamplesMatches), FuzzyFunctionNumOfSamplesMismatches( FuzzyFunctionNumOfSamplesMismatches), FuzzyFunctionSignalIsDrifting(FuzzyFunctionSignalIsDrifting), FuzzyFunctionSignalIsStable(FuzzyFunctionSignalIsStable), SampleHistorySize(SampleHistorySize), DABSize(DABSize), DABHistorySize(DABHistorySize) {} /// Destroys \p this object. ~SignalStateDetector(void) = default; /// Detects a signal 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. /// +<<<<<<< HEAD /// \return the signal state ID as unsigend integer type. State IDs start with /// number +======= + /// \return the state ID as unsigned integer type. State IDs start with number +>>>>>>> 13709b6ff470b4e2a4c18bdff670dfe32eca69c7 /// 1; that means if there is no current state, the return value is 0. unsigned int detectSignalState(INDATATYPE Sample) noexcept { StateInfoPtr StateInfo = detectState__debug(Sample); return StateInfo->StateID; } /// Gives information about the current state. /// /// \return a the Signal 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 currentSignalStateInformation(void) noexcept { 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 SignallStateHasChanged(void) noexcept { return SignallStateHasChanged; } private: +<<<<<<< HEAD // TODO: change exlaination! it is not totally right +======= + //@maxi \param is there to Document a specific parameter of a method/function + // this method doesn't have any parameters. +>>>>>>> 13709b6ff470b4e2a4c18bdff670dfe32eca69c7 /// 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 /// +<<<<<<< HEAD /// \return the new created state or NULL if no state could be created. StatePtr createNewState(void) noexcept { +======= + /// \return a pointer to the newly created state or NULL if no state could be + /// created. + StatePtr createNewState(void) { +>>>>>>> 13709b6ff470b4e2a4c18bdff670dfe32eca69c7 StatePtr S = new (std::nothrow) State( NextStateID, SampleHistorySize, DABSize, DABHistorySize, FuzzyFunctionSampleMatches, FuzzyFunctionSampleMismatches, FuzzyFunctionNumOfSamplesMatches, FuzzyFunctionNumOfSamplesMismatches); // @benedikt: todo: assert in history, which checks if push_back worked DetectedStates.push_back(S); return S; } #ifdef STATEDETECTORDEBUGMODE public: #else private: #endif // STATEDETECTORDEBUGMODE + // @maxi is this a debug method or is it a method that will be used and + // you simply want to have access to it in debug mode? + // debug -> extend the preprocessor around the function + // access -> remove the __debug from the name ( it is confusing) + // if you want to have it marked as a debug method for auto + // complete you can do something like this : + // + //#ifdef STATEDETECTORDEBUGMODE + // public: + // StateInfoPtr debug_detectState(INDATATYPE Sample) { + // return detectState(Sample); + // } + //#endif // STATEDETECTORDEBUGMODE + // private : + // StateInfoPtr detectState(INDATATYPE Sample) { ... + // + /// 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). +<<<<<<< HEAD StateInfoPtr detectState__debug(INDATATYPE Sample) noexcept { +======= + // TODO: return something const.. cannot remember exactly (ask benedikt) + // + // maby: you are returning a pointer to the state info so who ever has that + // pointer can actually change the information if you want to return only the + // *current info* return a copy of the state info + // like this: + // + // StateInfoPtr detectState__debug(INDATATYPE Sample) -> + // StateInformation detectState__debug(INDATATYPE Sample) + // + // return CurrentState->stateInformation(); -> + // return *(CurrentState->stateInformation()); + StateInfoPtr detectState__debug(INDATATYPE Sample) { +>>>>>>> 13709b6ff470b4e2a4c18bdff670dfe32eca69c7 if (!CurrentState) { ASSERT(DetectedStates.empty()); StatePtr S = createNewState(); CurrentState = S; } else { CONFDATATYPE ConfidenceSampleMatchesState = CurrentState->confSampleMatchesState(Sample); CONFDATATYPE ConfidenceSampleMismatchesState = CurrentState->confSampleMismatchesState(Sample); if (ConfidenceSampleMatchesState > ConfidenceSampleMismatchesState) { SignalStateHasChanged = false; } else { SignalStateHasChanged = 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 = nullptr; for (auto &SavedState : DetectedStates) { if (SavedState != CurrentState) { CONFDATATYPE ConfidenceSampleMatchesState = SavedState->confSampleMatchesState(Sample); CONFDATATYPE 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) { StatePtr S = createNewState(); CurrentState = S; } } } +<<<<<<< HEAD StateInformation StateInfo = CurrentState->insertSample(Sample); +======= + // State::insertSample() current return type: void + StateInfoPtr StateInfo = CurrentState->insertSample(Sample); +>>>>>>> 13709b6ff470b4e2a4c18bdff670dfe32eca69c7 if (StateInfo.StateJustGotValid) { NextStateID++; } return StateInfo; } #ifdef STATEDETECTORDEBUGMODE public: #else private: #endif // STATEDETECTORDEBUGMODE + //@maxi here again are you sure you want to return the pointer? /// Gives information about the current state. /// +<<<<<<< HEAD /// \return a struct StateInformation that contains information about the /// current state or NULL if no current state exists. StateInformation currentStateInformation__debug(void) noexcept { +======= + /// \return a pointer to a struct StateInformation that contains information + /// about the current state or NULL if no current state exists. + StateInfoPtr currentStateInformation__debug(void) { +>>>>>>> 13709b6ff470b4e2a4c18bdff670dfe32eca69c7 if (CurrentState) { return CurrentState->stateInformation(); } else { return NULL; } } }; } // End namespace agent } // End namespace rosa #endif // ROSA_AGENT_STATEDETECTOR_HPP