00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "SelfSimilarityMatrix.h"
00020
00021 using namespace std;
00022 using namespace Marsyas;
00023
00024 SelfSimilarityMatrix::SelfSimilarityMatrix(mrs_string name):MarSystem("SelfSimilarityMatrix", name)
00025 {
00026 isComposite_ = true;
00027 addControls();
00028 }
00029
00030 SelfSimilarityMatrix::SelfSimilarityMatrix(const SelfSimilarityMatrix& a) : MarSystem(a)
00031 {
00032 ctrl_covMatrix_ = getctrl("mrs_realvec/covMatrix");
00033 ctrl_calcCovMatrix_ = getctrl("mrs_natural/calcCovMatrix");
00034 ctrl_normalize_ = getctrl("mrs_string/normalize");
00035 ctrl_stdDev_ = getctrl("mrs_real/stdDev");
00036
00037 ctrl_mode_ = getctrl("mrs_natural/mode");
00038 ctrl_instanceIndexes_ = getctrl("mrs_realvec/instanceIndexes");
00039 ctrl_nInstances_ = getctrl("mrs_natural/nInstances");
00040 ctrl_done_ = getctrl("mrs_bool/done");
00041 }
00042
00043 SelfSimilarityMatrix::~SelfSimilarityMatrix()
00044 {
00045 }
00046
00047 MarSystem*
00048 SelfSimilarityMatrix::clone() const
00049 {
00050 return new SelfSimilarityMatrix(*this);
00051 }
00052
00053 void
00054 SelfSimilarityMatrix::addControls()
00055 {
00056 addControl("mrs_realvec/covMatrix", realvec(), ctrl_covMatrix_);
00057 addControl("mrs_natural/calcCovMatrix", SelfSimilarityMatrix::noCovMatrix, ctrl_calcCovMatrix_);
00058 addControl("mrs_string/normalize", "none", ctrl_normalize_);
00059 addControl("mrs_real/stdDev", 1.0, ctrl_stdDev_);
00060
00061 addControl("mrs_natural/mode", SelfSimilarityMatrix::outputDistanceMatrix, ctrl_mode_);
00062 ctrl_mode_->setState(true);
00063 addControl("mrs_realvec/instanceIndexes", realvec(), ctrl_instanceIndexes_);
00064 addControl("mrs_natural/nInstances", -1, ctrl_nInstances_);
00065 addControl("mrs_bool/done", false, ctrl_done_);
00066 }
00067
00068 void
00069 SelfSimilarityMatrix::myUpdate(MarControlPtr sender)
00070 {
00071 (void) sender;
00072
00073 if(this->getctrl("mrs_natural/mode")->to<mrs_natural>() == SelfSimilarityMatrix::outputDistanceMatrix)
00074 {
00075
00076
00077
00078
00079
00080 ctrl_onObservations_->setValue(ctrl_inSamples_, NOUPDATE);
00081 ctrl_onSamples_->setValue(ctrl_inSamples_, NOUPDATE);
00082 ctrl_osrate_->setValue(ctrl_osrate_, NOUPDATE);
00083 ostringstream oss;
00084 for(mrs_natural o=0; o < ctrl_onObservations_->to<mrs_natural>(); ++o)
00085 oss << "SelfSimilarityMatrix_" << o << ",";
00086 ctrl_onObsNames_->setValue(oss.str(), NOUPDATE);
00087
00088
00089
00090
00091 if(marsystemsSize_ == 1 && inSamples_ > 0)
00092 {
00093
00094
00095 i_featVec_.create(ctrl_inObservations_->to<mrs_natural>());
00096 j_featVec_.create(ctrl_inObservations_->to<mrs_natural>());
00097 stackedFeatVecs_.create(ctrl_inObservations_->to<mrs_natural>()*2, 1);
00098
00099
00100
00101 marsystems_[0]->setctrl("mrs_natural/inObservations", ctrl_inObservations_->to<mrs_natural>()*2);
00102 marsystems_[0]->setctrl("mrs_natural/inSamples", 1);
00103 marsystems_[0]->setctrl("mrs_real/israte", ctrl_israte_->to<mrs_real>());
00104 oss.clear();
00105 oss << ctrl_inObsNames_->to<mrs_string>() << ctrl_inObsNames_->to<mrs_string>();
00106 marsystems_[0]->setctrl("mrs_string/inObsNames", oss.str());
00107 marsystems_[0]->update();
00108
00109
00110 MarControlPtr ctrl_childCovMat = marsystems_[0]->getctrl("mrs_realvec/covMatrix");
00111 if(!ctrl_childCovMat.isInvalid())
00112 ctrl_childCovMat->linkTo(ctrl_covMatrix_);
00113
00114
00115 metricResult_.create(1,1);
00116
00117
00118 if(marsystems_[0]->getctrl("mrs_natural/onObservations") != 1 ||
00119 marsystems_[0]->getctrl("mrs_natural/onSamples") != 1)
00120 {
00121 MRSWARN("SelfSimilarityMatrix::myUpdate - invalid Child Metric MarSystem (does not output a real value)!");
00122 }
00123 }
00124 else if(marsystemsSize_ > 1)
00125 {
00126 MRSWARN("similarityMatrix::myUpdate - more than one children MarSystem exists! Only one MarSystem should be added as a metric!");
00127 }
00128 }
00129 else if(this->getctrl("mrs_natural/mode")->to<mrs_natural>() == SelfSimilarityMatrix::outputPairDistance)
00130 {
00131
00132
00133
00134
00135 ctrl_onObservations_->setValue(1, NOUPDATE);
00136 ctrl_onSamples_->setValue(1, NOUPDATE);
00137 ctrl_osrate_->setValue(ctrl_osrate_, NOUPDATE);
00138 ostringstream oss;
00139 oss << "Distance";
00140 ctrl_onObsNames_->setValue("Distance", NOUPDATE);
00141
00142
00143
00144
00145 if(marsystemsSize_ == 1 && inSamples_ > 0)
00146 {
00147
00148
00149 i_featVec_.create(ctrl_inObservations_->to<mrs_natural>());
00150 j_featVec_.create(ctrl_inObservations_->to<mrs_natural>());
00151 stackedFeatVecs_.create(ctrl_inObservations_->to<mrs_natural>()*2, 1);
00152
00153
00154
00155 marsystems_[0]->setctrl("mrs_natural/inObservations", ctrl_inObservations_->to<mrs_natural>()*2);
00156 marsystems_[0]->setctrl("mrs_natural/inSamples", 1);
00157 marsystems_[0]->setctrl("mrs_real/israte", ctrl_israte_->to<mrs_real>());
00158 oss.clear();
00159 oss << ctrl_inObsNames_->to<mrs_string>() << ctrl_inObsNames_->to<mrs_string>();
00160 marsystems_[0]->setctrl("mrs_string/inObsNames", oss.str());
00161 marsystems_[0]->update();
00162
00163
00164 MarControlPtr ctrl_childCovMat = marsystems_[0]->getctrl("mrs_realvec/covMatrix");
00165 if(!ctrl_childCovMat.isInvalid())
00166 ctrl_childCovMat->linkTo(ctrl_covMatrix_);
00167
00168
00169 metricResult_.create(1,1);
00170
00171 MarControlAccessor acc(ctrl_instanceIndexes_);
00172 realvec& instIdxs = acc.to<mrs_realvec>();
00173 instIdxs.create(0.0, 1, 2);
00174
00175 ctrl_done_->setValue(false, NOUPDATE);
00176
00177
00178 if(marsystems_[0]->getctrl("mrs_natural/onObservations") != 1 ||
00179 marsystems_[0]->getctrl("mrs_natural/onSamples") != 1)
00180 {
00181 MRSWARN("SelfSimilarityMatrix::myUpdate - invalid Child Metric MarSystem (does not output a real value)!");
00182 }
00183 }
00184 else if(marsystemsSize_ > 1)
00185 {
00186 MRSWARN("similarityMatrix::myUpdate - more than one children MarSystem exists! Only one MarSystem should be added as a metric!");
00187 }
00188 }
00189
00190 }
00191
00192 void
00193 SelfSimilarityMatrix::myProcess(realvec& in, realvec& out)
00194 {
00195 if(this->getctrl("mrs_natural/mode")->to<mrs_natural>() == SelfSimilarityMatrix::outputDistanceMatrix)
00196 {
00197
00198
00199
00200 if(inSamples_ > 0)
00201 {
00202 if(marsystemsSize_ == 1)
00203 {
00204 mrs_natural nfeats = in.getRows();
00205
00206
00207 if(ctrl_normalize_->to<mrs_string>() == "MinMax")
00208 in.normObsMinMax();
00209 else if(ctrl_normalize_->to<mrs_string>() == "MeanStd")
00210 in.normObs();
00211
00212
00213 if(ctrl_calcCovMatrix_->to<mrs_natural>() & SelfSimilarityMatrix::fixedStdDev)
00214 {
00215
00216 MarControlAccessor acc(ctrl_covMatrix_);
00217 realvec& covMatrix = acc.to<mrs_realvec>();
00218 covMatrix.create(inObservations_, inObservations_);
00219 mrs_real var = ctrl_stdDev_->to<mrs_real>();
00220 var *= var;
00221 for(mrs_natural i=0; i< inObservations_; ++i)
00222 {
00223 covMatrix(i,i) = var;
00224 }
00225 }
00226 else if(ctrl_calcCovMatrix_->to<mrs_natural>() & SelfSimilarityMatrix::diagCovMatrix)
00227 {
00228 in.varObs(vars_);
00229 mrs_natural dim = vars_.getSize();
00230
00231 MarControlAccessor acc(ctrl_covMatrix_);
00232 realvec& covMatrix = acc.to<mrs_realvec>();
00233 covMatrix.create(dim, dim);
00234 for(mrs_natural i=0; i< dim; ++i)
00235 {
00236 covMatrix(i,i) = vars_(i);
00237 }
00238 }
00239 else if(ctrl_calcCovMatrix_->to<mrs_natural>() & SelfSimilarityMatrix::fullCovMatrix)
00240 {
00241 MarControlAccessor acc(ctrl_covMatrix_);
00242 realvec& covMatrix = acc.to<mrs_realvec>();
00243 in.covariance(covMatrix);
00244 }
00245 else if(ctrl_calcCovMatrix_->to<mrs_natural>() == SelfSimilarityMatrix::noCovMatrix)
00246 {
00247 ctrl_covMatrix_->setValue(realvec());
00248 }
00249
00250 for(mrs_natural i=0; i < in.getCols(); ++i)
00251 {
00252 in.getCol(i, i_featVec_);
00253 for(mrs_natural j=0; j <= i; ++j)
00254 {
00255 in.getCol(j, j_featVec_);
00256
00257
00258 for(mrs_natural r=0; r < nfeats; ++r)
00259 {
00260 stackedFeatVecs_(r, 0) = i_featVec_(r);
00261 stackedFeatVecs_(r+nfeats, 0) = j_featVec_(r);
00262 }
00263
00264
00265 marsystems_[0]->process(stackedFeatVecs_, metricResult_);
00266 out(i,j) = metricResult_(0,0);
00267
00268 out(j, i) = out(i, j);
00269 }
00270 }
00271 }
00272 else
00273 {
00274 out.setval(0.0);
00275 if(marsystemsSize_ == 0)
00276 {
00277 MRSWARN("SelfSimilarityMatrix::myProcess - no Child Metric MarSystem added - outputting zero similarity matrix!");
00278 }
00279 else
00280 {
00281 MRSWARN("SelfSimilarityMatrix::myProcess - more than one Child MarSystem exists (i.e. invalid metric) - outputting zero similarity matrix!");
00282 }
00283 }
00284 }
00285
00286
00287
00288
00289
00290
00291 }
00292 else if(this->getctrl("mrs_natural/mode")->to<mrs_natural>() == SelfSimilarityMatrix::outputPairDistance)
00293 {
00294 if(inSamples_ == 2)
00295 {
00296 if(marsystemsSize_ == 1)
00297 {
00298 MarControlAccessor acc(ctrl_instanceIndexes_);
00299 realvec& instIdxs = acc.to<mrs_realvec>();
00300 mrs_natural i = mrs_natural(instIdxs(0));
00301 mrs_natural j = mrs_natural(instIdxs(1));
00302
00303
00304
00305 mrs_natural nInstances = ctrl_nInstances_->to<mrs_natural>();
00306 if(i >= nInstances || j >= nInstances)
00307 ctrl_done_->setValue(true);
00308
00309
00310 if(!ctrl_done_->isTrue())
00311 {
00312 mrs_natural nfeats = in.getRows();
00313
00314
00315 in.getCol(0, i_featVec_);
00316 in.getCol(1, j_featVec_);
00317
00318
00319 for(mrs_natural r=0; r < nfeats; ++r)
00320 {
00321 stackedFeatVecs_(r, 0) = i_featVec_(r);
00322 stackedFeatVecs_(r+nfeats, 0) = j_featVec_(r);
00323 }
00324
00325
00326
00327 marsystems_[0]->process(stackedFeatVecs_, out);
00328
00329 }
00330 else
00331 {
00332
00333
00334 out(0) = 0.0;
00335 MRSWARN("SelfSimilarityMatrix::myProcess - no more pairwise similarity computations to be performed - outputting zero similarity value!")
00336 }
00337
00338
00339
00340
00341
00342 if (i < j)
00343 ++i;
00344 else
00345 {
00346 ++j;
00347 i = 0;
00348 }
00349 if (j >= nInstances)
00350 {
00351 ctrl_done_->setValue(true);
00352 j = -1;
00353 i = -1;
00354 }
00355 else
00356 ctrl_done_->setValue(false);
00357
00358
00359 instIdxs(0) = i;
00360 instIdxs(1) = j;
00361 }
00362 else
00363 {
00364 out.setval(0.0);
00365 if(marsystemsSize_ == 0)
00366 {
00367 MRSWARN("SelfSimilarityMatrix::myProcess - no Child Metric MarSystem added - outputting zero similarity value!");
00368 }
00369 else
00370 {
00371 MRSWARN("SelfSimilarityMatrix::myProcess - more than one Child MarSystem exists (i.e. invalid metric) - outputting zero similarity value!");
00372 }
00373 }
00374 }
00375 }
00376 }