/******************************************************* * * DESCRIPTION: class OutputQuantizer * * AUTHOR: Mariana C. D'Abreu * * EMAIL: mdabreu@dc.uba.ar * ********************************************************/ #include "outputquantizer.h" const double OutputQuantizer::InvalidHysteresisWindow = -1; /******************************************************************* * Function: OutputQuantizerr * Description: constructor ********************************************************************/ OutputQuantizer::OutputQuantizer( const string &quantMethod ) :method( quantMethod ), firstValue( true ), hysteresis( false ), hystWindow( OutputQuantizer::InvalidHysteresisWindow ) { quantizer = Quantizer::create( quantMethod ); lastQValue = new Value(); } /******************************************************************* * Function: OutputQuantizerr * Description: constructor ********************************************************************/ OutputQuantizer::OutputQuantizer( const string &quantMethod, const double hystWindow ) :method( quantMethod ), firstValue( true ), hysteresis( true ) { if ( hystWindow < 0 ) { OutputQuantizerException e; e.addText( "Invalid hysteresis window size!" ); MTHROW( e ); } this->hystWindow = hystWindow; quantizer = Quantizer::create( quantMethod ); lastQValue = new Value(); } /******************************************************************* * Function Name: ~OutputQuantizer * Destructor ********************************************************************/ OutputQuantizer::~OutputQuantizer() { if ( quantizer ) { delete quantizer; } if ( lastQValue ) { delete lastQValue; } } /******************************************************************* * Function Name: setter ********************************************************************/ OutputQuantizer &OutputQuantizer::hysteresisWindow( const double hystWindow ) { if ( hystWindow < 0 ) { OutputQuantizerException e; e.addText( "Invalid hysteresis window size!" ); MTHROW( e ); } this->hystWindow = hystWindow; hysteresis = true; return *this; } /******************************************************************* * Function Name: quantize ********************************************************************/ bool OutputQuantizer::emitOutput( const Value &value, Value* &qValue ) { bool emit; if ( value.isReal() ) { quantizeValue( value.toReal(), qValue ); } else { quantizeList( (VList *)&value, (VList *)qValue ); } emit = emitValue( qValue ); firstValue = false; lastQValue = qValue->clone(); return emit; } /******************************************************************* * Function Name: quantizeValue ********************************************************************/ bool OutputQuantizer::quantizeValue( const RealValue &value, Value* &qValue, const int index ) { qValue = new Value(); //--- El primer valor siempre lo cuantifico if ( firstValue ) { *qValue = quantizer->quantize( value ); } else { if( hysteresis ) { *qValue = hquantize( value, index ); } else { *qValue = quantizer->quantize( value ); } } return true; } /******************************************************************* * Function Name: quantizeList ********************************************************************/ bool OutputQuantizer::quantizeList( const VList *value, VList* &qValue ) { Value *v, *vq; VList *vlq; qValue = new VList(); for( int i = 1; i <= value->numberOfElements(); i++ ) { v = value->elementAt( i ); if ( v->isReal() ) { if ( quantizeValue( v->toReal(), vq, i ) ) { qValue->addElement( vq ); } } else { if ( quantizeList( (VList *)v, vlq ) ) { qValue->addElement( vlq ); } } } return true; } /******************************************************************* * Function Name: hquantize ********************************************************************/ RealValue OutputQuantizer::hquantize( const RealValue &value, const int index ) { RealValue lQValue; if ( lastQValue->isReal() ) { lQValue = lastQValue->toReal(); } else { // si se trata de una lista utilizo el indice... lQValue = ((VList *)lastQValue)->elementAt( index )->toReal(); } // aplico histeresis if ( value > lQValue ) { return quantizer->quantize( value ); } else if ( value <= lQValue - hystWindow ) { return quantizer->quantize( value ); } return lQValue; } /******************************************************************* * Function Name: emitValue ********************************************************************/ bool OutputQuantizer::emitValue( const Value *value ) { return ( firstValue || ( *value != *lastQValue ) ); } /******************************************************************* * Function Name: printInfo *******************************************************************/ void OutputQuantizer::printInfo( ostream &out ) { out << "Hysteresis: " << useHysteresis() << endl; out << "Hysteresis Window: " << hysteresisWindow() << endl; assert ( quantizer ); quantizer->printInfo( out ); }