Marsyas  0.6.0-alpha
/usr/src/RPM/BUILD/marsyas-0.6.0/src/marsyas/marsystems/RunningAutocorrelation.cpp
Go to the documentation of this file.
00001 /*
00002  ** Copyright (C) 2010 Stefaan Lippens
00003  **
00004  ** This program is free software; you can redistribute it and/or modify
00005  ** it under the terms of the GNU General Public License as published by
00006  ** the Free Software Foundation; either version 2 of the License, or
00007  ** (at your option) any later version.
00008  **
00009  ** This program is distributed in the hope that it will be useful,
00010  ** but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  ** GNU General Public License for more details.
00013  **
00014  ** You should have received a copy of the GNU General Public License
00015  ** along with this program; if not, write to the Free Software
00016  ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
00017  */
00018 
00019 #include "RunningAutocorrelation.h"
00020 #include "../common_source.h"
00021 
00022 // For min().
00023 #include <algorithm>
00024 
00025 using namespace std;
00026 using namespace Marsyas;
00027 
00028 RunningAutocorrelation::RunningAutocorrelation(mrs_string name) :
00029   MarSystem("RunningAutocorrelation", name)
00030 {
00032   addControls();
00033 }
00034 
00035 RunningAutocorrelation::RunningAutocorrelation(const RunningAutocorrelation& a) :
00036   MarSystem(a)
00037 {
00040   ctrl_maxLag_ = getctrl("mrs_natural/maxLag");
00041   ctrl_normalize_ = getctrl("mrs_bool/normalize");
00042   ctrl_doNotNormalizeForLag0_ = getctrl("mrs_bool/doNotNormalizeForLag0");
00043   ctrl_clear_ = getctrl("mrs_bool/clear");
00044   ctrl_unfoldToObservations_ = getctrl("mrs_bool/unfoldToObservations");
00045 }
00046 
00047 RunningAutocorrelation::~RunningAutocorrelation()
00048 {
00049 }
00050 
00051 MarSystem*
00052 RunningAutocorrelation::clone() const
00053 {
00054   return new RunningAutocorrelation(*this);
00055 }
00056 
00057 void RunningAutocorrelation::addControls()
00058 {
00060   addctrl("mrs_natural/maxLag", 15, ctrl_maxLag_);
00061   setctrlState("mrs_natural/maxLag", true);
00062   addctrl("mrs_bool/normalize", false, ctrl_normalize_);
00063   setctrlState("mrs_bool/normalize", true);
00064   addctrl("mrs_bool/doNotNormalizeForLag0", false,
00065           ctrl_doNotNormalizeForLag0_);
00066   setctrlState("mrs_bool/doNotNormalizeForLag0", true);
00067   addctrl("mrs_bool/clear", false, ctrl_clear_);
00068   setctrlState("mrs_bool/clear", true);
00069   addctrl("mrs_bool/unfoldToObservations", false, ctrl_unfoldToObservations_);
00070   setctrlState("mrs_bool/unfoldToObservations", true);
00071 }
00072 
00076 mrs_string prefixObservationNamesWithAutocorrelationUnfoldingPrefixes_(
00077   mrs_string inObservationNames, mrs_bool normalize,
00078   mrs_bool doNotNormalizeForLag0, mrs_natural maxLag)
00079 {
00080   vector<mrs_string> inObsNames = obsNamesSplit(inObservationNames);
00081   mrs_string onObsNames("");
00082   for (vector<mrs_string>::iterator it = inObsNames.begin(); it
00083        != inObsNames.end(); it++)
00084   {
00085     for (int lag = 0; lag <= maxLag; lag++)
00086     {
00087       ostringstream oss;
00088       if (normalize && !(doNotNormalizeForLag0 && lag == 0))
00089       {
00090         oss << "Normalized";
00091       }
00092       oss << "Autocorr" << lag << "_" << (*it) << ",";
00093       onObsNames += oss.str();
00094     }
00095 
00096   }
00097   return onObsNames;
00098 
00099 }
00100 
00101 void RunningAutocorrelation::myUpdate(MarControlPtr sender)
00102 {
00103   (void) sender;  //suppress warning of unused parameter(s)
00104   MRSDIAG("RunningAutocorrelation.cpp - RunningAutocorrelation:myUpdate");
00105 
00106   // Update the cache of the control values.
00107   maxLag_ = ctrl_maxLag_->to<mrs_natural> ();
00108   if (maxLag_ < 0)
00109   {
00110     MRSERR("maxLag should be greater than zero.");
00111     // Setting it to zero to be sure.
00112     maxLag_ = 0;
00113   }
00114   normalize_ = ctrl_normalize_->to<mrs_bool> ();
00115   doNotNormalizeForLag0_ = ctrl_doNotNormalizeForLag0_->to<mrs_bool> ();
00116   unfoldToObservations_ = ctrl_unfoldToObservations_->to<mrs_bool> ();
00117 
00118   // Configure output flow.
00119   mrs_natural onObservations = unfoldToObservations_ ? inObservations_
00120                                * (maxLag_ + 1) : inObservations_;
00121   mrs_natural onSamples = unfoldToObservations_ ? 1 : maxLag_ + 1;
00122   ctrl_onSamples_->setValue(onSamples, NOUPDATE);
00123   ctrl_onObservations_->setValue(onObservations, NOUPDATE);
00124   ctrl_osrate_->setValue(ctrl_israte_, NOUPDATE);
00125   // Handle the observation names.
00126   mrs_string onObsNames = ctrl_inObsNames_->to<mrs_string> ();
00127   if (unfoldToObservations_)
00128   {
00129     onObsNames
00130     = prefixObservationNamesWithAutocorrelationUnfoldingPrefixes_(
00131         onObsNames, normalize_, doNotNormalizeForLag0_, maxLag_);
00132   }
00133   ctrl_onObsNames_->setValue(onObsNames, NOUPDATE);
00134 
00135   // Allocate and initialize the buffers and counters.
00136   this->acBuffer_.stretch(inObservations_, maxLag_ + 1);
00137   this->acBuffer_.setval(0.0);
00138   this->memory_.stretch(inObservations_, maxLag_);
00139   this->memory_.setval(0.0);
00140 
00141   // We just cleared the internal buffers, so we should reset the clear control.
00142   ctrl_clear_->setValue(false, NOUPDATE);
00143 }
00144 
00145 void RunningAutocorrelation::myProcess(realvec& in, realvec& out)
00146 {
00148   for (mrs_natural i = 0; i < inObservations_; ++i)
00149   {
00150     // Calculate the autocorrelation terms
00151     for (mrs_natural lag = 0; lag <= maxLag_; lag++)
00152     {
00153       // For the first part, we need the memory.
00154       for (mrs_natural n = 0; n < min(lag, inSamples_); n++)
00155       {
00156         acBuffer_(i, lag) += in(i, n) * memory_(i, maxLag_ - lag + n);
00157       }
00158       // For the second part, we have enough with the input slice.
00159       for (mrs_natural n = lag; n < inSamples_; n++)
00160       {
00161         acBuffer_(i, lag) += in(i, n) * in(i, n - lag);
00162       }
00163     }
00164 
00165     // Store result in output vector.
00166     mrs_natural u = (mrs_natural) unfoldToObservations_;
00167     mrs_natural o_base = unfoldToObservations_ ? i * (maxLag_ + 1) : i;
00168     for (mrs_natural lag = 0; lag <= maxLag_; lag++)
00169     {
00170       out(o_base + u * lag, (1 - u) * lag) = acBuffer_(i, lag);
00171 
00172     }
00173     // Do the (optional) normalization.
00174     if (normalize_ && acBuffer_(i, 0) > 0.0)
00175     {
00176       mrs_natural lag = doNotNormalizeForLag0_ ? 1 : 0;
00177       for (; lag <= maxLag_; lag++)
00178       {
00179         out(o_base + u * lag, (1 - u) * lag) /= acBuffer_(i, 0);
00180       }
00181     }
00182 
00183     // Remember the last samples for next time.
00184     // First, shift samples in memory (if needed).
00185     for (mrs_natural m = 0; m < maxLag_ - inSamples_; m++)
00186     {
00187       memory_(i, m) = memory_(i, m + inSamples_);
00188     }
00189     // Second, copy over samples from input.
00190     for (mrs_natural m = 1; m <= min(maxLag_, inSamples_); m++)
00191     {
00192       memory_(i, maxLag_ - m) = in(i, inSamples_ - m);
00193     }
00194   }
00195 }