00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "Metric.h"
00020 #include "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 return rand()/mrs_real(RAND_MAX);
00029 }
00030
00031 Metric::Metric(mrs_string name):MarSystem("Metric", name)
00032 {
00033 addControls();
00034 }
00035
00036 Metric::Metric(const Metric& a) : MarSystem(a)
00037 {
00038 ctrl_metric_ = getctrl("mrs_string/metric");
00039 ctrl_covMatrix_ = getctrl("mrs_realvec/covMatrix");
00040 }
00041
00042 Metric::~Metric()
00043 {
00044
00045 }
00046
00047 MarSystem*
00048 Metric::clone() const
00049 {
00050 return new Metric(*this);
00051 }
00052
00053 void
00054 Metric::addControls()
00055 {
00056 addControl("mrs_string/metric", "euclideanDistance", ctrl_metric_);
00057 ctrl_metric_->setState(true);
00058
00059 addControl("mrs_realvec/covMatrix", realvec(), ctrl_covMatrix_);
00060 }
00061
00062 void
00063 Metric::myUpdate(MarControlPtr sender)
00064 {
00065 (void) sender;
00066 if(inSamples_ > 1)
00067 MRSWARN("Metric::myUpdate - inSamples > 1 : only first column will be processed!");
00068
00069 ctrl_onObservations_->setValue(1, NOUPDATE);
00070 ctrl_onSamples_->setValue(1, NOUPDATE);
00071 ctrl_osrate_->setValue(ctrl_israte_, NOUPDATE);
00072 ctrl_onObsNames_->setValue("metric", NOUPDATE);
00073
00074
00075 if(inObservations_ % 2 != 0)
00076 MRSWARN("Metric::myUpdate - input flow controls do not seem to be in a valid format!");
00077 vec_i_.create(ctrl_inObservations_->to<mrs_natural>()/2, ctrl_inSamples_->to<mrs_natural>());
00078 vec_j_.create(ctrl_inObservations_->to<mrs_natural>()/2, ctrl_inSamples_->to<mrs_natural>());
00079
00080
00081 mrs_string metricName = ctrl_metric_->to<mrs_string>();
00082 if(metricName == "euclideanDistance")
00083 {
00084 metricFunc_ = &NumericLib::euclideanDistance;
00085 }
00086 else if(metricName == "mahalanobisDistance")
00087 {
00088 metricFunc_ = &NumericLib::mahalanobisDistance;
00089 }
00090 else if(metricName == "cosineDistance")
00091 {
00092 metricFunc_ = &NumericLib::cosineDistance;
00093 }
00094 else if(metricName == "randomDistance")
00095 {
00096 metricFunc_ = &randomDistance;
00097 }
00098 else
00099 {
00100 MRSWARN("Metric::myUpdate: unsuported metric funtion: " + metricName);
00101 metricFunc_ = NULL;
00102 }
00103 }
00104
00105 void
00106 Metric::myProcess(realvec& in, realvec& out)
00107 {
00108 mrs_natural t,o;
00109 if(metricFunc_)
00110 {
00111
00112 for(o=0; o < inObservations_/2; ++o)
00113 {
00114 for(t=0; t < inSamples_; ++t)
00115 {
00116 vec_i_(o,t) = in(o,t);
00117 vec_j_(o,t) = in(o+inObservations_/2,t);
00118 }
00119 }
00120
00121
00122 out(0) = metricFunc_(vec_i_, vec_j_, ctrl_covMatrix_->to<mrs_realvec>());
00123 }
00124 else
00125 out(0) = 0;
00126 }