Marsyas
0.6.0-alpha
|
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 }