void SelfSimilarityMatrix::myProcess(realvec& in, realvec& out) { if(this->getctrl("mrs_natural/mode")->to<mrs_natural>() == SelfSimilarityMatrix::outputDistanceMatrix) { //check if there are any elements to process at the input //(in some cases, they may not exist!) - otherwise, do nothing //(i.e. output will be zeroed out) if(inSamples_ > 0) { unsigned int child_count = marsystems_.size(); if(child_count == 1) { mrs_natural nfeats = in.getRows(); //normalize input features if necessary if(ctrl_normalize_->to<mrs_string>() == "MinMax") in.normObsMinMax(); // (x - min)/(max - min) else if(ctrl_normalize_->to<mrs_string>() == "MeanStd") in.normObs(); // (x - mean)/std //calculate the Covariance Matrix from the input, if defined if(ctrl_calcCovMatrix_->to<mrs_natural>() & SelfSimilarityMatrix::fixedStdDev) { //fill covMatrix diagonal with fixed value (remaining values are zero) MarControlAccessor acc(ctrl_covMatrix_); realvec& covMatrix = acc.to<mrs_realvec>(); covMatrix.create(inObservations_, inObservations_); mrs_real var = ctrl_stdDev_->to<mrs_real>(); var *= var; for(mrs_natural i=0; i< inObservations_; ++i) { covMatrix(i,i) = var; } } else if(ctrl_calcCovMatrix_->to<mrs_natural>() & SelfSimilarityMatrix::diagCovMatrix) { in.varObs(vars_); //FASTER -> only get the vars for each feature mrs_natural dim = vars_.getSize(); //fill covMatrix diagonal with var values (remaining values are zero) MarControlAccessor acc(ctrl_covMatrix_); realvec& covMatrix = acc.to<mrs_realvec>(); covMatrix.create(dim, dim); for(mrs_natural i=0; i< dim; ++i) { covMatrix(i,i) = vars_(i); } } else if(ctrl_calcCovMatrix_->to<mrs_natural>() & SelfSimilarityMatrix::fullCovMatrix) { MarControlAccessor acc(ctrl_covMatrix_); realvec& covMatrix = acc.to<mrs_realvec>(); in.covariance(covMatrix); //SLOWER -> estimate the full cov matrix } else if(ctrl_calcCovMatrix_->to<mrs_natural>() == SelfSimilarityMatrix::noCovMatrix) { ctrl_covMatrix_->setValue(realvec()); } for(mrs_natural i=0; i < in.getCols(); ++i) { in.getCol(i, i_featVec_); for(mrs_natural j=0; j <= i; ++j) { in.getCol(j, j_featVec_); //stack i and j feat vecs for(mrs_natural r=0; r < nfeats; ++r) { stackedFeatVecs_(r, 0) = i_featVec_(r); stackedFeatVecs_(r+nfeats, 0) = j_featVec_(r); } //do the metric calculation for these two feat vectors //and store it in the similarity matrix (which is symmetric) marsystems_[0]->process(stackedFeatVecs_, metricResult_); out(i,j) = metricResult_(0,0); //metric should be symmetric! out(j, i) = out(i, j); } } } else { out.setval(0.0); if(child_count == 0) { MRSWARN("SelfSimilarityMatrix::myProcess - no Child Metric MarSystem added - outputting zero similarity matrix!"); } else { MRSWARN("SelfSimilarityMatrix::myProcess - more than one Child MarSystem exists (i.e. invalid metric) - outputting zero similarity matrix!"); } } } //MATLAB_PUT(out, "simMatrix"); //MATLAB_EVAL("figure(1);imagesc(simMatrix);"); //MATLAB_PUT(out, "simMat"); //MATLAB_EVAL(name_+"=["+name_+",simMat(:)'];"); } else if(this->getctrl("mrs_natural/mode")->to<mrs_natural>() == SelfSimilarityMatrix::outputPairDistance) { if(inSamples_ == 2) //we always need two column vector instances at input { unsigned int child_count = marsystems_.size(); if(child_count == 1) { MarControlAccessor acc(ctrl_instanceIndexes_); realvec& instIdxs = acc.to<mrs_realvec>(); mrs_natural i = mrs_natural(instIdxs(0)); mrs_natural j = mrs_natural(instIdxs(1)); //check for out of bound indexes (which could have been set //by someone outside changing the value of the ctrl_instanceIndexes control) mrs_natural nInstances = ctrl_nInstances_->to<mrs_natural>(); if(i >= nInstances || j >= nInstances) ctrl_done_->setValue(true); if(!ctrl_done_->isTrue()) { mrs_natural nfeats = in.getRows(); //COMPUTE DISTANCE between the two column vector at input in.getCol(0, i_featVec_); in.getCol(1, j_featVec_); //stack i and j feat vecs for(mrs_natural r=0; r < nfeats; ++r) { stackedFeatVecs_(r, 0) = i_featVec_(r); stackedFeatVecs_(r+nfeats, 0) = j_featVec_(r); } //do the metric calculation for these two feat vectors //and send it to the output marsystems_[0]->process(stackedFeatVecs_, out); //out(0) = metricResult_(0,0); } else { //Self Similarity has completed all pair-wise similarity computations //so, it will just send zero valued values and a warning out(0) = 0.0; MRSWARN("SelfSimilarityMatrix::myProcess - no more pairwise similarity computations to be performed - outputting zero similarity value!") } //Select indexes for next pair of instances for distance computation //Similarity matrix is tringular simetric, so we should just compute //half of it (including diagonal). These indexes are to be used by some //source MarSystem that has a control linked to ctrl_instanceIndexes (e.g. WekaSource) if (i < j) ++i; else { ++j; i = 0; } if (j >= nInstances) { ctrl_done_->setValue(true); j = -1; //used to signal that there are no more instance pairs to compute i = -1; //used to signal that there are no more instance pairs to compute } else ctrl_done_->setValue(false); //set indexes into the ctrl_instanceIndexes_ control instIdxs(0) = i; instIdxs(1) = j; } else {