00001 #include "SimilarityMatrix.h"
00002
00003 using namespace std;
00004 using namespace Marsyas;
00005
00006 SimilarityMatrix::SimilarityMatrix(mrs_string name):MarSystem("SimilarityMatrix", name)
00007 {
00008 isComposite_ = true;
00009 addControls();
00010 }
00011
00012 SimilarityMatrix::SimilarityMatrix(const SimilarityMatrix& a):MarSystem(a)
00013 {
00014 ctrl_covMatrix_ = getctrl("mrs_realvec/covMatrix");
00015 ctrl_calcCovMatrix_ = getctrl("mrs_natural/calcCovMatrix");
00016 ctrl_normalize_ = getctrl("mrs_string/normalize");
00017 ctrl_stdDev_ = getctrl("mrs_real/stdDev");
00018 ctrl_sizes_ = getctrl("mrs_realvec/sizes");
00019
00020 }
00021
00022 SimilarityMatrix::~SimilarityMatrix()
00023 {
00024 }
00025
00026 MarSystem*
00027 SimilarityMatrix::clone() const
00028 {
00029 return new SimilarityMatrix(*this);
00030 }
00031
00032 void
00033 SimilarityMatrix::addControls()
00034 {
00035
00036 addControl("mrs_realvec/covMatrix", realvec(), ctrl_covMatrix_);
00037 addControl("mrs_natural/calcCovMatrix", SimilarityMatrix::noCovMatrix, ctrl_calcCovMatrix_);
00038 addControl("mrs_string/normalize", "none", ctrl_normalize_);
00039 addControl("mrs_real/stdDev", 1.0, ctrl_stdDev_);
00040 addControl("mrs_realvec/sizes", realvec(), ctrl_sizes_);
00041 }
00042
00043 void SimilarityMatrix::myUpdate(MarControlPtr sender)
00044 {
00045
00046 (void) sender;
00047 MarControlAccessor acc(ctrl_sizes_);
00048 realvec& tmpvec = acc.to<mrs_realvec>();
00049 mrs_natural insize = ctrl_inSamples_->to<mrs_natural>();
00050 if(tmpvec.getRows() == 1 && tmpvec.getCols() >= 2)
00051 {
00052 sizes_.create(tmpvec.getCols());
00053 for(mrs_natural i=0; i<tmpvec.getCols(); ++i)
00054 {
00055 sizes_(i) = (mrs_natural)tmpvec(0,i);
00056 }
00057 for(mrs_natural i=0; i<tmpvec.getCols(); ++i)
00058 {
00059 if(sizes_(i) > insize)
00060 sizes_(i) = insize;
00061 }
00062 }
00063 else if(tmpvec.getRows() >= 2 && tmpvec.getCols() == 1)
00064 {
00065 sizes_.create(tmpvec.getRows());
00066 for(mrs_natural i=0; i<tmpvec.getRows(); ++i)
00067 {
00068 sizes_(i) = (mrs_natural)tmpvec(i,0);
00069 }
00070 for(mrs_natural i=0; i<tmpvec.getRows(); ++i)
00071 {
00072 if(sizes_(i) > insize)
00073 sizes_(i) = insize;
00074 }
00075 }
00076 else
00077 {
00078 sizes_.create(2);
00079 sizes_(0) = insize;
00080 sizes_(1) = insize;
00081 }
00082
00083 mrs_natural obs = 0;
00084 for(mrs_natural i=1; i<sizes_.getSize(); ++i)
00085 {
00086 obs += (mrs_natural)sizes_(i);
00087 }
00088 ctrl_onObservations_->setValue(obs, NOUPDATE);
00089 ctrl_onSamples_->setValue((mrs_natural)sizes_(0), NOUPDATE);
00090 ctrl_osrate_->setValue(ctrl_osrate_, NOUPDATE);
00091 ostringstream oss;
00092 for(mrs_natural o=0; o<ctrl_onObservations_->to<mrs_natural>(); o++)
00093 oss << "SimilarityMatrix_" << o << ",";
00094 ctrl_onObsNames_->setValue(oss.str(), NOUPDATE);
00095
00096 invecs_.resize(sizes_.getSize());
00097 obs = getctrl("mrs_natural/inObservations")->to<mrs_natural>()/sizes_.getSize();
00098 for(mrs_natural k=0; k<sizes_.getSize(); k++)
00099 {
00100 invecs_[k].create(obs, (mrs_natural)sizes_(k));
00101 }
00102
00103
00104 if(marsystemsSize_ == 1 && inSamples_ > 0)
00105 {
00106
00107
00108 i_featVec_.create(ctrl_inObservations_->to<mrs_natural>()/sizes_.getSize());
00109 j_featVec_.create(ctrl_inObservations_->to<mrs_natural>()/sizes_.getSize());
00110 stackedFeatVecs_.create(ctrl_inObservations_->to<mrs_natural>()/sizes_.getSize()*2, 1);
00111
00112
00113
00114 marsystems_[0]->setctrl("mrs_natural/inObservations", stackedFeatVecs_.getRows());
00115 marsystems_[0]->setctrl("mrs_natural/inSamples", 1);
00116 marsystems_[0]->setctrl("mrs_real/israte", ctrl_israte_->to<mrs_real>());
00117 oss.clear();
00118 oss << ctrl_inObsNames_->to<mrs_string>() << ctrl_inObsNames_->to<mrs_string>();
00119 marsystems_[0]->setctrl("mrs_string/inObsNames", oss.str());
00120 marsystems_[0]->update();
00121
00122
00123 MarControlPtr ctrl_childCovMat = marsystems_[0]->getctrl("mrs_realvec/covMatrix");
00124 if(!ctrl_childCovMat.isInvalid())
00125 ctrl_childCovMat->linkTo(ctrl_covMatrix_);
00126 metricResult_.create(1,1);
00127 if(marsystems_[0]->getctrl("mrs_natural/onObservations") != 1 ||
00128 marsystems_[0]->getctrl("mrs_natural/onSamples") != 1)
00129 {
00130 MRSWARN("SimilarityMatrix:myUpdate - invalid Child Metric MarSystem (does not output a real value)!");
00131 }
00132 }
00133 else if(marsystemsSize_ > 1)
00134 {
00135 MRSWARN("similarityMatrix2:myUpdate - more than one children MarSystem exist! Only one MarSystem should be added as a metric!");
00136 }
00137 }
00138
00139 void
00140 SimilarityMatrix::myProcess(realvec& in, realvec& out)
00141 {
00142
00143
00144
00145 mrs_natural i, j, k, l;
00146 if(inSamples_ > 0)
00147 {
00148 if(marsystemsSize_ == 1)
00149 {
00150 mrs_natural nfeats = in.getRows()/sizes_.getSize();
00151
00152
00153 mrs_natural obs = 0;
00154 for(i=0; i<sizes_.getSize(); ++i)
00155 {
00156 for(j=0; j<sizes_(i); j++)
00157 {
00158 for(k=0; (mrs_natural)k<invecs_[i].getRows(); k++)
00159 {
00160 invecs_[i](k, j) = in(k+obs, j);
00161 }
00162 }
00163 obs += invecs_[i].getRows();
00164 }
00165
00166
00167 if(ctrl_normalize_->to<mrs_string>() == "MinMax")
00168 for(i=0; i<sizes_.getSize(); ++i)
00169 {
00170 invecs_[i].normObsMinMax();
00171 }
00172 else if(ctrl_normalize_->to<mrs_string>() == "MeanStd")
00173 for(i=0; i<sizes_.getSize(); ++i)
00174 {
00175 invecs_[i].normObs();
00176 }
00177
00178 if(ctrl_calcCovMatrix_->to<mrs_natural>() & SimilarityMatrix::fixedStdDev)
00179 {
00180 MarControlAccessor acc(ctrl_covMatrix_);
00181 realvec& covMatrix = acc.to<mrs_realvec>();
00182 covMatrix.create(inObservations_/sizes_.getSize(), inObservations_/sizes_.getSize());
00183 mrs_real var = ctrl_stdDev_->to<mrs_real>();
00184 var *= var;
00185 for(i=0; i< inObservations_/sizes_.getSize(); ++i)
00186 {
00187 covMatrix(i,i) = var;
00188 }
00189 }
00190 else if(ctrl_calcCovMatrix_->to<mrs_natural>() & SimilarityMatrix::diagCovMatrix)
00191 {
00192 invecs_[0].varObs(vars_);
00193 mrs_natural dim = vars_.getSize();
00194
00195 MarControlAccessor acc(ctrl_covMatrix_);
00196 realvec& covMatrix = acc.to<mrs_realvec>();
00197 covMatrix.create(dim, dim);
00198 for(i=0; i<(mrs_natural)dim; ++i)
00199 {
00200 covMatrix(i,i) = vars_(i);
00201 }
00202 }
00203 else if(ctrl_calcCovMatrix_->to<mrs_natural>() & SimilarityMatrix::fullCovMatrix)
00204 {
00205 MarControlAccessor acc(ctrl_covMatrix_);
00206 realvec& covMatrix = acc.to<mrs_realvec>();
00207 invecs_[0].covariance(covMatrix);
00208 }
00209 else if(ctrl_calcCovMatrix_->to<mrs_natural>() & SimilarityMatrix::noCovMatrix)
00210 {
00211 ctrl_covMatrix_->setValue(realvec());
00212 }
00213
00214 for(i=0; i<sizes_(0); ++i)
00215 {
00216 obs = 0;
00217 invecs_[0].getCol(i, i_featVec_);
00218 for(l=0; l<(mrs_natural)nfeats; l++)
00219 {
00220 stackedFeatVecs_(l,0) = i_featVec_(l);
00221 }
00222 for(j=1; j<sizes_.getSize(); j++)
00223 {
00224 for(k=0; k<sizes_(j); k++)
00225 {
00226 invecs_[j].getCol(k, j_featVec_);
00227
00228 for(l=0; l<(mrs_natural)nfeats; l++)
00229 {
00230 stackedFeatVecs_(l+nfeats,0) = j_featVec_(l);
00231 }
00232 marsystems_[0]->process(stackedFeatVecs_, metricResult_);
00233 out(k+obs,i) = metricResult_(0,0);
00234 }
00235 obs += (mrs_natural)sizes_(j);
00236 }
00237 }
00238 }
00239 else
00240 {
00241 out.setval(0.0);
00242 if(marsystemsSize_ == 0)
00243 {
00244 MRSWARN("SimilarityMatrix::myProcess - no Child Metric MarSystem added - outputting zero similarity matrix!");
00245 }
00246 else
00247 {
00248 MRSWARN("SimilarityMatrix::myProcess - more than one Child MarSystem exists (i.e. invalid metric) - outputting zero similarity matrix!");
00249 }
00250 }
00251 }
00252
00253
00254 }