Marsyas  0.6.0-alpha
/usr/src/RPM/BUILD/marsyas-0.6.0/src/marsyas/marsystems/SimilarityMatrix.cpp
Go to the documentation of this file.
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   //ctrl_disMatrix_ = getctrl("mrs_realvec/disMatrix");
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   //  addControl("mrs_realvec/disMatrix", realvec(), ctrl_disMatrix_);
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;  //suppress warning of unused parameter(s)
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   child_count_t child_count = marsystems_.size();
00104   if(child_count == 1 && inSamples_ > 0)
00105   {
00106     // allocate realvec for the pair of stacked feature vectors
00107     // to be used in the similarity computation
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     // configure the metric child MarSystem:
00113     // the input to metric are the two vectors to process stacked vertically
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     // link covMatrix control
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(child_count > 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   //check if there are any elements to process at the input
00143   //(in some cases, they may not exist!) - otherwise, do nothing
00144   //(i.e. output is also an empty vector)
00145   mrs_natural i, j, k, l;
00146 
00147   if(inSamples_ > 0)
00148   {
00149     child_count_t child_count = marsystems_.size();
00150     if(child_count == 1)
00151     {
00152       mrs_natural nfeats = in.getRows()/sizes_.getSize();
00153 
00154       // calculate hte Covariance Matrix from the input, if defined
00155       mrs_natural obs = 0;
00156       for(i=0; i<sizes_.getSize(); ++i)
00157       {
00158         for(j=0; j<sizes_(i); j++)
00159         {
00160           for(k=0; (mrs_natural)k<invecs_[i].getRows(); k++)
00161           {
00162             invecs_[i](k, j) = in(k+obs, j);
00163           }
00164         }
00165         obs += invecs_[i].getRows();
00166       }
00167 
00168       // normalize input features if necessary
00169       if(ctrl_normalize_->to<mrs_string>() == "MinMax")
00170         for(i=0; i<sizes_.getSize(); ++i)
00171         {
00172           invecs_[i].normObsMinMax(); // (x - min)/(max - min)
00173         }
00174       else if(ctrl_normalize_->to<mrs_string>() == "MeanStd")
00175         for(i=0; i<sizes_.getSize(); ++i)
00176         {
00177           invecs_[i].normObs();  // (x - mean)/std
00178         }
00179 
00180       if(ctrl_calcCovMatrix_->to<mrs_natural>() & SimilarityMatrix::fixedStdDev)
00181       {
00182         MarControlAccessor acc(ctrl_covMatrix_);
00183         realvec& covMatrix = acc.to<mrs_realvec>();
00184         covMatrix.create(inObservations_/sizes_.getSize(), inObservations_/sizes_.getSize());
00185         mrs_real var = ctrl_stdDev_->to<mrs_real>();
00186         var *= var;
00187         for(i=0; i< inObservations_/sizes_.getSize(); ++i)
00188         {
00189           covMatrix(i,i) = var;
00190         }
00191       }
00192       else if(ctrl_calcCovMatrix_->to<mrs_natural>() & SimilarityMatrix::diagCovMatrix)
00193       {
00194         invecs_[0].varObs(vars_); // Faster
00195         mrs_natural dim = vars_.getSize();
00196         // fill covMatrix diagonal with var values (remaining values are zero)
00197         MarControlAccessor acc(ctrl_covMatrix_);
00198         realvec& covMatrix = acc.to<mrs_realvec>();
00199         covMatrix.create(dim, dim);
00200         for(i=0; i<(mrs_natural)dim; ++i)
00201         {
00202           covMatrix(i,i) = vars_(i);
00203         }
00204       }
00205       else if(ctrl_calcCovMatrix_->to<mrs_natural>() & SimilarityMatrix::fullCovMatrix)
00206       {
00207         MarControlAccessor acc(ctrl_covMatrix_);
00208         realvec& covMatrix = acc.to<mrs_realvec>();
00209         invecs_[0].covariance(covMatrix); // Slower
00210       }
00211       else if(ctrl_calcCovMatrix_->to<mrs_natural>() & SimilarityMatrix::noCovMatrix)
00212       {
00213         ctrl_covMatrix_->setValue(realvec());
00214       }
00215 
00216       for(i=0; i<sizes_(0); ++i)
00217       {
00218         obs = 0;
00219         invecs_[0].getCol(i, i_featVec_);
00220         for(l=0; l<(mrs_natural)nfeats; l++)
00221         {
00222           stackedFeatVecs_(l,0) = i_featVec_(l);
00223         }
00224         for(j=1; j<sizes_.getSize(); j++)
00225         {
00226           for(k=0; k<sizes_(j); k++)
00227           {
00228             invecs_[j].getCol(k, j_featVec_);
00229             // stack i and j feat vectors
00230             for(l=0; l<(mrs_natural)nfeats; l++)
00231             {
00232               stackedFeatVecs_(l+nfeats,0) = j_featVec_(l);
00233             }
00234             marsystems_[0]->process(stackedFeatVecs_, metricResult_);
00235             out(k+obs,i) = metricResult_(0,0);
00236           }
00237           obs += (mrs_natural)sizes_(j);
00238         }
00239       }
00240     }
00241     else
00242     {
00243       out.setval(0.0);
00244       if(child_count == 0)
00245       {
00246         MRSWARN("SimilarityMatrix::myProcess - no Child Metric MarSystem added - outputting zero similarity matrix!");
00247       }
00248       else
00249       {
00250         MRSWARN("SimilarityMatrix::myProcess - more than one Child MarSystem exists (i.e. invalid metric) - outputting zero similarity matrix!");
00251       }
00252     }
00253   }
00254   //MATLAB_PUT(out, "simMat");
00255   //MATLAB_EVAL(name_+"=["+name_+",simMat(:)'];");
00256 }