this->AddThreshold( thr );
}
+// -------------------------------------------------------------------------
+template< class _TAlgorithm >
+unsigned long fpa::Base::Mori< _TAlgorithm >::
+GetNumberOfEvaluatedThresholds( ) const
+{
+ return( this->m_Signal.size( ) );
+}
+
+// -------------------------------------------------------------------------
+template< class _TAlgorithm >
+typename fpa::Base::Mori< _TAlgorithm >::
+TInputValue fpa::Base::Mori< _TAlgorithm >::
+GetOptimumThreshold( ) const
+{
+ TInputValue thr = TInputValue( 0 );
+ if( this->m_Signal.size( ) > 1 )
+ thr = this->m_Signal[ this->m_Signal.size( ) - 2 ].first;
+ return( thr );
+}
+
// -------------------------------------------------------------------------
template< class _TAlgorithm >
fpa::Base::Mori< _TAlgorithm >::
Mori( )
: Superclass( ),
+ m_SignalLag( 20 ),
+ m_SignalThreshold( 500 ),
+ m_SignalInfluence( 0.5 ),
m_InsideValue( TOutputValue( 1 ) )
{
this->SetInitValue( TOutputValue( 0 ) );
this->m_Predicate->SetUpper( *( this->m_CurrentThreshold ) );
this->m_Count = 0;
this->m_Signal.clear( );
-}
-
-// -------------------------------------------------------------------------
-template< class _TAlgorithm >
-void fpa::Base::Mori< _TAlgorithm >::
-_AfterGenerateData( )
-{
- // https://stackoverflow.com/questions/22583391/peak-signal-detection-in-realtime-timeseries-data
- this->Superclass::_AfterGenerateData( );
-
- typename TSignal::const_iterator sIt = this->m_Signal.begin( );
- for( ; sIt != this->m_Signal.end( ); ++sIt )
- {
- std::cout << int( sIt->first ) << " " << int( sIt->second.first ) << " " << sIt->second.second << std::endl;
-
- } // rof
+ this->m_FilteredSignal.clear( );
+ this->m_SignalAverages.clear( );
+ this->m_SignalDeviations.clear( );
+ this->m_SignalPeaks.clear( );
+ this->m_CurrentAverage = double( 0 );
+ this->m_CurrentVariance = double( 0 );
}
// -------------------------------------------------------------------------
{
if( this->m_Queues[ this->m_CurrentQueue ].size( ) == 0 )
{
- this->m_Signal[ this->m_Signal.size( ) + 1 ] =
- TSignalData( *this->m_CurrentThreshold, this->m_Count );
+ this->m_Signal.push_back(
+ TSignalData( *this->m_CurrentThreshold, this->m_Count )
+ );
this->m_CurrentThreshold++;
this->m_CurrentQueue = ( this->m_CurrentQueue + 1 ) % 2;
if( this->m_CurrentThreshold != this->m_Thresholds.end( ) )
{
+ if( this->m_FilteredSignal.size( ) < this->m_SignalLag )
+ {
+ double v = double( this->m_Count );
+ double n = double( this->m_FilteredSignal.size( ) + 1 );
+ this->m_FilteredSignal.push_back( v );
+ this->m_SignalAverages.push_back( double( 0 ) );
+ this->m_SignalDeviations.push_back( double( 0 ) );
+ this->m_SignalPeaks.push_back( 0 );
+ if( n > double( 1 ) )
+ this->m_CurrentVariance =
+ ( ( ( n - 2.0 ) / ( n - 1.0 ) ) * this->m_CurrentVariance ) +
+ ( (
+ ( v - this->m_CurrentAverage ) *
+ ( v - this->m_CurrentAverage )
+ ) / n );
+ this->m_CurrentAverage += ( v - this->m_CurrentAverage ) / n;
+ if( this->m_FilteredSignal.size( ) == this->m_SignalLag )
+ {
+ this->m_SignalAverages.push_back( this->m_CurrentAverage );
+ this->m_SignalDeviations.push_back(
+ std::sqrt( this->m_CurrentVariance )
+ );
+
+ } // fi
+ }
+ else
+ {
+ unsigned long i = this->m_Signal.size( ) - 1;
+ double v = double( this->m_Count );
+ if(
+ ( std::fabs( v - this->m_SignalAverages[ i - 1 ] ) ) >
+ ( this->m_SignalThreshold * this->m_SignalDeviations[ i - 1 ] )
+ )
+ {
+ if( v > this->m_SignalAverages[ i - 1 ] )
+ this->m_SignalPeaks.push_back( 1 );
+ else
+ this->m_SignalPeaks.push_back( -1 );
+ this->m_FilteredSignal.push_back(
+ ( this->m_SignalInfluence * v ) +
+ (
+ ( 1.0 - this->m_SignalInfluence ) *
+ this->m_FilteredSignal[ i - 1 ]
+ )
+ );
+ }
+ else
+ {
+ this->m_SignalPeaks.push_back( 0 );
+ this->m_FilteredSignal.push_back( v );
+
+ } // fi
+
+ double avg = double( 0 );
+ double var = double( 0 );
+ unsigned long k = 0;
+ for( unsigned long j = i - this->m_SignalLag; j <= i; ++j, ++k )
+ {
+ double v = this->m_FilteredSignal[ j ];
+ double n = double( k + 1 );
+ if( k > 1 )
+ var =
+ ( ( ( n - 2.0 ) / ( n - 1.0 ) ) * var ) +
+ ( ( ( v - avg ) * ( v - avg ) ) / n );
+ avg += ( v - avg ) / n;
+
+ } // rof
+ this->m_SignalAverages.push_back( avg );
+ this->m_SignalDeviations.push_back( std::sqrt( var ) );
+
+ } // fi
this->m_Predicate->SetUpper( *( this->m_CurrentThreshold ) );
this->m_Count = 0;
+
+ // Peak detected? -> stop!
+ if( this->m_SignalPeaks.back( ) == 1 )
+ this->_QueueClear( );
}
else
this->_QueueClear( );