Marsyas  0.6.0-alpha
/usr/src/RPM/BUILD/marsyas-0.6.0/src/marsyas/marsystems/Metric.cpp
Go to the documentation of this file.
00001 /*
00002 ** Copyright (C) 1998-2006 George Tzanetakis <gtzan@cs.uvic.ca>
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 "Metric.h"
00020 #include <marsyas/NumericLib.h>
00021 
00022 using std::ostringstream;
00023 using namespace Marsyas;
00024 
00025 static mrs_real
00026 randomDistance(const realvec& Vi, const realvec& Vj, const realvec& covMatrix)
00027 {
00028   (void) Vi;
00029   (void) Vj;
00030   (void) covMatrix;
00031   return rand()/mrs_real(RAND_MAX);
00032 }
00033 
00034 Metric::Metric(mrs_string name):MarSystem("Metric", name)
00035 {
00036   addControls();
00037 }
00038 
00039 Metric::Metric(const Metric& a) : MarSystem(a)
00040 {
00041   ctrl_metric_ = getctrl("mrs_string/metric");
00042   ctrl_covMatrix_ = getctrl("mrs_realvec/covMatrix");
00043 }
00044 
00045 Metric::~Metric()
00046 {
00047 
00048 }
00049 
00050 MarSystem*
00051 Metric::clone() const
00052 {
00053   return new Metric(*this);
00054 }
00055 
00056 void
00057 Metric::addControls()
00058 {
00059   addControl("mrs_string/metric", "euclideanDistance", ctrl_metric_);
00060   ctrl_metric_->setState(true);
00061 
00062   addControl("mrs_realvec/covMatrix", realvec(), ctrl_covMatrix_);
00063 }
00064 
00065 void
00066 Metric::myUpdate(MarControlPtr sender)
00067 {
00068   (void) sender;  //suppress warning of unused parameter(s)
00069   if(inSamples_ > 1) {
00070     MRSWARN("Metric::myUpdate - inSamples > 1 : only first column will be processed!");
00071   }
00072 
00073   ctrl_onObservations_->setValue(1, NOUPDATE);
00074   ctrl_onSamples_->setValue(1, NOUPDATE);
00075   ctrl_osrate_->setValue(ctrl_israte_, NOUPDATE); //[?]
00076   ctrl_onObsNames_->setValue("metric", NOUPDATE);
00077 
00078   //the input has the two vectors/matrices to process stacked vertically
00079   if(inObservations_ % 2 != 0) {
00080     MRSWARN("Metric::myUpdate - input flow controls do not seem to be in a valid format!");
00081   }
00082   vec_i_.create(ctrl_inObservations_->to<mrs_natural>()/2, ctrl_inSamples_->to<mrs_natural>());
00083   vec_j_.create(ctrl_inObservations_->to<mrs_natural>()/2, ctrl_inSamples_->to<mrs_natural>());
00084 
00085   //get the pointer for the correct metric function
00086   mrs_string metricName = ctrl_metric_->to<mrs_string>();
00087   if(metricName == "euclideanDistance")
00088   {
00089     metricFunc_ = &NumericLib::euclideanDistance;
00090   }
00091   else if(metricName == "mahalanobisDistance")
00092   {
00093     metricFunc_ = &NumericLib::mahalanobisDistance;
00094   }
00095   else if(metricName == "cosineDistance")
00096   {
00097     metricFunc_ = &NumericLib::cosineDistance;
00098   }
00099   else if(metricName == "randomDistance")
00100   {
00101     metricFunc_ = &randomDistance;
00102   }
00103   else
00104   {
00105     MRSWARN("Metric::myUpdate: unsuported metric funtion: " + metricName);
00106     metricFunc_ = NULL;
00107   }
00108 }
00109 
00110 void
00111 Metric::myProcess(realvec& in, realvec& out)
00112 {
00113   mrs_natural t,o;
00114   if(metricFunc_)
00115   {
00116     //get the two stacked vectors from the input
00117     for(o=0; o < inObservations_/2; ++o)
00118     {
00119       for(t=0; t < inSamples_; ++t)
00120       {
00121         vec_i_(o,t) = in(o,t);
00122         vec_j_(o,t) = in(o+inObservations_/2,t);
00123       }
00124     }
00125 
00126     //do the actual metric calculation
00127     out(0) = metricFunc_(vec_i_, vec_j_, ctrl_covMatrix_->to<mrs_realvec>());
00128   }
00129   else
00130     out(0) = 0; //default output value when no metric is defined
00131 }